Jelajahi Sumber

feat: add HTTP/SSE tool discovery support for MCP servers

- Added SSEClientTransport support to tool discovery
- Implemented discoverHttpServerTools method for HTTP/SSE-based MCP servers
- Renamed discoverServerTools to discoverStdioServerTools for clarity
- Added headers field to MCPServerConfig type for HTTP authentication
- Both stdio and HTTP/SSE MCP servers now support tool discovery

This fixes the issue where HTTP-based MCP servers (like Supabase) were
being skipped during tool discovery with a warning message. Now they are
properly discovered and their tools are available to Claude.

Also fixed the gogs-mcp path configuration by updating MCP config files to
use ${GOGS_MCP_PATH} environment variable substitution instead of hardcoded
paths.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Claude 9 bulan lalu
induk
melakukan
0d2e84488a
2 mengubah file dengan 76 tambahan dan 8 penghapusan
  1. 75 8
      client/src/toolDiscovery.ts
  2. 1 0
      client/src/types.ts

+ 75 - 8
client/src/toolDiscovery.ts

@@ -7,6 +7,7 @@
 
 import { Client } from '@modelcontextprotocol/sdk/client/index.js';
 import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
+import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
 import { spawn, ChildProcess } from 'child_process';
 import { MCPServerConfig } from './types.js';
 
@@ -49,13 +50,17 @@ export class ToolDiscovery {
     for (const serverName of serverNames) {
       const serverConfig = mcpConfig.mcpServers[serverName];
 
-      if (serverConfig.type !== 'stdio') {
-        console.warn(`Warning: MCP server '${serverName}' uses type '${serverConfig.type}' - only 'stdio' type is supported for tool discovery. Skipping.`);
-        continue;
-      }
-
       try {
-        const tools = await this.discoverServerTools(serverName, serverConfig);
+        let tools: string[];
+
+        if (serverConfig.type === 'stdio') {
+          tools = await this.discoverStdioServerTools(serverName, serverConfig);
+        } else if (serverConfig.type === 'http' || serverConfig.type === 'sse') {
+          tools = await this.discoverHttpServerTools(serverName, serverConfig);
+        } else {
+          console.warn(`Warning: MCP server '${serverName}' uses unsupported type '${serverConfig.type}'. Skipping.`);
+          continue;
+        }
 
         console.log(`  - ${serverName}: discovered ${tools.length} tool(s)`);
 
@@ -73,9 +78,9 @@ export class ToolDiscovery {
   }
 
   /**
-   * Discover tools from a single MCP server
+   * Discover tools from a single stdio-based MCP server
    */
-  private static async discoverServerTools(
+  private static async discoverStdioServerTools(
     serverName: string,
     serverConfig: { command?: string; args?: string[]; env?: Record<string, string> }
   ): Promise<string[]> {
@@ -167,4 +172,66 @@ export class ToolDiscovery {
       throw error;
     }
   }
+
+  /**
+   * Discover tools from a single HTTP/SSE-based MCP server
+   */
+  private static async discoverHttpServerTools(
+    serverName: string,
+    serverConfig: { url?: string; headers?: Record<string, string> }
+  ): Promise<string[]> {
+    if (!serverConfig.url) {
+      throw new Error(`MCP server '${serverName}' is missing 'url' field`);
+    }
+
+    let client: Client | null = null;
+
+    try {
+      // Parse the URL
+      const url = new URL(serverConfig.url);
+
+      // Create SSE transport with optional headers
+      const transport = new SSEClientTransport(url, {
+        requestInit: serverConfig.headers ? {
+          headers: serverConfig.headers
+        } : undefined
+      });
+
+      // Create MCP client
+      client = new Client({
+        name: `tool-discovery-${serverName}`,
+        version: '1.0.0'
+      }, {
+        capabilities: {}
+      });
+
+      // Connect to the server
+      await client.connect(transport);
+
+      // List available tools
+      const toolsResponse = await client.listTools();
+
+      // Format tool names with mcp__ prefix
+      const tools = toolsResponse.tools.map(tool =>
+        `mcp__${serverName}__${tool.name}`
+      );
+
+      // Close the connection
+      await client.close();
+
+      return tools;
+
+    } catch (error) {
+      // Ensure cleanup
+      if (client) {
+        try {
+          await client.close();
+        } catch (closeError) {
+          // Ignore close errors
+        }
+      }
+
+      throw error;
+    }
+  }
 }

+ 1 - 0
client/src/types.ts

@@ -38,6 +38,7 @@ export interface MCPServerConfig {
       args?: string[];
       env?: Record<string, string>;
       url?: string;
+      headers?: Record<string, string>;
     };
   };
 }