diff --git a/apps/nextjs/src/app/[locale]/manage/tools/api/components/mcp-instructions.tsx b/apps/nextjs/src/app/[locale]/manage/tools/api/components/mcp-instructions.tsx index 9288448e5..f3ac4ea6d 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/api/components/mcp-instructions.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/api/components/mcp-instructions.tsx @@ -292,8 +292,12 @@ export function McpInstructions({ baseUrl, hasApiKeys, toolGroups }: McpInstruct - {group.namespace} - {group.tools.length} + + {group.namespace} + + + {group.tools.length} + @@ -304,8 +308,12 @@ export function McpInstructions({ baseUrl, hasApiKeys, toolGroups }: McpInstruct {toolTypeDisplay[tool.type].method}
- {tool.name} - {tool.description} + + {tool.name} + + + {tool.description} +
))} diff --git a/apps/nextjs/src/app/api/mcp/[transport]/route.ts b/apps/nextjs/src/app/api/mcp/[transport]/route.ts index 6769f48c7..2cfcfbb24 100644 --- a/apps/nextjs/src/app/api/mcp/[transport]/route.ts +++ b/apps/nextjs/src/app/api/mcp/[transport]/route.ts @@ -29,10 +29,12 @@ declare global { var mcpRateLimit: RateLimitStore | undefined; } -const rateLimitStore = globalThis.mcpRateLimit ?? (globalThis.mcpRateLimit = { - authFailures: new Map(), - cleanupTimer: null, -}); +const rateLimitStore = + globalThis.mcpRateLimit ?? + (globalThis.mcpRateLimit = { + authFailures: new Map(), + cleanupTimer: null, + }); const authFailures = rateLimitStore.authFailures; if (!rateLimitStore.cleanupTimer) { @@ -203,7 +205,10 @@ const mcpHandler = createMcpHandler( }; } catch (error) { const message = sanitizeErrorMessage(error); - logger.warn("MCP tool execution failed", { tool: name, error: error instanceof Error ? error.message : String(error) }); + logger.warn("MCP tool execution failed", { + tool: name, + error: error instanceof Error ? error.message : String(error), + }); return { content: [{ type: "text" as const, text: JSON.stringify({ error: message }) }], isError: true, @@ -248,7 +253,11 @@ const handler = async (req: NextRequest) => { const { ua } = userAgent(req); if (!checkAuthRateLimit(ipAddress)) { - return jsonErrorResponse(429, { error: "rate_limited", hint: "Too many failed authentication attempts. Try again later." }, { "Retry-After": "60" }); + return jsonErrorResponse( + 429, + { error: "rate_limited", hint: "Too many failed authentication attempts. Try again later." }, + { "Retry-After": "60" }, + ); } if (!apiKeyValue) { @@ -256,7 +265,10 @@ const handler = async (req: NextRequest) => { const baseUrl = extractBaseUrlFromHeaders(req.headers); return jsonErrorResponse( 401, - { error: "unauthorized", hint: "Authenticate with an ApiKey header or via OAuth at /.well-known/oauth-authorization-server" }, + { + error: "unauthorized", + hint: "Authenticate with an ApiKey header or via OAuth at /.well-known/oauth-authorization-server", + }, { "WWW-Authenticate": `Bearer resource_metadata="${baseUrl}/.well-known/oauth-protected-resource"` }, ); } @@ -270,7 +282,10 @@ const handler = async (req: NextRequest) => { if (!session) { recordAuthFailure(ipAddress); - return jsonErrorResponse(401, { error: "invalid_token", hint: "The API key was not found or the token is incorrect." }); + return jsonErrorResponse(401, { + error: "invalid_token", + hint: "The API key was not found or the token is incorrect.", + }); } clearAuthFailures(ipAddress); diff --git a/apps/nextjs/src/app/api/mcp/oauth/_store.ts b/apps/nextjs/src/app/api/mcp/oauth/_store.ts index 5d50de9b2..14352a41b 100644 --- a/apps/nextjs/src/app/api/mcp/oauth/_store.ts +++ b/apps/nextjs/src/app/api/mcp/oauth/_store.ts @@ -38,12 +38,14 @@ declare global { var mcpOAuthStore: OAuthStore | undefined; } -const store = globalThis.mcpOAuthStore ?? (globalThis.mcpOAuthStore = { - clients: new Map(), - authCodes: new Map(), - pendingAuths: new Map(), - cleanupTimer: null, -}); +const store = + globalThis.mcpOAuthStore ?? + (globalThis.mcpOAuthStore = { + clients: new Map(), + authCodes: new Map(), + pendingAuths: new Map(), + cleanupTimer: null, + }); const clients = store.clients; const authCodes = store.authCodes; const pendingAuths = store.pendingAuths; diff --git a/apps/nextjs/src/app/api/mcp/oauth/register/route.ts b/apps/nextjs/src/app/api/mcp/oauth/register/route.ts index ff28ad829..af20cca49 100644 --- a/apps/nextjs/src/app/api/mcp/oauth/register/route.ts +++ b/apps/nextjs/src/app/api/mcp/oauth/register/route.ts @@ -12,10 +12,12 @@ declare global { var mcpRegisterRateLimit: RateLimitStore | undefined; } -const store = globalThis.mcpRegisterRateLimit ?? (globalThis.mcpRegisterRateLimit = { - attempts: new Map(), - timer: null, -}); +const store = + globalThis.mcpRegisterRateLimit ?? + (globalThis.mcpRegisterRateLimit = { + attempts: new Map(), + timer: null, + }); const registerAttempts = store.attempts; if (!store.timer) { diff --git a/apps/nextjs/src/app/api/mcp/oauth/token/route.ts b/apps/nextjs/src/app/api/mcp/oauth/token/route.ts index c9d24f7a1..1122e1950 100644 --- a/apps/nextjs/src/app/api/mcp/oauth/token/route.ts +++ b/apps/nextjs/src/app/api/mcp/oauth/token/route.ts @@ -22,10 +22,12 @@ declare global { var mcpTokenRateLimit: RateLimitStore | undefined; } -const store = globalThis.mcpTokenRateLimit ?? (globalThis.mcpTokenRateLimit = { - failures: new Map(), - timer: null, -}); +const store = + globalThis.mcpTokenRateLimit ?? + (globalThis.mcpTokenRateLimit = { + failures: new Map(), + timer: null, + }); const tokenFailures = store.failures; if (!store.timer) { @@ -133,10 +135,9 @@ export async function POST(req: Request) { scope: "mcp:tools", }); } catch (error) { - logger.error("Failed to create API key during OAuth token exchange", { error: error instanceof Error ? error.message : String(error) }); - return Response.json( - { error: "server_error", error_description: "Failed to issue access token" }, - { status: 500 }, - ); + logger.error("Failed to create API key during OAuth token exchange", { + error: error instanceof Error ? error.message : String(error), + }); + return Response.json({ error: "server_error", error_description: "Failed to issue access token" }, { status: 500 }); } }