@mcpjam/inspector 0.9.2 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +13 -0
- package/README.md +25 -6
- package/bin/start.js +6 -3
- package/dist/client/assets/index-C-vxFpw4.css +1 -0
- package/dist/client/assets/index-CTiiyjex.js +1723 -0
- package/dist/client/assets/index-CTiiyjex.js.map +1 -0
- package/dist/client/deepseek_logo.svg +1 -0
- package/dist/client/index.html +2 -2
- package/dist/server/index.js +381 -211
- package/dist/server/index.js.map +1 -1
- package/package.json +15 -10
- package/dist/client/assets/index-BxtnlkQW.css +0 -1
- package/dist/client/assets/index-C2tpp_KC.js +0 -357
- package/dist/client/assets/index-C2tpp_KC.js.map +0 -1
- package/dist/main/main.cjs +0 -1315
- package/dist/preload/preload.js +0 -26
- package/dist/renderer/assets/index-CYiU4_x2.css +0 -1
- package/dist/renderer/assets/index-woGCpEdp.js +0 -356
- package/dist/renderer/catalyst.png +0 -0
- package/dist/renderer/claude_logo.png +0 -0
- package/dist/renderer/demo_1.png +0 -0
- package/dist/renderer/demo_2.png +0 -0
- package/dist/renderer/demo_3.png +0 -0
- package/dist/renderer/file.svg +0 -1
- package/dist/renderer/globe.svg +0 -1
- package/dist/renderer/index.html +0 -14
- package/dist/renderer/mcp.svg +0 -1
- package/dist/renderer/mcp_jam.svg +0 -12
- package/dist/renderer/mcp_jam_dark.png +0 -0
- package/dist/renderer/mcp_jam_light.png +0 -0
- package/dist/renderer/next.svg +0 -1
- package/dist/renderer/ollama_dark.png +0 -0
- package/dist/renderer/ollama_logo.svg +0 -7
- package/dist/renderer/openai_logo.png +0 -0
- package/dist/renderer/vercel.svg +0 -1
- package/dist/renderer/window.svg +0 -1
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../server/index.ts","../../server/routes/mcp/index.ts","../../server/routes/mcp/connect.ts","../../server/utils/mcp-utils.ts","../../server/routes/mcp/tools.ts","../../server/routes/mcp/resources.ts","../../server/routes/mcp/prompts.ts","../../server/routes/mcp/chat.ts","../../server/routes/mcp/oauth.ts"],"sourcesContent":["import { serve } from \"@hono/node-server\";\nimport { Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport { logger } from \"hono/logger\";\nimport { serveStatic } from \"@hono/node-server/serve-static\";\nimport { readFileSync } from \"fs\";\nimport { join } from \"path\";\n\n// ANSI color codes for console output\nconst colors = {\n reset: \"\\x1b[0m\",\n bright: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n blue: \"\\x1b[34m\",\n magenta: \"\\x1b[35m\",\n cyan: \"\\x1b[36m\",\n white: \"\\x1b[37m\",\n};\n\n// Utility function to create a boxed console output\nfunction logBox(content: string, title?: string) {\n const lines = content.split(\"\\n\");\n const maxLength = Math.max(...lines.map((line) => line.length));\n const width = maxLength + 4;\n\n console.log(\"┌\" + \"─\".repeat(width) + \"┐\");\n if (title) {\n const titlePadding = Math.floor((width - title.length - 2) / 2);\n console.log(\n \"│\" +\n \" \".repeat(titlePadding) +\n title +\n \" \".repeat(width - title.length - titlePadding) +\n \"│\",\n );\n console.log(\"├\" + \"─\".repeat(width) + \"┤\");\n }\n\n lines.forEach((line) => {\n const padding = width - line.length - 2;\n console.log(\"│ \" + line + \" \".repeat(padding) + \" │\");\n });\n\n console.log(\"└\" + \"─\".repeat(width) + \"┘\");\n}\n\n// Import routes\nimport mcpRoutes from \"./routes/mcp/index\";\n\n// Utility function to extract MCP server config from environment variables\nfunction getMCPConfigFromEnv() {\n const command = process.env.MCP_SERVER_COMMAND;\n if (!command) {\n return null;\n }\n\n const argsString = process.env.MCP_SERVER_ARGS;\n const args = argsString ? JSON.parse(argsString) : [];\n\n return {\n command,\n args,\n name: \"CLI Server\", // Default name for CLI-provided servers\n };\n}\n\nconst app = new Hono();\n\n// Middleware\napp.use(\"*\", logger());\n// Dynamic CORS origin based on PORT environment variable\nconst serverPort = process.env.PORT || \"3001\";\nconst corsOrigins = [\n `http://localhost:${serverPort}`,\n \"http://localhost:3000\", // Keep for development\n \"http://localhost:3001\", // Keep for development\n];\n\napp.use(\n \"*\",\n cors({\n origin: corsOrigins,\n credentials: true,\n }),\n);\n\n// API Routes\napp.route(\"/api/mcp\", mcpRoutes);\n\n// Health check\napp.get(\"/health\", (c) => {\n return c.json({ status: \"ok\", timestamp: new Date().toISOString() });\n});\n\n// API endpoint to get MCP CLI config (for development mode)\napp.get(\"/api/mcp-cli-config\", (c) => {\n const mcpConfig = getMCPConfigFromEnv();\n return c.json({ config: mcpConfig });\n});\n\n// Static file serving (for production)\nif (process.env.NODE_ENV === \"production\") {\n // Serve static assets (JS, CSS, images, etc.)\n app.use(\"/*\", serveStatic({ root: \"./dist/client\" }));\n\n // SPA fallback - serve index.html for all non-API routes\n app.get(\"*\", async (c) => {\n const path = c.req.path;\n // Don't intercept API routes\n if (path.startsWith(\"/api/\")) {\n return c.notFound();\n }\n // Return index.html for SPA routes\n const indexPath = join(process.cwd(), \"dist\", \"client\", \"index.html\");\n let htmlContent = readFileSync(indexPath, \"utf-8\");\n \n // Inject MCP server config if provided via CLI\n const mcpConfig = getMCPConfigFromEnv();\n if (mcpConfig) {\n const configScript = `<script>window.MCP_CLI_CONFIG = ${JSON.stringify(mcpConfig)};</script>`;\n htmlContent = htmlContent.replace('</head>', `${configScript}</head>`);\n }\n \n return c.html(htmlContent);\n });\n} else {\n // Development mode - just API\n app.get(\"/\", (c) => {\n return c.json({\n message: \"MCP Inspector API Server\",\n environment: \"development\",\n frontend: `http://localhost:${serverPort}`,\n });\n });\n}\n\nconst port = parseInt(process.env.PORT || \"3001\");\n\n// Display the localhost URL in a box\nlogBox(`http://localhost:${port}`, \"🚀 Inspector Launched\");\n\n// Graceful shutdown handling\nconst server = serve({\n fetch: app.fetch,\n port,\n hostname: \"0.0.0.0\", // Bind to all interfaces for Docker\n});\n\n// Handle graceful shutdown\nprocess.on(\"SIGINT\", () => {\n console.log(\"\\n🛑 Shutting down gracefully...\");\n server.close();\n process.exit(0);\n});\n\nprocess.on(\"SIGTERM\", () => {\n console.log(\"\\n🛑 Shutting down gracefully...\");\n server.close();\n process.exit(0);\n});\n\nexport default app;\n","import { Hono } from \"hono\";\nimport connect from \"./connect\";\nimport tools from \"./tools\";\nimport resources from \"./resources\";\nimport prompts from \"./prompts\";\nimport chat from \"./chat\";\nimport oauth from \"./oauth\";\n\nconst mcp = new Hono();\n\n// Health check\nmcp.get(\"/health\", (c) => {\n return c.json({\n service: \"MCP API\",\n status: \"ready\",\n timestamp: new Date().toISOString(),\n });\n});\n\n// Chat endpoint - REAL IMPLEMENTATION\nmcp.route(\"/chat\", chat);\n\n// Connect endpoint - REAL IMPLEMENTATION\nmcp.route(\"/connect\", connect);\n\n// Tools endpoint - REAL IMPLEMENTATION\nmcp.route(\"/tools\", tools);\n\n// Resources endpoints - REAL IMPLEMENTATION\nmcp.route(\"/resources\", resources);\n\n// Prompts endpoints - REAL IMPLEMENTATION\nmcp.route(\"/prompts\", prompts);\n\n// OAuth proxy endpoints\nmcp.route(\"/oauth\", oauth);\n\nexport default mcp;\n","import { Hono } from \"hono\";\nimport { validateServerConfig, createMCPClient } from \"../../utils/mcp-utils\";\nimport { ContentfulStatusCode } from \"hono/utils/http-status\";\n\nconst connect = new Hono();\n\nconnect.post(\"/\", async (c) => {\n try {\n const { serverConfig } = await c.req.json();\n\n const validation = validateServerConfig(serverConfig);\n if (!validation.success) {\n const error = validation.error!;\n return c.json(\n {\n success: false,\n error: error.message,\n },\n error.status as ContentfulStatusCode,\n );\n }\n\n let client;\n try {\n client = createMCPClient(validation.config!, `test-${Date.now()}`);\n } catch (error) {\n return c.json(\n {\n success: false,\n error: `Failed to create a MCP client. Please double check your server configuration: ${JSON.stringify(serverConfig)}`,\n details: error instanceof Error ? error.message : \"Unknown error\",\n },\n 500,\n );\n }\n\n try {\n await client.getTools();\n await client.disconnect();\n return c.json({\n success: true,\n });\n } catch (error) {\n return c.json(\n {\n success: false,\n error: `MCP configuration is invalid. Please double check your server configuration: ${JSON.stringify(serverConfig)}`,\n details: error instanceof Error ? error.message : \"Unknown error\",\n },\n 500,\n );\n }\n } catch (error) {\n return c.json(\n {\n success: false,\n error: \"Failed to parse request body\",\n details: error instanceof Error ? error.message : \"Unknown error\",\n },\n 400,\n );\n }\n});\n\nexport default connect;\n","import { MCPClient } from \"@mastra/mcp\";\nimport type { MastraMCPServerDefinition } from \"../../shared/types\";\n\n// Hono-compatible error response type\nexport interface HonoErrorResponse {\n message: string;\n status: number;\n}\n\nexport interface ValidationResult {\n success: boolean;\n config?: MastraMCPServerDefinition;\n error?: HonoErrorResponse;\n}\n\nexport interface MultipleValidationResult {\n success: boolean;\n validConfigs?: Record<string, MastraMCPServerDefinition>;\n errors?: Record<string, string>;\n error?: HonoErrorResponse;\n}\n\nexport function validateServerConfig(serverConfig: any): ValidationResult {\n if (!serverConfig) {\n return {\n success: false,\n error: {\n message: \"Server configuration is required\",\n status: 400,\n },\n };\n }\n\n // Validate and prepare config\n const config = { ...serverConfig };\n\n // Validate and convert URL if provided\n if (config.url) {\n try {\n // Convert string URL to URL object if needed\n if (typeof config.url === \"string\") {\n config.url = new URL(config.url);\n } else if (typeof config.url === \"object\" && !config.url.href) {\n return {\n success: false,\n error: {\n message: \"Invalid URL configuration\",\n status: 400,\n },\n };\n }\n\n // Handle OAuth authentication for HTTP servers\n if (config.oauth?.access_token) {\n const authHeaders = {\n Authorization: `Bearer ${config.oauth.access_token}`,\n ...(config.requestInit?.headers || {}),\n };\n\n config.requestInit = {\n ...config.requestInit,\n headers: authHeaders,\n };\n\n // For SSE connections, add eventSourceInit with OAuth headers\n config.eventSourceInit = {\n fetch(input: Request | URL | string, init?: RequestInit) {\n const headers = new Headers(init?.headers || {});\n\n // Add OAuth authorization header\n headers.set(\n \"Authorization\",\n `Bearer ${config.oauth!.access_token}`,\n );\n\n // Copy other headers from requestInit\n if (config.requestInit?.headers) {\n const requestHeaders = new Headers(config.requestInit.headers);\n requestHeaders.forEach((value, key) => {\n if (key.toLowerCase() !== \"authorization\") {\n headers.set(key, value);\n }\n });\n }\n\n return fetch(input, {\n ...init,\n headers,\n });\n },\n };\n } else if (config.requestInit?.headers) {\n // For SSE connections without OAuth, add eventSourceInit if requestInit has custom headers\n config.eventSourceInit = {\n fetch(input: Request | URL | string, init?: RequestInit) {\n const headers = new Headers(init?.headers || {});\n\n // Copy headers from requestInit\n const requestHeaders = new Headers(config.requestInit.headers);\n requestHeaders.forEach((value, key) => {\n headers.set(key, value);\n });\n\n return fetch(input, {\n ...init,\n headers,\n });\n },\n };\n }\n } catch (error) {\n return {\n success: false,\n error: {\n message: `Invalid URL format: ${error}`,\n status: 400,\n },\n };\n }\n }\n\n return {\n success: true,\n config,\n };\n}\n\nexport function createMCPClient(\n config: MastraMCPServerDefinition,\n id: string,\n): MCPClient {\n return new MCPClient({\n id,\n servers: {\n server: config,\n },\n });\n}\n\nexport interface MultipleValidationResult {\n success: boolean;\n validConfigs?: Record<string, MastraMCPServerDefinition>;\n errors?: Record<string, string>;\n error?: HonoErrorResponse;\n}\n\nexport const validateMultipleServerConfigs = (\n serverConfigs: Record<string, MastraMCPServerDefinition>,\n): MultipleValidationResult => {\n if (!serverConfigs || Object.keys(serverConfigs).length === 0) {\n return {\n success: false,\n error: {\n message: \"At least one server configuration is required\",\n status: 400,\n },\n };\n }\n\n const validConfigs: Record<string, MastraMCPServerDefinition> = {};\n const errors: Record<string, string> = {};\n let hasErrors = false;\n\n // Validate each server configuration\n for (const [serverName, serverConfig] of Object.entries(serverConfigs)) {\n const validationResult = validateServerConfig(serverConfig);\n\n if (validationResult.success && validationResult.config) {\n validConfigs[serverName] = validationResult.config;\n } else {\n hasErrors = true;\n let errorMessage = \"Configuration validation failed\";\n if (validationResult.error) {\n errorMessage = validationResult.error.message;\n }\n errors[serverName] = errorMessage;\n }\n }\n\n // If all configs are valid, return success\n if (!hasErrors) {\n return {\n success: true,\n validConfigs,\n };\n }\n\n // If some configs are valid but others failed, return partial success\n if (Object.keys(validConfigs).length > 0) {\n return {\n success: false,\n validConfigs,\n errors,\n };\n }\n\n // If all configs failed, return error\n return {\n success: false,\n errors,\n error: {\n message: \"All server configurations failed validation\",\n status: 400,\n },\n };\n};\n\nexport function createMCPClientWithMultipleConnections(\n serverConfigs: Record<string, MastraMCPServerDefinition>,\n): MCPClient {\n // Normalize server config names\n const normalizedConfigs: Record<string, MastraMCPServerDefinition> = {};\n for (const [serverName, config] of Object.entries(serverConfigs)) {\n const normalizedName = normalizeServerConfigName(serverName);\n normalizedConfigs[normalizedName] = config;\n }\n\n return new MCPClient({\n id: `chat-${Date.now()}`,\n servers: normalizedConfigs,\n });\n}\n\nexport function normalizeServerConfigName(serverName: string): string {\n // Convert to lowercase and replace spaces/hyphens with underscores\n return serverName\n .toLowerCase()\n .replace(/[\\s\\-]+/g, \"_\")\n .replace(/[^a-z0-9_]/g, \"\");\n}\n\nexport function createErrorResponse(\n message: string,\n details?: string,\n status: number = 500,\n): HonoErrorResponse {\n return {\n message: details ? `${message}: ${details}` : message,\n status,\n };\n}\n","import { Hono } from \"hono\";\nimport { validateServerConfig, createMCPClient } from \"../../utils/mcp-utils\";\nimport type { Tool } from \"@mastra/core/tools\";\nimport { z } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport { ContentfulStatusCode } from \"hono/utils/http-status\";\n\nconst tools = new Hono();\n\n// Store for pending elicitation requests\nconst pendingElicitations = new Map<\n string,\n {\n resolve: (response: any) => void;\n reject: (error: any) => void;\n }\n>();\n\ntools.post(\"/\", async (c) => {\n let client: any = null;\n let encoder: TextEncoder | null = null;\n let streamController: ReadableStreamDefaultController | null = null;\n let action: string | undefined;\n let toolName: string | undefined;\n\n try {\n const requestData = await c.req.json();\n action = requestData.action;\n toolName = requestData.toolName;\n const { serverConfig, parameters, requestId, response } = requestData;\n\n if (!action || ![\"list\", \"execute\", \"respond\"].includes(action)) {\n return c.json(\n {\n success: false,\n error: \"Action must be 'list', 'execute', or 'respond'\",\n },\n 400,\n );\n }\n\n // Handle elicitation response\n if (action === \"respond\") {\n if (!requestId) {\n return c.json(\n {\n success: false,\n error: \"requestId is required for respond action\",\n },\n 400,\n );\n }\n\n const pending = pendingElicitations.get(requestId);\n if (!pending) {\n return c.json(\n {\n success: false,\n error: \"No pending elicitation found for this requestId\",\n },\n 404,\n );\n }\n\n // Resolve the pending elicitation with user's response\n pending.resolve(response);\n pendingElicitations.delete(requestId);\n\n return c.json({ success: true });\n }\n\n const validation = validateServerConfig(serverConfig);\n if (!validation.success) {\n return c.json(\n { success: false, error: validation.error!.message },\n validation.error!.status as ContentfulStatusCode,\n );\n }\n\n encoder = new TextEncoder();\n const readableStream = new ReadableStream({\n async start(controller) {\n streamController = controller;\n\n try {\n const clientId = `tools-${action}-${Date.now()}`;\n client = createMCPClient(validation.config!, clientId);\n\n if (action === \"list\") {\n // Stream tools list\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"tools_loading\",\n message: \"Fetching tools from server...\",\n })}\\n\\n`,\n ),\n );\n\n const tools: Record<string, Tool> = await client.getTools();\n\n // Convert from Zod to JSON Schema\n const toolsWithJsonSchema: Record<string, any> = Object.fromEntries(\n Object.entries(tools).map(([toolName, tool]) => {\n return [\n toolName,\n {\n ...tool,\n inputSchema: zodToJsonSchema(\n tool.inputSchema as unknown as z.ZodType<any>,\n ),\n },\n ];\n }),\n );\n\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"tools_list\",\n tools: toolsWithJsonSchema,\n })}\\n\\n`,\n ),\n );\n } else if (action === \"execute\") {\n // Stream tool execution\n if (!toolName) {\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"tool_error\",\n error: \"Tool name is required for execution\",\n })}\\n\\n`,\n ),\n );\n return;\n }\n\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"tool_executing\",\n toolName,\n parameters: parameters || {},\n message: \"Executing tool...\",\n })}\\n\\n`,\n ),\n );\n\n const tools = await client.getTools();\n const tool = tools[toolName];\n\n if (!tool) {\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"tool_error\",\n error: `Tool '${toolName}' not found`,\n })}\\n\\n`,\n ),\n );\n return;\n }\n\n const toolArgs =\n parameters && typeof parameters === \"object\" ? parameters : {};\n\n // Set up elicitation handler\n const elicitationHandler = async (elicitationRequest: any) => {\n const requestId = `elicit_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n\n // Stream elicitation request to client\n if (streamController && encoder) {\n streamController.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({\n type: \"elicitation_request\",\n requestId,\n message: elicitationRequest.message,\n schema: elicitationRequest.requestedSchema,\n timestamp: new Date(),\n })}\\n\\n`,\n ),\n );\n }\n\n // Return a promise that will be resolved when user responds\n return new Promise((resolve, reject) => {\n pendingElicitations.set(requestId, { resolve, reject });\n\n // Set a timeout to clean up if no response\n setTimeout(() => {\n if (pendingElicitations.has(requestId)) {\n pendingElicitations.delete(requestId);\n reject(new Error(\"Elicitation timeout\"));\n }\n }, 300000); // 5 minute timeout\n });\n };\n\n // Register elicitation handler with the client\n if (client.elicitation && client.elicitation.onRequest) {\n const serverName = \"server\"; // See createMCPClient() function. The name of the server is \"server\"\n client.elicitation.onRequest(serverName, elicitationHandler);\n }\n\n const result = await tool.execute({\n context: toolArgs,\n });\n\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"tool_result\",\n toolName,\n result,\n })}\\n\\n`,\n ),\n );\n\n // Stream elicitation completion if there were any\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"elicitation_complete\",\n toolName,\n })}\\n\\n`,\n ),\n );\n }\n\n controller.enqueue(encoder!.encode(`data: [DONE]\\n\\n`));\n } catch (error) {\n const errorMsg =\n error instanceof Error ? error.message : \"Unknown error\";\n\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"tool_error\",\n error: errorMsg,\n })}\\n\\n`,\n ),\n );\n } finally {\n if (client) {\n await client.disconnect();\n }\n controller.close();\n }\n },\n });\n\n return new Response(readableStream, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n });\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : \"Unknown error\";\n\n // Clean up client on error\n if (client) {\n try {\n await client.disconnect();\n } catch (cleanupError) {\n // Ignore cleanup errors\n }\n }\n\n return c.json(\n {\n success: false,\n error: errorMsg,\n },\n 500,\n );\n }\n});\n\nexport default tools;\n","import { Hono } from \"hono\";\nimport { validateServerConfig, createMCPClient } from \"../../utils/mcp-utils\";\nimport { ContentfulStatusCode } from \"hono/utils/http-status\";\n\nconst resources = new Hono();\n\n// List resources endpoint\nresources.post(\"/list\", async (c) => {\n try {\n const { serverConfig } = await c.req.json();\n\n const validation = validateServerConfig(serverConfig);\n if (!validation.success) {\n return c.json(\n { success: false, error: validation.error!.message },\n validation.error!.status as ContentfulStatusCode,\n );\n }\n\n const client = createMCPClient(\n validation.config!,\n `resources-list-${Date.now()}`,\n );\n\n try {\n const resources = await client.resources.list();\n\n // Cleanup\n await client.disconnect();\n\n return c.json({ resources });\n } catch (error) {\n await client.disconnect();\n throw error;\n }\n } catch (error) {\n console.error(\"Error fetching resources:\", error);\n return c.json(\n {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n 500,\n );\n }\n});\n\n// Read resource endpoint\nresources.post(\"/read\", async (c) => {\n try {\n const { serverConfig, uri } = await c.req.json();\n\n const validation = validateServerConfig(serverConfig);\n if (!validation.success) {\n return c.json(\n { success: false, error: validation.error!.message },\n validation.error!.status as ContentfulStatusCode,\n );\n }\n\n if (!uri) {\n return c.json(\n {\n success: false,\n error: \"Resource URI is required\",\n },\n 400,\n );\n }\n\n const client = createMCPClient(\n validation.config!,\n `resources-read-${Date.now()}`,\n );\n\n try {\n const content = await client.resources.read(\"server\", uri);\n\n // Cleanup\n await client.disconnect();\n\n return c.json({ content });\n } catch (error) {\n await client.disconnect();\n throw error;\n }\n } catch (error) {\n console.error(\"Error reading resource:\", error);\n return c.json(\n {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n 500,\n );\n }\n});\n\nexport default resources;\n","import { Hono } from \"hono\";\nimport { validateServerConfig, createMCPClient } from \"../../utils/mcp-utils\";\nimport { ContentfulStatusCode } from \"hono/utils/http-status\";\n\nconst prompts = new Hono();\n\n// List prompts endpoint\nprompts.post(\"/list\", async (c) => {\n try {\n const { serverConfig } = await c.req.json();\n\n const validation = validateServerConfig(serverConfig);\n if (!validation.success) {\n return c.json(\n { success: false, error: validation.error!.message },\n validation.error!.status as ContentfulStatusCode,\n );\n }\n\n const client = createMCPClient(\n validation.config!,\n `prompts-list-${Date.now()}`,\n );\n\n try {\n const prompts = await client.prompts.list();\n\n // Cleanup\n await client.disconnect();\n\n return c.json({ prompts });\n } catch (error) {\n await client.disconnect();\n throw error;\n }\n } catch (error) {\n console.error(\"Error fetching prompts:\", error);\n return c.json(\n {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n 500,\n );\n }\n});\n\n// Get prompt endpoint\nprompts.post(\"/get\", async (c) => {\n try {\n const { serverConfig, name, args } = await c.req.json();\n\n const validation = validateServerConfig(serverConfig);\n if (!validation.success) {\n return c.json(\n { success: false, error: validation.error!.message },\n validation.error!.status as ContentfulStatusCode,\n );\n }\n\n if (!name) {\n return c.json(\n {\n success: false,\n error: \"Prompt name is required\",\n },\n 400,\n );\n }\n\n const client = createMCPClient(\n validation.config!,\n `prompts-get-${Date.now()}`,\n );\n\n try {\n const content = await client.prompts.get({\n serverName: \"server\",\n name,\n args: args || {},\n });\n\n // Cleanup\n await client.disconnect();\n\n return c.json({ content });\n } catch (error) {\n await client.disconnect();\n throw error;\n }\n } catch (error) {\n console.error(\"Error getting prompt:\", error);\n return c.json(\n {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n 500,\n );\n }\n});\n\nexport default prompts;\n","import { Hono } from \"hono\";\nimport {\n validateMultipleServerConfigs,\n createMCPClientWithMultipleConnections,\n} from \"../../utils/mcp-utils\";\nimport { Agent } from \"@mastra/core/agent\";\nimport { createAnthropic } from \"@ai-sdk/anthropic\";\nimport { createOpenAI } from \"@ai-sdk/openai\";\nimport { createOllama } from \"ollama-ai-provider\";\nimport { ChatMessage, ModelDefinition } from \"../../../shared/types\";\nimport { MCPClient } from \"@mastra/mcp\";\nimport { ContentfulStatusCode } from \"hono/utils/http-status\";\n\nconst chat = new Hono();\n\n// Store for pending elicitation requests\nconst pendingElicitations = new Map<\n string,\n {\n resolve: (response: any) => void;\n reject: (error: any) => void;\n }\n>();\n\nchat.post(\"/\", async (c) => {\n let client: MCPClient | null = null;\n try {\n const requestData = await c.req.json();\n const {\n serverConfigs,\n model,\n apiKey,\n systemPrompt,\n messages,\n ollamaBaseUrl,\n action,\n requestId,\n response,\n }: {\n serverConfigs?: Record<string, any>;\n model?: ModelDefinition;\n apiKey?: string;\n systemPrompt?: string;\n messages?: ChatMessage[];\n ollamaBaseUrl?: string;\n action?: string;\n requestId?: string;\n response?: any;\n } = requestData;\n\n // Handle elicitation response\n if (action === \"elicitation_response\") {\n if (!requestId) {\n return c.json(\n {\n success: false,\n error: \"requestId is required for elicitation_response action\",\n },\n 400,\n );\n }\n\n const pending = pendingElicitations.get(requestId);\n if (!pending) {\n return c.json(\n {\n success: false,\n error: \"No pending elicitation found for this requestId\",\n },\n 404,\n );\n }\n\n // Resolve the pending elicitation with user's response\n pending.resolve(response);\n pendingElicitations.delete(requestId);\n\n return c.json({ success: true });\n }\n\n if (!model || !model.id || !apiKey || !messages) {\n return c.json(\n {\n success: false,\n error: \"model (with id), apiKey, and messages are required\",\n },\n 400,\n );\n }\n\n if (serverConfigs && Object.keys(serverConfigs).length > 0) {\n const validation = validateMultipleServerConfigs(serverConfigs);\n if (!validation.success) {\n return c.json(\n {\n success: false,\n error: validation.error!.message,\n details: validation.errors,\n },\n validation.error!.status as ContentfulStatusCode,\n );\n }\n\n client = createMCPClientWithMultipleConnections(validation.validConfigs!);\n } else {\n client = new MCPClient({\n id: `chat-${Date.now()}`,\n servers: {},\n });\n }\n\n // Get tools and ensure client is connected\n const tools = await client.getTools();\n\n const llmModel = getLlmModel(model, apiKey, ollamaBaseUrl);\n\n // Create a custom event emitter for streaming tool events\n let toolCallId = 0;\n let streamController: ReadableStreamDefaultController | null = null;\n let encoder: TextEncoder | null = null;\n\n // Set up elicitation handler\n const elicitationHandler = async (elicitationRequest: any) => {\n const requestId = `elicit_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n\n // Stream elicitation request to client\n if (streamController && encoder) {\n streamController.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({\n type: \"elicitation_request\",\n requestId,\n message: elicitationRequest.message,\n schema: elicitationRequest.requestedSchema,\n timestamp: new Date(),\n })}\\n\\n`,\n ),\n );\n }\n\n // Return a promise that will be resolved when user responds\n return new Promise<{\n action: \"accept\" | \"decline\" | \"cancel\";\n content?: { [x: string]: unknown };\n _meta?: { [x: string]: unknown };\n }>((resolve, reject) => {\n pendingElicitations.set(requestId, { resolve, reject });\n\n // Set a timeout to clean up if no response\n setTimeout(() => {\n if (pendingElicitations.has(requestId)) {\n pendingElicitations.delete(requestId);\n reject(new Error(\"Elicitation timeout\"));\n }\n }, 300000); // 5 minute timeout\n });\n };\n\n // Register elicitation handler with the client for all servers\n if (client.elicitation && client.elicitation.onRequest && serverConfigs) {\n // Register elicitation handler for each server\n for (const serverName of Object.keys(serverConfigs)) {\n // Normalize server name to match MCPClient's internal naming\n const normalizedName = serverName\n .toLowerCase()\n .replace(/[\\s\\-]+/g, \"_\")\n .replace(/[^a-z0-9_]/g, \"\");\n client.elicitation.onRequest(normalizedName, elicitationHandler);\n }\n }\n\n // Wrap tools to capture tool calls and results\n const originalTools = tools && Object.keys(tools).length > 0 ? tools : {};\n const wrappedTools: Record<string, any> = {};\n\n for (const [name, tool] of Object.entries(originalTools)) {\n wrappedTools[name] = {\n ...(tool as any),\n execute: async (params: any) => {\n const currentToolCallId = ++toolCallId;\n\n // Stream tool call event immediately\n if (streamController && encoder) {\n streamController.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({\n type: \"tool_call\",\n toolCall: {\n id: currentToolCallId,\n name,\n parameters: params,\n timestamp: new Date(),\n status: \"executing\",\n },\n })}\\n\\n`,\n ),\n );\n }\n\n try {\n const result = await (tool as any).execute(params);\n\n // Stream tool result event immediately\n if (streamController && encoder) {\n streamController.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({\n type: \"tool_result\",\n toolResult: {\n id: currentToolCallId,\n toolCallId: currentToolCallId,\n result,\n timestamp: new Date(),\n },\n })}\\n\\n`,\n ),\n );\n }\n\n return result;\n } catch (error) {\n // Stream tool error event immediately\n if (streamController && encoder) {\n streamController.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({\n type: \"tool_result\",\n toolResult: {\n id: currentToolCallId,\n toolCallId: currentToolCallId,\n error:\n error instanceof Error ? error.message : String(error),\n timestamp: new Date(),\n },\n })}\\n\\n`,\n ),\n );\n }\n throw error;\n }\n },\n };\n }\n\n const agent = new Agent({\n name: \"MCP Chat Agent\",\n instructions:\n systemPrompt || \"You are a helpful assistant with access to MCP tools.\",\n model: llmModel,\n tools: Object.keys(wrappedTools).length > 0 ? wrappedTools : undefined,\n });\n\n const formattedMessages = messages.map((msg: ChatMessage) => ({\n role: msg.role,\n content: msg.content,\n }));\n\n // Start streaming\n const stream = await agent.stream(formattedMessages, {\n maxSteps: 10, // Allow up to 10 steps for tool usage\n });\n\n encoder = new TextEncoder();\n const readableStream = new ReadableStream({\n async start(controller) {\n streamController = controller;\n\n try {\n let hasContent = false;\n for await (const chunk of stream.textStream) {\n if (chunk && chunk.trim()) {\n hasContent = true;\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({ type: \"text\", content: chunk })}\\n\\n`,\n ),\n );\n }\n }\n\n // If no content was streamed, send a fallback message\n if (!hasContent) {\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({ type: \"text\", content: \"I apologize, but I couldn't generate a response. Please try again.\" })}\\n\\n`,\n ),\n );\n }\n\n // Stream elicitation completion if there were any\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"elicitation_complete\",\n })}\\n\\n`,\n ),\n );\n\n controller.enqueue(encoder!.encode(`data: [DONE]\\n\\n`));\n } catch (error) {\n console.error(\"Streaming error:\", error);\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"error\",\n error: error instanceof Error ? error.message : \"Unknown error\",\n })}\\n\\n`,\n ),\n );\n } finally {\n if (client) {\n try {\n await client.disconnect();\n } catch (cleanupError) {\n console.warn(\n \"Error cleaning up MCP client after streaming:\",\n cleanupError,\n );\n }\n }\n controller.close();\n }\n },\n });\n\n return new Response(readableStream, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n });\n } catch (error) {\n console.error(\"Error in chat API:\", error);\n\n // Clean up client on error\n if (client) {\n try {\n await client.disconnect();\n } catch (cleanupError) {\n console.warn(\"Error cleaning up MCP client after error:\", cleanupError);\n }\n }\n\n return c.json(\n {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n 500,\n );\n }\n});\n\nconst getLlmModel = (\n modelDefinition: ModelDefinition,\n apiKey: string,\n ollamaBaseUrl?: string,\n) => {\n if (!modelDefinition || !modelDefinition.id || !modelDefinition.provider) {\n throw new Error(\n `Invalid model definition: ${JSON.stringify(modelDefinition)}`,\n );\n }\n\n switch (modelDefinition.provider) {\n case \"anthropic\":\n return createAnthropic({ apiKey })(modelDefinition.id);\n case \"openai\":\n return createOpenAI({ apiKey })(modelDefinition.id);\n case \"ollama\":\n const baseUrl = ollamaBaseUrl || \"http://localhost:11434\";\n return createOllama({\n baseURL: `${baseUrl}/api`, // Configurable Ollama API endpoint\n })(modelDefinition.id, {\n simulateStreaming: true, // Enable streaming for Ollama models\n });\n default:\n throw new Error(\n `Unsupported provider: ${modelDefinition.provider} for model: ${modelDefinition.id}`,\n );\n }\n};\n\nexport default chat;\n","import { Hono } from \"hono\";\nimport { ContentfulStatusCode } from \"hono/utils/http-status\";\n\nconst oauth = new Hono();\n\n/**\n * Proxy OAuth metadata requests to bypass CORS restrictions\n * GET /api/mcp/oauth/metadata?url=https://mcp.asana.com/.well-known/oauth-authorization-server/sse\n */\noauth.get(\"/metadata\", async (c) => {\n try {\n const url = c.req.query(\"url\");\n\n if (!url) {\n return c.json({ error: \"Missing url parameter\" }, 400);\n }\n\n // Validate URL format and ensure it's HTTPS\n let metadataUrl: URL;\n try {\n metadataUrl = new URL(url);\n if (metadataUrl.protocol !== \"https:\") {\n return c.json({ error: \"Only HTTPS URLs are allowed\" }, 400);\n }\n } catch (error) {\n return c.json({ error: \"Invalid URL format\" }, 400);\n }\n\n // Fetch OAuth metadata from the server\n const response = await fetch(metadataUrl.toString(), {\n method: \"GET\",\n headers: {\n Accept: \"application/json\",\n \"User-Agent\": \"MCP-Inspector/1.0\",\n },\n });\n\n if (!response.ok) {\n return c.json(\n {\n error: `Failed to fetch OAuth metadata: ${response.status} ${response.statusText}`,\n },\n response.status as ContentfulStatusCode,\n );\n }\n\n const metadata = await response.json();\n\n // Return the metadata with proper CORS headers\n return c.json(metadata);\n } catch (error) {\n console.error(\"OAuth metadata proxy error:\", error);\n return c.json(\n {\n error:\n error instanceof Error ? error.message : \"Unknown error occurred\",\n },\n 500,\n );\n }\n});\n\nexport default oauth;\n"],"mappings":"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","names":["Hono","Hono","Hono","Hono","tools","toolName","requestId","Hono","Hono","resources","Hono","Hono","prompts","Hono","MCPClient","Hono","pendingElicitations","tools","requestId","Hono","Hono","Hono"]}
|
|
1
|
+
{"version":3,"sources":["../../server/index.ts","../../server/routes/mcp/index.ts","../../server/routes/mcp/connect.ts","../../server/utils/mcp-utils.ts","../../server/routes/mcp/tools.ts","../../server/routes/mcp/resources.ts","../../server/routes/mcp/prompts.ts","../../server/routes/mcp/chat.ts","../../client/src/lib/chat-utils.ts","../../server/routes/mcp/oauth.ts"],"sourcesContent":["import { serve } from \"@hono/node-server\";\nimport { Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport { logger } from \"hono/logger\";\nimport { serveStatic } from \"@hono/node-server/serve-static\";\nimport { readFileSync } from \"fs\";\nimport { join } from \"path\";\n\n// ANSI color codes for console output\nconst colors = {\n reset: \"\\x1b[0m\",\n bright: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n blue: \"\\x1b[34m\",\n magenta: \"\\x1b[35m\",\n cyan: \"\\x1b[36m\",\n white: \"\\x1b[37m\",\n};\n\n// Utility function to create a boxed console output\nfunction logBox(content: string, title?: string) {\n const lines = content.split(\"\\n\");\n const maxLength = Math.max(...lines.map((line) => line.length));\n const width = maxLength + 4;\n\n console.log(\"┌\" + \"─\".repeat(width) + \"┐\");\n if (title) {\n const titlePadding = Math.floor((width - title.length - 2) / 2);\n console.log(\n \"│\" +\n \" \".repeat(titlePadding) +\n title +\n \" \".repeat(width - title.length - titlePadding) +\n \"│\",\n );\n console.log(\"├\" + \"─\".repeat(width) + \"┤\");\n }\n\n lines.forEach((line) => {\n const padding = width - line.length - 2;\n console.log(\"│ \" + line + \" \".repeat(padding) + \" │\");\n });\n\n console.log(\"└\" + \"─\".repeat(width) + \"┘\");\n}\n\n// Import routes\nimport mcpRoutes from \"./routes/mcp/index\";\n\n// Utility function to extract MCP server config from environment variables\nfunction getMCPConfigFromEnv() {\n const command = process.env.MCP_SERVER_COMMAND;\n if (!command) {\n return null;\n }\n\n const argsString = process.env.MCP_SERVER_ARGS;\n const args = argsString ? JSON.parse(argsString) : [];\n\n return {\n command,\n args,\n name: \"CLI Server\", // Default name for CLI-provided servers\n };\n}\n\nconst app = new Hono();\n\n// Middleware\napp.use(\"*\", logger());\n// Dynamic CORS origin based on PORT environment variable\nconst serverPort = process.env.PORT || \"3001\";\nconst corsOrigins = [\n `http://localhost:${serverPort}`,\n \"http://localhost:3000\", // Keep for development\n \"http://localhost:3001\", // Keep for development\n];\n\napp.use(\n \"*\",\n cors({\n origin: corsOrigins,\n credentials: true,\n }),\n);\n\n// API Routes\napp.route(\"/api/mcp\", mcpRoutes);\n\n// Health check\napp.get(\"/health\", (c) => {\n return c.json({ status: \"ok\", timestamp: new Date().toISOString() });\n});\n\n// API endpoint to get MCP CLI config (for development mode)\napp.get(\"/api/mcp-cli-config\", (c) => {\n const mcpConfig = getMCPConfigFromEnv();\n return c.json({ config: mcpConfig });\n});\n\n// Static file serving (for production)\nif (process.env.NODE_ENV === \"production\") {\n // Serve static assets (JS, CSS, images, etc.)\n app.use(\"/*\", serveStatic({ root: \"./dist/client\" }));\n\n // SPA fallback - serve index.html for all non-API routes\n app.get(\"*\", async (c) => {\n const path = c.req.path;\n // Don't intercept API routes\n if (path.startsWith(\"/api/\")) {\n return c.notFound();\n }\n // Return index.html for SPA routes\n const indexPath = join(process.cwd(), \"dist\", \"client\", \"index.html\");\n let htmlContent = readFileSync(indexPath, \"utf-8\");\n\n // Inject MCP server config if provided via CLI\n const mcpConfig = getMCPConfigFromEnv();\n if (mcpConfig) {\n const configScript = `<script>window.MCP_CLI_CONFIG = ${JSON.stringify(mcpConfig)};</script>`;\n htmlContent = htmlContent.replace(\"</head>\", `${configScript}</head>`);\n }\n\n return c.html(htmlContent);\n });\n} else {\n // Development mode - just API\n app.get(\"/\", (c) => {\n return c.json({\n message: \"MCPJam API Server\",\n environment: \"development\",\n frontend: `http://localhost:${serverPort}`,\n });\n });\n}\n\nconst port = parseInt(process.env.PORT || \"3001\");\n\n// Display the localhost URL in a box\nlogBox(`http://localhost:${port}`, \"🚀 Inspector Launched\");\n\n// Graceful shutdown handling\nconst server = serve({\n fetch: app.fetch,\n port,\n hostname: \"0.0.0.0\", // Bind to all interfaces for Docker\n});\n\n// Handle graceful shutdown\nprocess.on(\"SIGINT\", () => {\n console.log(\"\\n🛑 Shutting down gracefully...\");\n server.close();\n process.exit(0);\n});\n\nprocess.on(\"SIGTERM\", () => {\n console.log(\"\\n🛑 Shutting down gracefully...\");\n server.close();\n process.exit(0);\n});\n\nexport default app;\n","import { Hono } from \"hono\";\nimport connect from \"./connect\";\nimport tools from \"./tools\";\nimport resources from \"./resources\";\nimport prompts from \"./prompts\";\nimport chat from \"./chat\";\nimport oauth from \"./oauth\";\n\nconst mcp = new Hono();\n\n// Health check\nmcp.get(\"/health\", (c) => {\n return c.json({\n service: \"MCP API\",\n status: \"ready\",\n timestamp: new Date().toISOString(),\n });\n});\n\n// Chat endpoint - REAL IMPLEMENTATION\nmcp.route(\"/chat\", chat);\n\n// Connect endpoint - REAL IMPLEMENTATION\nmcp.route(\"/connect\", connect);\n\n// Tools endpoint - REAL IMPLEMENTATION\nmcp.route(\"/tools\", tools);\n\n// Resources endpoints - REAL IMPLEMENTATION\nmcp.route(\"/resources\", resources);\n\n// Prompts endpoints - REAL IMPLEMENTATION\nmcp.route(\"/prompts\", prompts);\n\n// OAuth proxy endpoints\nmcp.route(\"/oauth\", oauth);\n\nexport default mcp;\n","import { Hono } from \"hono\";\nimport { validateServerConfig, createMCPClient } from \"../../utils/mcp-utils\";\nimport { ContentfulStatusCode } from \"hono/utils/http-status\";\n\nconst connect = new Hono();\n\nconnect.post(\"/\", async (c) => {\n try {\n const { serverConfig } = await c.req.json();\n\n const validation = validateServerConfig(serverConfig);\n if (!validation.success) {\n const error = validation.error!;\n return c.json(\n {\n success: false,\n error: error.message,\n },\n error.status as ContentfulStatusCode,\n );\n }\n\n let client;\n try {\n client = createMCPClient(validation.config!, `test-${Date.now()}`);\n } catch (error) {\n return c.json(\n {\n success: false,\n error: `Failed to create a MCP client. Please double check your server configuration: ${JSON.stringify(serverConfig)}`,\n details: error instanceof Error ? error.message : \"Unknown error\",\n },\n 500,\n );\n }\n\n try {\n await client.getTools();\n await client.disconnect();\n return c.json({\n success: true,\n });\n } catch (error) {\n return c.json(\n {\n success: false,\n error: `MCP configuration is invalid. Please double check your server configuration: ${JSON.stringify(serverConfig)}`,\n details: error instanceof Error ? error.message : \"Unknown error\",\n },\n 500,\n );\n }\n } catch (error) {\n return c.json(\n {\n success: false,\n error: \"Failed to parse request body\",\n details: error instanceof Error ? error.message : \"Unknown error\",\n },\n 400,\n );\n }\n});\n\nexport default connect;\n","import { MastraMCPServerDefinition, MCPClient } from \"@mastra/mcp\";\n\n// Hono-compatible error response type\nexport interface HonoErrorResponse {\n message: string;\n status: number;\n}\n\nexport interface ValidationResult {\n success: boolean;\n config?: MastraMCPServerDefinition;\n error?: HonoErrorResponse;\n}\n\nexport interface MultipleValidationResult {\n success: boolean;\n validConfigs?: Record<string, MastraMCPServerDefinition>;\n errors?: Record<string, string>;\n error?: HonoErrorResponse;\n}\n\nexport function validateServerConfig(serverConfig: any): ValidationResult {\n if (!serverConfig) {\n return {\n success: false,\n error: {\n message: \"Server configuration is required\",\n status: 400,\n },\n };\n }\n\n // Validate and prepare config\n const config = { ...serverConfig };\n\n // Validate and convert URL if provided\n if (config.url) {\n try {\n // Convert string URL to URL object if needed and strip query/hash\n if (typeof config.url === \"string\") {\n const parsed = new URL(config.url);\n parsed.search = \"\";\n parsed.hash = \"\";\n config.url = parsed;\n } else if (typeof config.url === \"object\" && !config.url.href) {\n return {\n success: false,\n error: {\n message: \"Invalid URL configuration\",\n status: 400,\n },\n };\n }\n\n // Handle OAuth authentication for HTTP servers\n if (config.oauth?.access_token) {\n const authHeaders = {\n Authorization: `Bearer ${config.oauth.access_token}`,\n ...(config.requestInit?.headers || {}),\n };\n\n config.requestInit = {\n ...config.requestInit,\n headers: authHeaders,\n };\n\n // For SSE connections, add eventSourceInit with OAuth headers\n config.eventSourceInit = {\n fetch(input: Request | URL | string, init?: RequestInit) {\n const headers = new Headers(init?.headers || {});\n\n // Add OAuth authorization header\n headers.set(\n \"Authorization\",\n `Bearer ${config.oauth!.access_token}`,\n );\n\n // Copy other headers from requestInit\n if (config.requestInit?.headers) {\n const requestHeaders = new Headers(config.requestInit.headers);\n requestHeaders.forEach((value, key) => {\n if (key.toLowerCase() !== \"authorization\") {\n headers.set(key, value);\n }\n });\n }\n\n return fetch(input, {\n ...init,\n headers,\n });\n },\n };\n } else if (config.requestInit?.headers) {\n // For SSE connections without OAuth, add eventSourceInit if requestInit has custom headers\n config.eventSourceInit = {\n fetch(input: Request | URL | string, init?: RequestInit) {\n const headers = new Headers(init?.headers || {});\n\n // Copy headers from requestInit\n const requestHeaders = new Headers(config.requestInit.headers);\n requestHeaders.forEach((value, key) => {\n headers.set(key, value);\n });\n\n return fetch(input, {\n ...init,\n headers,\n });\n },\n };\n }\n } catch (error) {\n return {\n success: false,\n error: {\n message: `Invalid URL format: ${error}`,\n status: 400,\n },\n };\n }\n }\n\n return {\n success: true,\n config,\n };\n}\n\nexport function createMCPClient(\n config: MastraMCPServerDefinition,\n id: string,\n): MCPClient {\n return new MCPClient({\n id,\n servers: {\n server: config,\n },\n });\n}\n\nexport interface MultipleValidationResult {\n success: boolean;\n validConfigs?: Record<string, MastraMCPServerDefinition>;\n errors?: Record<string, string>;\n error?: HonoErrorResponse;\n}\n\nexport const validateMultipleServerConfigs = (\n serverConfigs: Record<string, MastraMCPServerDefinition>,\n): MultipleValidationResult => {\n if (!serverConfigs || Object.keys(serverConfigs).length === 0) {\n return {\n success: false,\n error: {\n message: \"At least one server configuration is required\",\n status: 400,\n },\n };\n }\n\n const validConfigs: Record<string, MastraMCPServerDefinition> = {};\n const errors: Record<string, string> = {};\n let hasErrors = false;\n\n // Validate each server configuration\n for (const [serverName, serverConfig] of Object.entries(serverConfigs)) {\n const validationResult = validateServerConfig(serverConfig);\n\n if (validationResult.success && validationResult.config) {\n validConfigs[serverName] = validationResult.config;\n } else {\n hasErrors = true;\n let errorMessage = \"Configuration validation failed\";\n if (validationResult.error) {\n errorMessage = validationResult.error.message;\n }\n errors[serverName] = errorMessage;\n }\n }\n\n // If all configs are valid, return success\n if (!hasErrors) {\n return {\n success: true,\n validConfigs,\n };\n }\n\n // If some configs are valid but others failed, return partial success\n if (Object.keys(validConfigs).length > 0) {\n return {\n success: false,\n validConfigs,\n errors,\n };\n }\n\n // If all configs failed, return error\n return {\n success: false,\n errors,\n error: {\n message: \"All server configurations failed validation\",\n status: 400,\n },\n };\n};\n\nexport function createMCPClientWithMultipleConnections(\n serverConfigs: Record<string, MastraMCPServerDefinition>,\n): MCPClient {\n // Normalize server config names\n const normalizedConfigs: Record<string, MastraMCPServerDefinition> = {};\n for (const [serverName, config] of Object.entries(serverConfigs)) {\n const normalizedName = normalizeServerConfigName(serverName);\n normalizedConfigs[normalizedName] = config;\n }\n\n return new MCPClient({\n id: `chat-${Date.now()}`,\n servers: normalizedConfigs,\n });\n}\n\nexport function normalizeServerConfigName(serverName: string): string {\n // Convert to lowercase and replace spaces/hyphens with underscores\n return serverName\n .toLowerCase()\n .replace(/[\\s\\-]+/g, \"_\")\n .replace(/[^a-z0-9_]/g, \"\");\n}\n\nexport function createErrorResponse(\n message: string,\n details?: string,\n status: number = 500,\n): HonoErrorResponse {\n return {\n message: details ? `${message}: ${details}` : message,\n status,\n };\n}\n","import { Hono } from \"hono\";\nimport { validateServerConfig, createMCPClient } from \"../../utils/mcp-utils\";\nimport type { Tool } from \"@mastra/core/tools\";\nimport { z } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport { ContentfulStatusCode } from \"hono/utils/http-status\";\nimport { TextEncoder } from \"util\";\n\nconst tools = new Hono();\n\n// Store for pending elicitation requests\nconst pendingElicitations = new Map<\n string,\n {\n resolve: (response: any) => void;\n reject: (error: any) => void;\n }\n>();\n\ntools.post(\"/\", async (c) => {\n let client: any = null;\n let encoder: TextEncoder | null = null;\n let streamController: ReadableStreamDefaultController | null = null;\n let action: string | undefined;\n let toolName: string | undefined;\n\n try {\n const requestData = await c.req.json();\n action = requestData.action;\n toolName = requestData.toolName;\n const { serverConfig, parameters, requestId, response } = requestData;\n\n if (!action || ![\"list\", \"execute\", \"respond\"].includes(action)) {\n return c.json(\n {\n success: false,\n error: \"Action must be 'list', 'execute', or 'respond'\",\n },\n 400,\n );\n }\n\n // Handle elicitation response\n if (action === \"respond\") {\n if (!requestId) {\n return c.json(\n {\n success: false,\n error: \"requestId is required for respond action\",\n },\n 400,\n );\n }\n\n const pending = pendingElicitations.get(requestId);\n if (!pending) {\n return c.json(\n {\n success: false,\n error: \"No pending elicitation found for this requestId\",\n },\n 404,\n );\n }\n\n // Resolve the pending elicitation with user's response\n pending.resolve(response);\n pendingElicitations.delete(requestId);\n\n return c.json({ success: true });\n }\n\n const validation = validateServerConfig(serverConfig);\n if (!validation.success) {\n return c.json(\n { success: false, error: validation.error!.message },\n validation.error!.status as ContentfulStatusCode,\n );\n }\n\n encoder = new TextEncoder();\n const readableStream = new ReadableStream({\n async start(controller) {\n streamController = controller;\n\n try {\n const clientId = `tools-${action}-${Date.now()}`;\n client = createMCPClient(validation.config!, clientId);\n\n if (action === \"list\") {\n // Stream tools list\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"tools_loading\",\n message: \"Fetching tools from server...\",\n })}\\n\\n`,\n ),\n );\n\n const tools: Record<string, Tool> = await client.getTools();\n\n // Convert from Zod to JSON Schema\n const toolsWithJsonSchema: Record<string, any> = Object.fromEntries(\n Object.entries(tools).map(([toolName, tool]) => {\n return [\n toolName,\n {\n ...tool,\n inputSchema: zodToJsonSchema(\n tool.inputSchema as unknown as z.ZodType<any>,\n ),\n },\n ];\n }),\n );\n\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"tools_list\",\n tools: toolsWithJsonSchema,\n })}\\n\\n`,\n ),\n );\n } else if (action === \"execute\") {\n // Stream tool execution\n if (!toolName) {\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"tool_error\",\n error: \"Tool name is required for execution\",\n })}\\n\\n`,\n ),\n );\n return;\n }\n\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"tool_executing\",\n toolName,\n parameters: parameters || {},\n message: \"Executing tool...\",\n })}\\n\\n`,\n ),\n );\n\n const tools = await client.getTools();\n const tool = tools[toolName];\n\n if (!tool) {\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"tool_error\",\n error: `Tool '${toolName}' not found`,\n })}\\n\\n`,\n ),\n );\n return;\n }\n\n const toolArgs =\n parameters && typeof parameters === \"object\" ? parameters : {};\n\n // Set up elicitation handler\n const elicitationHandler = async (elicitationRequest: any) => {\n const requestId = `elicit_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n\n // Stream elicitation request to client\n if (streamController && encoder) {\n streamController.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({\n type: \"elicitation_request\",\n requestId,\n message: elicitationRequest.message,\n schema: elicitationRequest.requestedSchema,\n timestamp: new Date(),\n })}\\n\\n`,\n ),\n );\n }\n\n // Return a promise that will be resolved when user responds\n return new Promise((resolve, reject) => {\n pendingElicitations.set(requestId, { resolve, reject });\n\n // Set a timeout to clean up if no response\n setTimeout(() => {\n if (pendingElicitations.has(requestId)) {\n pendingElicitations.delete(requestId);\n reject(new Error(\"Elicitation timeout\"));\n }\n }, 300000); // 5 minute timeout\n });\n };\n\n // Register elicitation handler with the client\n if (client.elicitation && client.elicitation.onRequest) {\n const serverName = \"server\"; // See createMCPClient() function. The name of the server is \"server\"\n client.elicitation.onRequest(serverName, elicitationHandler);\n }\n\n const result = await tool.execute({\n context: toolArgs,\n });\n\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"tool_result\",\n toolName,\n result,\n })}\\n\\n`,\n ),\n );\n\n // Stream elicitation completion if there were any\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"elicitation_complete\",\n toolName,\n })}\\n\\n`,\n ),\n );\n }\n\n controller.enqueue(encoder!.encode(`data: [DONE]\\n\\n`));\n } catch (error) {\n const errorMsg =\n error instanceof Error ? error.message : \"Unknown error\";\n\n controller.enqueue(\n encoder!.encode(\n `data: ${JSON.stringify({\n type: \"tool_error\",\n error: errorMsg,\n })}\\n\\n`,\n ),\n );\n } finally {\n if (client) {\n await client.disconnect();\n }\n controller.close();\n }\n },\n });\n\n return new Response(readableStream, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n });\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : \"Unknown error\";\n\n // Clean up client on error\n if (client) {\n try {\n await client.disconnect();\n } catch (cleanupError) {\n // Ignore cleanup errors\n }\n }\n\n return c.json(\n {\n success: false,\n error: errorMsg,\n },\n 500,\n );\n }\n});\n\nexport default tools;\n","import { Hono } from \"hono\";\nimport { validateServerConfig, createMCPClient } from \"../../utils/mcp-utils\";\nimport { ContentfulStatusCode } from \"hono/utils/http-status\";\n\nconst resources = new Hono();\n\n// List resources endpoint\nresources.post(\"/list\", async (c) => {\n try {\n const { serverConfig } = await c.req.json();\n\n const validation = validateServerConfig(serverConfig);\n if (!validation.success) {\n return c.json(\n { success: false, error: validation.error!.message },\n validation.error!.status as ContentfulStatusCode,\n );\n }\n\n const client = createMCPClient(\n validation.config!,\n `resources-list-${Date.now()}`,\n );\n\n try {\n const resources = await client.resources.list();\n\n // Cleanup\n await client.disconnect();\n\n return c.json({ resources });\n } catch (error) {\n await client.disconnect();\n throw error;\n }\n } catch (error) {\n console.error(\"Error fetching resources:\", error);\n return c.json(\n {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n 500,\n );\n }\n});\n\n// Read resource endpoint\nresources.post(\"/read\", async (c) => {\n try {\n const { serverConfig, uri } = await c.req.json();\n\n const validation = validateServerConfig(serverConfig);\n if (!validation.success) {\n return c.json(\n { success: false, error: validation.error!.message },\n validation.error!.status as ContentfulStatusCode,\n );\n }\n\n if (!uri) {\n return c.json(\n {\n success: false,\n error: \"Resource URI is required\",\n },\n 400,\n );\n }\n\n const client = createMCPClient(\n validation.config!,\n `resources-read-${Date.now()}`,\n );\n\n try {\n const content = await client.resources.read(\"server\", uri);\n\n // Cleanup\n await client.disconnect();\n\n return c.json({ content });\n } catch (error) {\n await client.disconnect();\n throw error;\n }\n } catch (error) {\n console.error(\"Error reading resource:\", error);\n return c.json(\n {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n 500,\n );\n }\n});\n\nexport default resources;\n","import { Hono } from \"hono\";\nimport { validateServerConfig, createMCPClient } from \"../../utils/mcp-utils\";\nimport { ContentfulStatusCode } from \"hono/utils/http-status\";\n\nconst prompts = new Hono();\n\n// List prompts endpoint\nprompts.post(\"/list\", async (c) => {\n try {\n const { serverConfig } = await c.req.json();\n\n const validation = validateServerConfig(serverConfig);\n if (!validation.success) {\n return c.json(\n { success: false, error: validation.error!.message },\n validation.error!.status as ContentfulStatusCode,\n );\n }\n\n const client = createMCPClient(\n validation.config!,\n `prompts-list-${Date.now()}`,\n );\n\n try {\n const prompts = await client.prompts.list();\n\n // Cleanup\n await client.disconnect();\n\n return c.json({ prompts });\n } catch (error) {\n await client.disconnect();\n throw error;\n }\n } catch (error) {\n console.error(\"Error fetching prompts:\", error);\n return c.json(\n {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n 500,\n );\n }\n});\n\n// Get prompt endpoint\nprompts.post(\"/get\", async (c) => {\n try {\n const { serverConfig, name, args } = await c.req.json();\n\n const validation = validateServerConfig(serverConfig);\n if (!validation.success) {\n return c.json(\n { success: false, error: validation.error!.message },\n validation.error!.status as ContentfulStatusCode,\n );\n }\n\n if (!name) {\n return c.json(\n {\n success: false,\n error: \"Prompt name is required\",\n },\n 400,\n );\n }\n\n const client = createMCPClient(\n validation.config!,\n `prompts-get-${Date.now()}`,\n );\n\n try {\n const content = await client.prompts.get({\n serverName: \"server\",\n name,\n args: args || {},\n });\n\n // Cleanup\n await client.disconnect();\n\n return c.json({ content });\n } catch (error) {\n await client.disconnect();\n throw error;\n }\n } catch (error) {\n console.error(\"Error getting prompt:\", error);\n return c.json(\n {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n 500,\n );\n }\n});\n\nexport default prompts;\n","import { Hono } from \"hono\";\nimport {\n validateMultipleServerConfigs,\n createMCPClientWithMultipleConnections,\n normalizeServerConfigName,\n} from \"../../utils/mcp-utils\";\nimport { Agent } from \"@mastra/core/agent\";\nimport { createAnthropic } from \"@ai-sdk/anthropic\";\nimport { createOpenAI } from \"@ai-sdk/openai\";\nimport { createOllama } from \"ollama-ai-provider\";\nimport {\n ChatMessage,\n ModelDefinition,\n ModelProvider,\n} from \"../../../shared/types\";\nimport { MCPClient } from \"@mastra/mcp\";\nimport { ContentfulStatusCode } from \"hono/utils/http-status\";\nimport { TextEncoder } from \"util\";\nimport { getDefaultTemperatureByProvider } from \"../../../client/src/lib/chat-utils\";\n\n// Types\ninterface ElicitationRequest {\n message: string;\n requestedSchema: any;\n}\n\ninterface ElicitationResponse {\n [key: string]: unknown;\n action: \"accept\" | \"decline\" | \"cancel\";\n content?: any;\n _meta?: any;\n}\n\ninterface PendingElicitation {\n resolve: (response: ElicitationResponse) => void;\n reject: (error: any) => void;\n}\n\ninterface StreamingContext {\n controller: ReadableStreamDefaultController;\n encoder: TextEncoder;\n toolCallId: number;\n lastEmittedToolCallId: number | null;\n}\n\ninterface ChatRequest {\n serverConfigs?: Record<string, any>;\n model: ModelDefinition;\n provider: ModelProvider;\n apiKey?: string;\n systemPrompt?: string;\n messages?: ChatMessage[];\n ollamaBaseUrl?: string;\n action?: string;\n requestId?: string;\n response?: any;\n}\n\n// Constants\nconst DEBUG_ENABLED = process.env.MCP_DEBUG !== \"false\";\nconst ELICITATION_TIMEOUT = 300000; // 5 minutes\nconst MAX_AGENT_STEPS = 10;\n\n// Debug logging helper\nconst dbg = (...args: any[]) => {\n if (DEBUG_ENABLED) console.log(\"[mcp/chat]\", ...args);\n};\n\n// Avoid MaxListeners warnings when repeatedly creating MCP clients in dev\ntry {\n (process as any).setMaxListeners?.(50);\n} catch {}\n\n// Store for pending elicitation requests\nconst pendingElicitations = new Map<string, PendingElicitation>();\n\nconst chat = new Hono();\n\n// Helper Functions\n\n/**\n * Creates an LLM model based on the provider and configuration\n */\nconst createLlmModel = (\n modelDefinition: ModelDefinition,\n apiKey: string,\n ollamaBaseUrl?: string,\n) => {\n if (!modelDefinition?.id || !modelDefinition?.provider) {\n throw new Error(\n `Invalid model definition: ${JSON.stringify(modelDefinition)}`,\n );\n }\n\n switch (modelDefinition.provider) {\n case \"anthropic\":\n return createAnthropic({ apiKey })(modelDefinition.id);\n case \"openai\":\n return createOpenAI({ apiKey })(modelDefinition.id);\n case \"deepseek\":\n return createOpenAI({ apiKey, baseURL: \"https://api.deepseek.com/v1\" })(\n modelDefinition.id,\n );\n case \"ollama\":\n const baseUrl = ollamaBaseUrl || \"http://localhost:11434\";\n return createOllama({\n baseURL: `${baseUrl}`,\n })(modelDefinition.id, {\n simulateStreaming: true,\n });\n default:\n throw new Error(\n `Unsupported provider: ${modelDefinition.provider} for model: ${modelDefinition.id}`,\n );\n }\n};\n\n/**\n * Handles elicitation requests by streaming them to the client and waiting for response\n */\nconst createElicitationHandler = (streamingContext: StreamingContext) => {\n return async (elicitationRequest: ElicitationRequest) => {\n const requestId = `elicit_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n\n // Stream elicitation request to client\n if (streamingContext.controller && streamingContext.encoder) {\n streamingContext.controller.enqueue(\n streamingContext.encoder.encode(\n `data: ${JSON.stringify({\n type: \"elicitation_request\",\n requestId,\n message: elicitationRequest.message,\n schema: elicitationRequest.requestedSchema,\n timestamp: new Date(),\n })}\\n\\n`,\n ),\n );\n }\n\n // Return a promise that will be resolved when user responds\n return new Promise<ElicitationResponse>((resolve, reject) => {\n pendingElicitations.set(requestId, { resolve, reject });\n\n // Set timeout to clean up if no response\n setTimeout(() => {\n if (pendingElicitations.has(requestId)) {\n pendingElicitations.delete(requestId);\n reject(new Error(\"Elicitation timeout\"));\n }\n }, ELICITATION_TIMEOUT);\n });\n };\n};\n\n/**\n * Wraps MCP tools to capture execution events and stream them to the client\n */\nconst wrapToolsWithStreaming = (\n tools: Record<string, any>,\n streamingContext: StreamingContext,\n) => {\n const wrappedTools: Record<string, any> = {};\n\n for (const [name, tool] of Object.entries(tools)) {\n wrappedTools[name] = {\n ...(tool as any),\n execute: async (params: any) => {\n const currentToolCallId = ++streamingContext.toolCallId;\n const startedAt = Date.now();\n\n // Stream tool call event immediately\n if (streamingContext.controller && streamingContext.encoder) {\n streamingContext.controller.enqueue(\n streamingContext.encoder.encode(\n `data: ${JSON.stringify({\n type: \"tool_call\",\n toolCall: {\n id: currentToolCallId,\n name,\n parameters: params,\n timestamp: new Date(),\n status: \"executing\",\n },\n })}\\n\\n`,\n ),\n );\n }\n\n dbg(\"Tool executing\", { name, currentToolCallId, params });\n\n try {\n const result = await (tool as any).execute(params);\n dbg(\"Tool result\", {\n name,\n currentToolCallId,\n ms: Date.now() - startedAt,\n });\n\n // Stream tool result event\n if (streamingContext.controller && streamingContext.encoder) {\n streamingContext.controller.enqueue(\n streamingContext.encoder.encode(\n `data: ${JSON.stringify({\n type: \"tool_result\",\n toolResult: {\n id: currentToolCallId,\n toolCallId: currentToolCallId,\n result,\n timestamp: new Date(),\n },\n })}\\n\\n`,\n ),\n );\n }\n\n return result;\n } catch (error) {\n dbg(\"Tool error\", {\n name,\n currentToolCallId,\n error: error instanceof Error ? error.message : String(error),\n });\n\n // Stream tool error event\n if (streamingContext.controller && streamingContext.encoder) {\n streamingContext.controller.enqueue(\n streamingContext.encoder.encode(\n `data: ${JSON.stringify({\n type: \"tool_result\",\n toolResult: {\n id: currentToolCallId,\n toolCallId: currentToolCallId,\n error:\n error instanceof Error ? error.message : String(error),\n timestamp: new Date(),\n },\n })}\\n\\n`,\n ),\n );\n }\n throw error;\n }\n },\n };\n }\n\n return wrappedTools;\n};\n\n/**\n * Handles tool call and result events from the agent's onStepFinish callback\n */\nconst handleAgentStepFinish = (\n streamingContext: StreamingContext,\n text: string,\n toolCalls: any[] | undefined,\n toolResults: any[] | undefined,\n) => {\n try {\n // Handle tool calls\n if (toolCalls && Array.isArray(toolCalls)) {\n for (const call of toolCalls) {\n const currentToolCallId = ++streamingContext.toolCallId;\n streamingContext.lastEmittedToolCallId = currentToolCallId;\n\n if (streamingContext.controller && streamingContext.encoder) {\n streamingContext.controller.enqueue(\n streamingContext.encoder.encode(\n `data: ${JSON.stringify({\n type: \"tool_call\",\n toolCall: {\n id: currentToolCallId,\n name: call.name || call.toolName,\n parameters: call.params || call.args || {},\n timestamp: new Date(),\n status: \"executing\",\n },\n })}\\n\\n`,\n ),\n );\n }\n }\n }\n\n // Handle tool results\n if (toolResults && Array.isArray(toolResults)) {\n for (const result of toolResults) {\n const currentToolCallId =\n streamingContext.lastEmittedToolCallId != null\n ? streamingContext.lastEmittedToolCallId\n : ++streamingContext.toolCallId;\n\n if (streamingContext.controller && streamingContext.encoder) {\n streamingContext.controller.enqueue(\n streamingContext.encoder.encode(\n `data: ${JSON.stringify({\n type: \"tool_result\",\n toolResult: {\n id: currentToolCallId,\n toolCallId: currentToolCallId,\n result: result.result,\n error: (result as any).error,\n timestamp: new Date(),\n },\n })}\\n\\n`,\n ),\n );\n }\n }\n }\n } catch (err) {\n dbg(\"onStepFinish error\", err);\n }\n};\n\n/**\n * Streams text content from the agent's response\n */\nconst streamAgentResponse = async (\n streamingContext: StreamingContext,\n stream: any,\n) => {\n let hasContent = false;\n let chunkCount = 0;\n\n for await (const chunk of stream.textStream) {\n if (chunk && chunk.trim()) {\n hasContent = true;\n chunkCount++;\n streamingContext.controller.enqueue(\n streamingContext.encoder!.encode(\n `data: ${JSON.stringify({ type: \"text\", content: chunk })}\\n\\n`,\n ),\n );\n }\n }\n\n dbg(\"Streaming finished\", { hasContent, chunkCount });\n return { hasContent, chunkCount };\n};\n\n/**\n * Falls back to regular completion when streaming fails\n */\nconst fallbackToCompletion = async (\n agent: Agent,\n messages: any[],\n streamingContext: StreamingContext,\n provider: ModelProvider,\n) => {\n try {\n const result = await agent.generate(messages, {\n temperature: getDefaultTemperatureByProvider(provider),\n });\n if (result.text && result.text.trim()) {\n streamingContext.controller.enqueue(\n streamingContext.encoder!.encode(\n `data: ${JSON.stringify({\n type: \"text\",\n content: result.text,\n })}\\n\\n`,\n ),\n );\n }\n } catch (fallbackErr) {\n streamingContext.controller.enqueue(\n streamingContext.encoder!.encode(\n `data: ${JSON.stringify({\n type: \"text\",\n content: \"Failed to generate response. Please try again. \",\n error:\n fallbackErr instanceof Error\n ? fallbackErr.message\n : \"Unknown error\",\n })}\\n\\n`,\n ),\n );\n }\n};\n\n/**\n * Safely disconnects an MCP client\n */\nconst safeDisconnect = async (client: MCPClient | null) => {\n if (client) {\n try {\n await client.disconnect();\n } catch (cleanupError) {\n console.warn(\"[mcp/chat] Error cleaning up MCP client:\", cleanupError);\n }\n }\n};\n\n/**\n * Creates the streaming response for the chat\n */\nconst createStreamingResponse = async (\n agent: Agent,\n messages: any[],\n toolsets: any,\n streamingContext: StreamingContext,\n provider: ModelProvider,\n) => {\n const stream = await agent.stream(messages, {\n maxSteps: MAX_AGENT_STEPS,\n temperature: getDefaultTemperatureByProvider(provider),\n toolsets,\n onStepFinish: ({ text, toolCalls, toolResults }) => {\n handleAgentStepFinish(streamingContext, text, toolCalls, toolResults);\n },\n });\n\n const { hasContent } = await streamAgentResponse(streamingContext, stream);\n\n // Fall back to completion if no content was streamed\n if (!hasContent) {\n dbg(\"No content from textStream; falling back to completion\");\n await fallbackToCompletion(agent, messages, streamingContext, provider);\n }\n\n // Stream elicitation completion\n streamingContext.controller.enqueue(\n streamingContext.encoder!.encode(\n `data: ${JSON.stringify({\n type: \"elicitation_complete\",\n })}\\n\\n`,\n ),\n );\n\n // End stream\n streamingContext.controller.enqueue(\n streamingContext.encoder!.encode(`data: [DONE]\\n\\n`),\n );\n};\n\n// Main chat endpoint\nchat.post(\"/\", async (c) => {\n let client: MCPClient | null = null;\n\n try {\n const requestData: ChatRequest = await c.req.json();\n const {\n serverConfigs,\n model,\n provider,\n apiKey,\n systemPrompt,\n messages,\n ollamaBaseUrl,\n action,\n requestId,\n response,\n } = requestData;\n\n // Handle elicitation response\n if (action === \"elicitation_response\") {\n if (!requestId) {\n return c.json(\n {\n success: false,\n error: \"requestId is required for elicitation_response action\",\n },\n 400,\n );\n }\n\n const pending = pendingElicitations.get(requestId);\n if (!pending) {\n return c.json(\n {\n success: false,\n error: \"No pending elicitation found for this requestId\",\n },\n 404,\n );\n }\n\n pending.resolve(response);\n pendingElicitations.delete(requestId);\n return c.json({ success: true });\n }\n\n // Validate required parameters\n if (!model?.id || !apiKey || !messages) {\n return c.json(\n {\n success: false,\n error: \"model (with id), apiKey, and messages are required\",\n },\n 400,\n );\n }\n\n // Validate and create MCP client\n if (!serverConfigs || Object.keys(serverConfigs).length === 0) {\n return c.json(\n {\n success: false,\n error: \"No server configs provided\",\n },\n 400,\n );\n }\n\n const validation = validateMultipleServerConfigs(serverConfigs);\n if (!validation.success) {\n dbg(\n \"Server config validation failed\",\n validation.errors || validation.error,\n );\n return c.json(\n {\n success: false,\n error: validation.error!.message,\n details: validation.errors,\n },\n validation.error!.status as ContentfulStatusCode,\n );\n }\n\n client = createMCPClientWithMultipleConnections(validation.validConfigs!);\n\n // Create LLM model\n const llmModel = createLlmModel(model, apiKey, ollamaBaseUrl);\n const tools = await client.getTools();\n\n // Create agent without tools initially - we'll add them in the streaming context\n const agent = new Agent({\n name: \"MCP Chat Agent\",\n instructions:\n systemPrompt || \"You are a helpful assistant with access to MCP tools.\",\n model: llmModel,\n tools: undefined, // Start without tools, add them in streaming context\n });\n\n const formattedMessages = messages.map((msg: ChatMessage) => ({\n role: msg.role,\n content: msg.content,\n }));\n\n // Get toolsets for dynamic tool resolution\n const toolsets = await client.getToolsets();\n dbg(\"Streaming start\", {\n toolsetServers: Object.keys(toolsets),\n messageCount: formattedMessages.length,\n });\n\n // Create streaming response\n const encoder = new TextEncoder();\n const readableStream = new ReadableStream({\n async start(controller) {\n const streamingContext: StreamingContext = {\n controller,\n encoder,\n toolCallId: 0,\n lastEmittedToolCallId: null,\n };\n\n // Create streaming-wrapped tools\n const streamingWrappedTools = wrapToolsWithStreaming(\n tools,\n streamingContext,\n );\n\n // Create a new agent instance with streaming tools since tools property is read-only\n const streamingAgent = new Agent({\n name: agent.name,\n instructions: agent.instructions,\n model: agent.model!,\n tools:\n Object.keys(streamingWrappedTools).length > 0\n ? streamingWrappedTools\n : undefined,\n });\n\n // Register elicitation handler\n if (client?.elicitation?.onRequest) {\n for (const serverName of Object.keys(serverConfigs)) {\n const normalizedName = normalizeServerConfigName(serverName);\n const elicitationHandler =\n createElicitationHandler(streamingContext);\n client.elicitation.onRequest(normalizedName, elicitationHandler);\n }\n }\n\n try {\n if (client) {\n await createStreamingResponse(\n streamingAgent,\n formattedMessages,\n toolsets,\n streamingContext,\n provider,\n );\n } else {\n throw new Error(\"MCP client is null\");\n }\n } catch (error) {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({\n type: \"error\",\n error: error instanceof Error ? error.message : \"Unknown error\",\n })}\\n\\n`,\n ),\n );\n } finally {\n await safeDisconnect(client);\n controller.close();\n }\n },\n });\n\n return new Response(readableStream, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n });\n } catch (error) {\n console.error(\"[mcp/chat] Error in chat API:\", error);\n await safeDisconnect(client);\n\n return c.json(\n {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n },\n 500,\n );\n }\n});\n\nexport default chat;\n","import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\nimport { ChatMessage } from \"./chat-types\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport function generateId(): string {\n return Math.random().toString(36).substr(2, 9);\n}\n\nexport function sanitizeText(text: string): string {\n // Basic sanitization - in production you might want more robust sanitization\n return text.trim();\n}\n\nexport function formatTimestamp(date: Date): string {\n return new Intl.DateTimeFormat(\"en-US\", {\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true,\n }).format(date);\n}\n\nexport function formatMessageDate(date: Date): string {\n const now = new Date();\n const diffInMs = now.getTime() - date.getTime();\n const diffInDays = Math.floor(diffInMs / (1000 * 60 * 60 * 24));\n\n if (diffInDays === 0) {\n return formatTimestamp(date);\n } else if (diffInDays === 1) {\n return `Yesterday ${formatTimestamp(date)}`;\n } else if (diffInDays < 7) {\n return `${diffInDays} days ago`;\n } else {\n return new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: date.getFullYear() !== now.getFullYear() ? \"numeric\" : undefined,\n }).format(date);\n }\n}\n\nexport function createMessage(\n role: \"user\" | \"assistant\",\n content: string,\n attachments?: any[]\n): ChatMessage {\n return {\n id: generateId(),\n role,\n content,\n timestamp: new Date(),\n attachments,\n metadata: {\n createdAt: new Date().toISOString(),\n },\n };\n}\n\nexport function isValidFileType(file: File): boolean {\n const allowedTypes = [\n \"text/plain\",\n \"application/pdf\",\n \"image/jpeg\",\n \"image/jpg\",\n \"image/png\",\n \"image/gif\",\n \"image/webp\",\n \"application/json\",\n \"text/csv\",\n \"application/vnd.ms-excel\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n ];\n\n return allowedTypes.includes(file.type);\n}\n\nexport function isImageFile(file: File): boolean {\n return file.type.startsWith(\"image/\");\n}\n\nexport function isImageUrl(url: string): boolean {\n const imageExtensions = [\".jpg\", \".jpeg\", \".png\", \".gif\", \".webp\", \".svg\"];\n const lowerUrl = url.toLowerCase();\n return (\n imageExtensions.some((ext) => lowerUrl.includes(ext)) ||\n lowerUrl.includes(\"data:image/\") ||\n lowerUrl.includes(\"blob:\")\n );\n}\n\nexport function getImageDimensions(\n url: string\n): Promise<{ width: number; height: number }> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n resolve({ width: img.naturalWidth, height: img.naturalHeight });\n };\n img.onerror = reject;\n img.src = url;\n });\n}\n\nexport function formatFileSize(bytes: number): string {\n if (bytes === 0) return \"0 B\";\n\n const k = 1024;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + \" \" + sizes[i];\n}\n\nexport function truncateText(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text;\n return text.substring(0, maxLength) + \"...\";\n}\n\nexport function scrollToBottom(element?: Element | null) {\n if (element) {\n element.scrollTop = element.scrollHeight;\n } else {\n window.scrollTo(0, document.body.scrollHeight);\n }\n}\n\nexport function debounce<T extends (...args: any[]) => any>(\n func: T,\n wait: number\n): (...args: Parameters<T>) => void {\n let timeout: NodeJS.Timeout;\n return (...args: Parameters<T>) => {\n clearTimeout(timeout);\n timeout = setTimeout(() => func(...args), wait);\n };\n}\n\nexport function getDefaultTemperatureByProvider(provider: string): number {\n switch (provider) {\n case \"openai\":\n return 1.0;\n case \"anthropic\":\n return 0;\n default:\n return 0;\n }\n}\n","import { Hono } from \"hono\";\nimport { ContentfulStatusCode } from \"hono/utils/http-status\";\n\nconst oauth = new Hono();\n\n/**\n * Proxy OAuth metadata requests to bypass CORS restrictions\n * GET /api/mcp/oauth/metadata?url=https://mcp.asana.com/.well-known/oauth-authorization-server/sse\n */\noauth.get(\"/metadata\", async (c) => {\n try {\n const url = c.req.query(\"url\");\n\n if (!url) {\n return c.json({ error: \"Missing url parameter\" }, 400);\n }\n\n // Validate URL format and ensure it's HTTPS\n let metadataUrl: URL;\n try {\n metadataUrl = new URL(url);\n if (metadataUrl.protocol !== \"https:\") {\n return c.json({ error: \"Only HTTPS URLs are allowed\" }, 400);\n }\n } catch (error) {\n return c.json({ error: \"Invalid URL format\" }, 400);\n }\n\n // Fetch OAuth metadata from the server\n const response = await fetch(metadataUrl.toString(), {\n method: \"GET\",\n headers: {\n Accept: \"application/json\",\n \"User-Agent\": \"MCP-Inspector/1.0\",\n },\n });\n\n if (!response.ok) {\n return c.json(\n {\n error: `Failed to fetch OAuth metadata: ${response.status} ${response.statusText}`,\n },\n response.status as ContentfulStatusCode,\n );\n }\n\n const metadata = (await response.json()) as Record<string, unknown>;\n\n // Return the metadata with proper CORS headers\n return c.json(metadata);\n } catch (error) {\n console.error(\"OAuth metadata proxy error:\", error);\n return c.json(\n {\n error:\n error instanceof Error ? error.message : \"Unknown error occurred\",\n },\n 500,\n );\n }\n});\n\nexport default oauth;\n"],"mappings":"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","names":["Hono","Hono","Hono","Hono","tools","toolName","requestId","Hono","Hono","resources","Hono","Hono","prompts","Hono","TextEncoder","pendingElicitations","Hono","tools","TextEncoder","Hono","Hono","Hono"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcpjam/inspector",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "MCPJam Inspector",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -11,15 +11,17 @@
|
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "https://github.com/MCPJam/inspector.git"
|
|
13
13
|
},
|
|
14
|
-
"main": "
|
|
14
|
+
"main": "bin/start.js",
|
|
15
15
|
"bin": {
|
|
16
16
|
"inspector-vite": "bin/start.js"
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
19
|
"bin",
|
|
20
|
-
"dist",
|
|
21
|
-
"
|
|
22
|
-
"package.json"
|
|
20
|
+
"dist/client",
|
|
21
|
+
"dist/server",
|
|
22
|
+
"package.json",
|
|
23
|
+
"README.md",
|
|
24
|
+
"LICENSE"
|
|
23
25
|
],
|
|
24
26
|
"scripts": {
|
|
25
27
|
"dev": "concurrently \"npm run dev:server\" \"npm run dev:client\"",
|
|
@@ -29,7 +31,7 @@
|
|
|
29
31
|
"build:client": "cd client && npm run build",
|
|
30
32
|
"build:server": "cd server && npm run build",
|
|
31
33
|
"start": "NODE_ENV=production node bin/start.js",
|
|
32
|
-
"publish": "
|
|
34
|
+
"publish": "node -e \"console.error('Use npm publish directly.'); process.exit(1)\"",
|
|
33
35
|
"prettier-fix": "prettier --write .",
|
|
34
36
|
"install:deps": "cd server && npm install && cd ../client && npm install",
|
|
35
37
|
"docker:build": "docker build -t mcpjam/mcp-inspector:latest .",
|
|
@@ -51,20 +53,23 @@
|
|
|
51
53
|
},
|
|
52
54
|
"dependencies": {
|
|
53
55
|
"@ai-sdk/anthropic": "^1.2.12",
|
|
56
|
+
"@ai-sdk/deepseek": "^1.0.5",
|
|
54
57
|
"@ai-sdk/openai": "^1.3.23",
|
|
58
|
+
"@ai-sdk/provider": "^2.0.0",
|
|
55
59
|
"@dnd-kit/core": "^6.3.1",
|
|
56
60
|
"@dnd-kit/modifiers": "^9.0.0",
|
|
57
61
|
"@dnd-kit/sortable": "^10.0.0",
|
|
58
62
|
"@dnd-kit/utilities": "^3.2.2",
|
|
59
63
|
"@hono/node-server": "^1.13.7",
|
|
60
64
|
"@hookform/resolvers": "^3.10.0",
|
|
61
|
-
"@mastra/core": "^0.
|
|
62
|
-
"@mastra/mcp": "^0.10.
|
|
63
|
-
"@modelcontextprotocol/sdk": "^1.17.
|
|
65
|
+
"@mastra/core": "^0.13.2",
|
|
66
|
+
"@mastra/mcp": "^0.10.11",
|
|
67
|
+
"@modelcontextprotocol/sdk": "^1.17.3",
|
|
64
68
|
"@tanstack/react-query": "^5.83.0",
|
|
65
69
|
"@tanstack/react-table": "^8.21.3",
|
|
66
70
|
"@uiw/react-json-view": "^2.0.0-alpha.33",
|
|
67
|
-
"ai": "^
|
|
71
|
+
"ai": "^5.0.11",
|
|
72
|
+
"ajv": "^8.17.1",
|
|
68
73
|
"class-variance-authority": "^0.7.1",
|
|
69
74
|
"classnames": "^2.5.1",
|
|
70
75
|
"clsx": "^2.1.1",
|