|
@@ -8,6 +8,7 @@
|
|
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
|
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
|
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
|
|
|
+import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
|
import { spawn, ChildProcess } from 'child_process';
|
|
import { spawn, ChildProcess } from 'child_process';
|
|
|
import { MCPServerConfig } from './types.js';
|
|
import { MCPServerConfig } from './types.js';
|
|
|
|
|
|
|
@@ -55,8 +56,10 @@ export class ToolDiscovery {
|
|
|
|
|
|
|
|
if (serverConfig.type === 'stdio') {
|
|
if (serverConfig.type === 'stdio') {
|
|
|
tools = await this.discoverStdioServerTools(serverName, serverConfig);
|
|
tools = await this.discoverStdioServerTools(serverName, serverConfig);
|
|
|
- } else if (serverConfig.type === 'http' || serverConfig.type === 'sse') {
|
|
|
|
|
- tools = await this.discoverHttpServerTools(serverName, serverConfig);
|
|
|
|
|
|
|
+ } else if (serverConfig.type === 'http') {
|
|
|
|
|
+ tools = await this.discoverStreamableHttpServerTools(serverName, serverConfig);
|
|
|
|
|
+ } else if (serverConfig.type === 'sse') {
|
|
|
|
|
+ tools = await this.discoverSseServerTools(serverName, serverConfig);
|
|
|
} else {
|
|
} else {
|
|
|
console.warn(`Warning: MCP server '${serverName}' uses unsupported type '${serverConfig.type}'. Skipping.`);
|
|
console.warn(`Warning: MCP server '${serverName}' uses unsupported type '${serverConfig.type}'. Skipping.`);
|
|
|
continue;
|
|
continue;
|
|
@@ -174,9 +177,71 @@ export class ToolDiscovery {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * Discover tools from a single HTTP/SSE-based MCP server
|
|
|
|
|
|
|
+ * Discover tools from a single Streamable HTTP-based MCP server
|
|
|
*/
|
|
*/
|
|
|
- private static async discoverHttpServerTools(
|
|
|
|
|
|
|
+ private static async discoverStreamableHttpServerTools(
|
|
|
|
|
+ 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 Streamable HTTP transport with optional headers
|
|
|
|
|
+ const transport = new StreamableHTTPClientTransport(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;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Discover tools from a single SSE-based MCP server
|
|
|
|
|
+ */
|
|
|
|
|
+ private static async discoverSseServerTools(
|
|
|
serverName: string,
|
|
serverName: string,
|
|
|
serverConfig: { url?: string; headers?: Record<string, string> }
|
|
serverConfig: { url?: string; headers?: Record<string, string> }
|
|
|
): Promise<string[]> {
|
|
): Promise<string[]> {
|