feat: allow api_key query parameter for ChatGPT UI

ChatGPT UI lacks custom header support for MCP servers. Added
query parameter fallback (?api_key=) alongside Authorization
header to authenticate requests.

Updated tests to cover query param authentication.
This commit is contained in:
2026-01-29 21:03:05 +01:00
parent 08e9aa1de6
commit b990c6c527
2 changed files with 20 additions and 1 deletions

View File

@@ -74,6 +74,10 @@ async def authenticate_request(request: Request, call_next):
auth_header = request.headers.get("authorization") auth_header = request.headers.get("authorization")
api_key = auth_validator.extract_bearer_token(auth_header) api_key = auth_validator.extract_bearer_token(auth_header)
# Fallback: allow API key via query parameter (for ChatGPT UI without headers)
if not api_key:
api_key = request.query_params.get("api_key")
# Validate API key # Validate API key
is_valid, error_message = auth_validator.validate_api_key(api_key, client_ip, user_agent) is_valid, error_message = auth_validator.validate_api_key(api_key, client_ip, user_agent)
@@ -83,7 +87,10 @@ async def authenticate_request(request: Request, call_next):
content={ content={
"error": "Authentication failed", "error": "Authentication failed",
"message": error_message, "message": error_message,
"detail": "Please provide a valid API key in the Authorization header: Bearer <api-key>", "detail": (
"Provide a valid API key via Authorization header (Bearer <api-key>) "
"or ?api_key=<api-key> query parameter"
),
}, },
) )

View File

@@ -116,6 +116,18 @@ def test_list_tools_with_valid_key(client, mock_env):
assert "input_schema" in tool assert "input_schema" in tool
def test_list_tools_with_query_param(client):
"""Test /mcp/tools with API key in query parameter."""
response = client.get(
f"/mcp/tools?api_key={'a' * 64}"
)
assert response.status_code == 200
data = response.json()
assert "tools" in data
assert len(data["tools"]) > 0
def test_list_tools_no_auth_when_disabled(client_no_auth): def test_list_tools_no_auth_when_disabled(client_no_auth):
"""Test that /mcp/tools works without auth when disabled.""" """Test that /mcp/tools works without auth when disabled."""
response = client_no_auth.get("/mcp/tools") response = client_no_auth.get("/mcp/tools")