The 400 Bad Request on second POST was caused by CORS not exposing
the mcp-session-id header, preventing MCP Inspector from reading it
and sending it back in subsequent requests.
Without the session ID, each request created a new transport session
instead of reusing the existing one, causing protocol errors.
Fix:
- Add expose_headers to CORS middleware configuration
- Expose mcp-session-id and mcp-protocol-version headers
- Allows browser clients to read and reuse session IDs
- Applied to both streamable-http and SSE transports
This fixes the session continuity issue and eliminates 400 errors.
The previous approach of running uvicorn.run(mcp_app) directly bypassed
MCP's internal session management, causing 400 Bad Request errors when
MCP Inspector tried to reuse sessions.
Solution:
- Use mcp.run() with middleware parameter instead of uvicorn.run()
- Build middleware list using starlette.middleware.Middleware wrapper
- Pass middleware list to mcp.run(transport, middleware=middleware_list)
- This preserves MCP's session handling while applying our middleware
Benefits:
- Proper MCP session continuity for streamable-http transport
- CORS middleware still applies correctly
- Authentication middleware works as expected
- Debug logging middleware available when LOG_LEVEL=DEBUG
This fixes the 400 Bad Request error on the second POST request.
Added RequestLoggingMiddleware to help diagnose 400 Bad Request errors:
- Logs all request methods and paths in DEBUG mode
- Logs request headers for debugging
- Warns on any 4xx/5xx responses with details
- Only enabled when LOG_LEVEL=DEBUG to avoid spam
This helps troubleshoot MCP protocol issues without modifying
the core request handling logic.
CORS preflight requests (OPTIONS) don't include Authorization headers
by browser design. The middleware was blocking these requests with 401.
Solution:
- Skip authentication check for OPTIONS requests
- OPTIONS requests are handled by CORS middleware only
- Actual requests (GET, POST) still require authentication
This fixes the "401 Unauthorized" error on OPTIONS /mcp when using
MCP Inspector or other browser-based clients with authentication enabled.
The previous fix added CORS middleware to the app, but mcp.run()
creates a new app instance that doesn't include our middleware.
Solution:
- Import uvicorn
- For streamable-http transport, run uvicorn directly with the
middleware-enhanced app (mcp_app)
- This ensures CORS middleware is actually applied
- For other transports (SSE), fall back to mcp.run() with a warning
This fixes the "OPTIONS /mcp HTTP/1.1 405 Method Not Allowed" error
by ensuring CORS middleware handles preflight requests properly.
This commit addresses two critical issues in the MCP server:
1. CORS Middleware Fix:
- Move CORS middleware outside the auth check so it's always enabled
- CORS is required for browser-based MCP clients, regardless of auth
- Fixes "OPTIONS /mcp HTTP/1.1 405 Method Not Allowed" error
2. Schema Cache Improvements:
- Add specific handling for corrupted JSON cache files
- Automatically remove corrupted cache files and log the action
- Prevents startup failures due to malformed JSON
- Better error messages to help diagnose cache issues
3. Configuration Updates:
- Change default SCHEMA_CACHE_DIR from /app/data/schemas to ./data/schemas
- Better default for local development (Docker still uses /app/data/schemas)
- Update .env.example with clearer documentation
These fixes improve robustness and make local development easier.