Fix lint errors and add missing rate limiting to MCP endpoints
- Remove unused mcpAuthMetadataRouter import - Fix authMetadata type (use Record<string, unknown> instead of any) - Add rate limiting to all MCP endpoints (/mcp, /sse, /message)
This commit is contained in:
parent
695f9f68ae
commit
78f87bbeb4
1 changed files with 17 additions and 11 deletions
|
|
@ -13,7 +13,7 @@
|
|||
*/
|
||||
|
||||
import { BearerAuthMiddlewareOptions, requireBearerAuth } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";
|
||||
import { getOAuthProtectedResourceMetadataUrl, mcpAuthMetadataRouter } from "@modelcontextprotocol/sdk/server/auth/router.js";
|
||||
import { getOAuthProtectedResourceMetadataUrl } from "@modelcontextprotocol/sdk/server/auth/router.js";
|
||||
import cors from "cors";
|
||||
import rateLimit from "express-rate-limit";
|
||||
import express from "express";
|
||||
|
|
@ -135,13 +135,19 @@ app.use(baseSecurityHeaders);
|
|||
// Enable CORS pre-flight requests
|
||||
app.options('*', cors(corsOptions));
|
||||
|
||||
// Rate limiting for custom endpoints
|
||||
// Rate limiting for endpoints
|
||||
const staticFileRateLimit = rateLimit({
|
||||
windowMs: 10 * 60 * 1000, // 10 minutes
|
||||
limit: 25, // 25 requests per 10 minutes for static files
|
||||
message: { error: 'too_many_requests', error_description: 'Static file rate limit exceeded' }
|
||||
});
|
||||
|
||||
const mcpRateLimit = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
limit: 100, // 100 requests per 15 minutes per IP
|
||||
message: { error: 'too_many_requests', error_description: 'MCP rate limit exceeded' }
|
||||
});
|
||||
|
||||
// MCP server using external auth server
|
||||
logger.info('Starting MCP server', {
|
||||
baseUri: BASE_URI,
|
||||
|
|
@ -150,7 +156,7 @@ logger.info('Starting MCP server', {
|
|||
});
|
||||
|
||||
// Auth server state - will be populated asynchronously
|
||||
let authMetadata: any;
|
||||
let authMetadata: Record<string, unknown> | undefined;
|
||||
let authServerAvailable = false;
|
||||
|
||||
// OAuth metadata endpoint - responds based on current auth server status
|
||||
|
|
@ -197,13 +203,13 @@ const bearerAuth: express.RequestHandler = (req, res, next) => {
|
|||
};
|
||||
|
||||
// MCP routes (legacy SSE transport)
|
||||
app.get("/sse", cors(corsOptions), bearerAuth, sseHeaders, handleSSEConnection);
|
||||
app.post("/message", cors(corsOptions), bearerAuth, sensitiveDataHeaders, handleMessage);
|
||||
app.get("/sse", cors(corsOptions), mcpRateLimit, bearerAuth, sseHeaders, handleSSEConnection);
|
||||
app.post("/message", cors(corsOptions), mcpRateLimit, bearerAuth, sensitiveDataHeaders, handleMessage);
|
||||
|
||||
// MCP routes (new streamable HTTP transport)
|
||||
app.get("/mcp", cors(corsOptions), bearerAuth, handleStreamableHTTP);
|
||||
app.post("/mcp", cors(corsOptions), bearerAuth, handleStreamableHTTP);
|
||||
app.delete("/mcp", cors(corsOptions), bearerAuth, handleStreamableHTTP);
|
||||
app.get("/mcp", cors(corsOptions), mcpRateLimit, bearerAuth, handleStreamableHTTP);
|
||||
app.post("/mcp", cors(corsOptions), mcpRateLimit, bearerAuth, handleStreamableHTTP);
|
||||
app.delete("/mcp", cors(corsOptions), mcpRateLimit, bearerAuth, handleStreamableHTTP);
|
||||
|
||||
// Health check endpoint
|
||||
app.get("/health", (req, res) => {
|
||||
|
|
@ -291,9 +297,9 @@ async function connectToAuthServer() {
|
|||
authMetadata = await authMetadataResponse.json();
|
||||
authServerAvailable = true;
|
||||
logger.info('Successfully connected to auth server', {
|
||||
issuer: authMetadata.issuer,
|
||||
authorizationEndpoint: authMetadata.authorization_endpoint,
|
||||
tokenEndpoint: authMetadata.token_endpoint
|
||||
issuer: authMetadata?.issuer,
|
||||
authorizationEndpoint: authMetadata?.authorization_endpoint,
|
||||
tokenEndpoint: authMetadata?.token_endpoint
|
||||
});
|
||||
break; // Success, exit retry loop
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue