Implement streamable HTTP transport with Redis-based session management

- Add new /mcp endpoint supporting GET, POST, DELETE methods
- Implement SessionManager for Redis-based session state management
- Add MessageDelivery for message buffering when SSE disconnected
- Support horizontal scaling via Redis session storage
- Maintain backwards compatibility with existing /sse and /message endpoints
- Add comprehensive tests for SessionManager functionality
- Session TTL of 5 minutes prevents Redis bloat
- Message buffering for resilient connection handling

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Jerome 2025-06-05 12:24:04 +01:00
commit 2b673a28c2
No known key found for this signature in database

View file

@ -3,7 +3,7 @@ import express from "express";
import { BASE_URI, PORT } from "./config.js";
import { AuthRouterOptions, mcpAuthRouter } from "@modelcontextprotocol/sdk/server/auth/router.js";
import { EverythingAuthProvider } from "./auth/provider.js";
import { handleMessage, handleSSEConnection, authContext } from "./handlers/mcp.js";
import { handleMessage, handleSSEConnection, handleStreamableHTTP, authContext } from "./handlers/mcp.js";
import { handleFakeAuthorizeRedirect, handleFakeAuthorize } from "./handlers/fakeauth.js";
import { redisClient } from "./redis.js";
import { requireBearerAuth } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";
@ -87,10 +87,15 @@ const options: AuthRouterOptions = {
app.use(mcpAuthRouter(options));
const bearerAuth = requireBearerAuth(options);
// MCP routes
// MCP routes (legacy SSE transport)
app.get("/sse", cors(corsOptions), bearerAuth, authContext, sseHeaders, handleSSEConnection);
app.post("/message", cors(corsOptions), bearerAuth, authContext, sensitiveDataHeaders, handleMessage);
// MCP routes (new streamable HTTP transport)
app.get("/mcp", cors(corsOptions), bearerAuth, authContext, handleStreamableHTTP);
app.post("/mcp", cors(corsOptions), bearerAuth, authContext, handleStreamableHTTP);
app.delete("/mcp", cors(corsOptions), bearerAuth, authContext, handleStreamableHTTP);
// Upstream auth routes
app.get("/fakeupstreamauth/authorize", cors(corsOptions), handleFakeAuthorize);
app.get("/fakeupstreamauth/callback", cors(corsOptions), handleFakeAuthorizeRedirect);