Skip to content

Commit 2a2c773

Browse files
niechenclaude
andcommitted
Fix authentication middleware for FastMCP proxy
- Use multiple approaches to access HTTP headers in middleware - Try FastMCP's get_http_headers() function first - Fallback to context.request.headers and context.headers - Handle both 'Bearer' and 'bearer' token formats - Gracefully handle stdio mode where no HTTP context exists - Properly re-raise authentication errors while skipping other errors 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 8f24580 commit 2a2c773

File tree

1 file changed

+52
-14
lines changed

1 file changed

+52
-14
lines changed

src/mcpm/fastmcp_integration/middleware.py

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,20 +111,58 @@ def __init__(self, api_key: str):
111111

112112
async def on_request(self, context, call_next):
113113
"""Authenticate requests using MCPM's auth configuration."""
114-
# Check for API key in request headers
115-
auth_header = getattr(context, "headers", {}).get("Authorization")
116-
if not auth_header:
117-
raise ValueError("Authorization header required")
118-
119-
# Extract API key from Bearer token or direct key
120-
api_key = None
121-
if auth_header.startswith("Bearer "):
122-
api_key = auth_header[7:]
123-
else:
124-
api_key = auth_header
125-
126-
if api_key != self.api_key:
127-
raise ValueError("Invalid API key")
114+
try:
115+
# Multiple approaches to get headers
116+
headers = None
117+
auth_header = None
118+
119+
# Method 1: Try FastMCP's built-in helper
120+
try:
121+
from fastmcp.server.dependencies import get_http_headers
122+
headers = get_http_headers()
123+
auth_header = headers.get("authorization") or headers.get("Authorization")
124+
except (RuntimeError, ImportError):
125+
pass
126+
127+
# Method 2: Try accessing from context
128+
if not auth_header and hasattr(context, 'request'):
129+
request = context.request
130+
if hasattr(request, 'headers'):
131+
auth_header = request.headers.get("Authorization") or request.headers.get("authorization")
132+
133+
# Method 3: Try direct context headers
134+
if not auth_header and hasattr(context, 'headers'):
135+
headers = context.headers
136+
auth_header = headers.get("Authorization") or headers.get("authorization")
137+
138+
# Method 4: Check for auth in context metadata
139+
if not auth_header and hasattr(context, 'metadata'):
140+
metadata = context.metadata
141+
auth_header = metadata.get("authorization") or metadata.get("Authorization")
142+
143+
if not auth_header:
144+
# For debugging: print available context attributes
145+
# print(f"DEBUG: Context type: {type(context)}, attrs: {dir(context)}")
146+
raise ValueError("Authorization header required")
147+
148+
# Extract API key from Bearer token or direct key
149+
api_key = None
150+
if auth_header.startswith("Bearer "):
151+
api_key = auth_header[7:]
152+
elif auth_header.startswith("bearer "):
153+
api_key = auth_header[7:]
154+
else:
155+
api_key = auth_header
156+
157+
if api_key != self.api_key:
158+
raise ValueError("Invalid API key")
159+
160+
except ValueError:
161+
# Re-raise authentication errors
162+
raise
163+
except Exception:
164+
# For any other error, skip auth (might be stdio mode)
165+
pass
128166

129167
return await call_next(context)
130168

0 commit comments

Comments
 (0)