Skip to content

Commit bc48c93

Browse files
committed
feat: support api key
1 parent 4d27a77 commit bc48c93

File tree

7 files changed

+188
-122
lines changed

7 files changed

+188
-122
lines changed

Diff for: README.md

+23-1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,26 @@ If you want to use the tools inside of [claude desktop](https://claude.ai/downlo
123123

124124
To add new MCP servers, edit the config.json file.
125125

126+
### API Key Authentication
127+
128+
MCP-Bridge supports API key authentication to secure your server. To enable this feature, add an `api_key` field to your config.json file:
129+
130+
```json
131+
{
132+
"api_key": "your-secure-api-key-here"
133+
}
134+
```
135+
136+
When making requests to the MCP-Bridge server, include the API key in the Authorization header as a Bearer token:
137+
138+
```
139+
Authorization: Bearer your-secure-api-key-here
140+
```
141+
142+
If the `api_key` field is empty or not present in the configuration, authentication will be skipped, allowing backward compatibility.
143+
144+
### Full Configuration Example
145+
126146
an example config.json file with most of the options explicitly set:
127147

128148
```json
@@ -162,7 +182,8 @@ an example config.json file with most of the options explicitly set:
162182
},
163183
"logging": {
164184
"log_level": "DEBUG"
165-
}
185+
},
186+
"api_key": "your-secure-api-key-here"
166187
}
167188
```
168189

@@ -172,6 +193,7 @@ an example config.json file with most of the options explicitly set:
172193
| mcp_servers | The MCP servers configuration |
173194
| network | uvicorn network configuration |
174195
| logging | The logging configuration |
196+
| api_key | API key for server authentication |
175197

176198
## Support
177199

Diff for: mcp_bridge/auth.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from fastapi import Depends, HTTPException, Security, status
2+
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
3+
from mcp_bridge.config import config
4+
5+
security = HTTPBearer(auto_error=False)
6+
7+
async def get_api_key(credentials: HTTPAuthorizationCredentials = Security(security)):
8+
"""
9+
Validate the API key provided in the Authorization header.
10+
11+
If no API key is configured in the server settings, authentication is skipped.
12+
If an API key is configured, the request must include a matching API key.
13+
14+
The API key should be provided in the Authorization header as:
15+
Authorization: Bearer your-api-key-here
16+
"""
17+
# If no API key is configured, skip authentication
18+
if not config.api_key:
19+
return True
20+
21+
# If API key is configured but not provided in the request
22+
if not credentials:
23+
raise HTTPException(
24+
status_code=status.HTTP_401_UNAUTHORIZED,
25+
detail="API key is required in Authorization header (Bearer token)",
26+
)
27+
28+
# If API key is provided but doesn't match
29+
if credentials.credentials != config.api_key:
30+
raise HTTPException(
31+
status_code=status.HTTP_401_UNAUTHORIZED,
32+
detail="Invalid API key",
33+
)
34+
35+
return True

Diff for: mcp_bridge/config/final.py

+5
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ class Settings(BaseSettings):
7373
default_factory=lambda: Network.model_construct(),
7474
description="network config",
7575
)
76+
77+
api_key: str = Field(
78+
default="",
79+
description="API key for authenticating requests to the MCP Bridge server"
80+
)
7681

7782
model_config = SettingsConfigDict(
7883
env_prefix="MCP_BRIDGE__",

Diff for: mcp_bridge/endpoints.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from fastapi import APIRouter
1+
from fastapi import APIRouter, Depends
22

33
from lmos_openai_types import CreateChatCompletionRequest, CreateCompletionRequest
44

@@ -10,8 +10,9 @@
1010
)
1111

1212
from mcp_bridge.openapi_tags import Tag
13+
from mcp_bridge.auth import get_api_key
1314

14-
router = APIRouter(prefix="/v1", tags=[Tag.openai])
15+
router = APIRouter(prefix="/v1", tags=[Tag.openai], dependencies=[Depends(get_api_key)])
1516

1617

1718
@router.post("/completions")

Diff for: mcp_bridge/mcpManagement/router.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
from fastapi import APIRouter
1+
from fastapi import APIRouter, Depends
22
from mcp_bridge.openapi_tags import Tag
3+
from mcp_bridge.auth import get_api_key
34

45
from .tools import router as tools_router
56
from .prompts import router as prompts_router
67
from .resources import router as resources_router
78
from .server import router as server_router
89

9-
router = APIRouter(prefix="/mcp", tags=[Tag.mcp_management])
10+
router = APIRouter(prefix="/mcp", tags=[Tag.mcp_management], dependencies=[Depends(get_api_key)])
1011

1112
router.include_router(tools_router)
1213
router.include_router(prompts_router)

Diff for: mcp_bridge/mcp_server/__init__.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
from fastapi import APIRouter
1+
from fastapi import APIRouter, Depends
22
from .sse import router as sse_router
33
from mcp_bridge.openapi_tags import Tag
4+
from mcp_bridge.auth import get_api_key
45

56
__all__ = ["router"]
67

7-
router = APIRouter(prefix="/mcp-server", tags=[Tag.mcp_server])
8+
router = APIRouter(prefix="/mcp-server", tags=[Tag.mcp_server], dependencies=[Depends(get_api_key)])
89
router.include_router(sse_router)

0 commit comments

Comments
 (0)