MCP SSE support (#511)
Matches the config format used by other MCP clients.
This commit is contained in:
parent
8590efd229
commit
635666dec9
|
@ -24,10 +24,14 @@ import { WebSearchTool } from '../tools/web-search.js';
|
||||||
|
|
||||||
export class MCPServerConfig {
|
export class MCPServerConfig {
|
||||||
constructor(
|
constructor(
|
||||||
readonly command: string,
|
// For stdio transport
|
||||||
|
readonly command?: string,
|
||||||
readonly args?: string[],
|
readonly args?: string[],
|
||||||
readonly env?: Record<string, string>,
|
readonly env?: Record<string, string>,
|
||||||
readonly cwd?: string,
|
readonly cwd?: string,
|
||||||
|
// For sse transport
|
||||||
|
readonly url?: string,
|
||||||
|
// Common
|
||||||
readonly timeout?: number,
|
readonly timeout?: number,
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { spawn, execSync } from 'node:child_process';
|
||||||
// TODO: remove this dependency once MCP support is built into genai SDK
|
// TODO: remove this dependency once MCP support is built into genai SDK
|
||||||
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';
|
||||||
type ToolParams = Record<string, unknown>;
|
type ToolParams = Record<string, unknown>;
|
||||||
|
|
||||||
const MCP_TOOL_DEFAULT_TIMEOUT_MSEC = 10 * 60 * 1000; // default to 10 minutes
|
const MCP_TOOL_DEFAULT_TIMEOUT_MSEC = 10 * 60 * 1000; // default to 10 minutes
|
||||||
|
@ -206,14 +207,28 @@ export class ToolRegistry {
|
||||||
name: 'mcp-client',
|
name: 'mcp-client',
|
||||||
version: '0.0.1',
|
version: '0.0.1',
|
||||||
});
|
});
|
||||||
const transport = new StdioClientTransport({
|
let transport;
|
||||||
...mcpServerConfig,
|
if (mcpServerConfig.url) {
|
||||||
env: {
|
// SSE transport if URL is provided
|
||||||
...process.env,
|
transport = new SSEClientTransport(new URL(mcpServerConfig.url));
|
||||||
...(mcpServerConfig.env || {}),
|
} else if (mcpServerConfig.command) {
|
||||||
} as Record<string, string>,
|
// Stdio transport if command is provided
|
||||||
stderr: 'pipe',
|
transport = new StdioClientTransport({
|
||||||
});
|
command: mcpServerConfig.command,
|
||||||
|
args: mcpServerConfig.args || [],
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
...(mcpServerConfig.env || {}),
|
||||||
|
} as Record<string, string>,
|
||||||
|
cwd: mcpServerConfig.cwd,
|
||||||
|
stderr: 'pipe',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
`MCP server '${mcpServerName}' has invalid configuration: missing both url (for SSE) and command (for stdio). Skipping.`,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
await mcpClient.connect(transport);
|
await mcpClient.connect(transport);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -227,15 +242,17 @@ export class ToolRegistry {
|
||||||
mcpClient.onerror = (error) => {
|
mcpClient.onerror = (error) => {
|
||||||
console.error('MCP ERROR', error.toString());
|
console.error('MCP ERROR', error.toString());
|
||||||
};
|
};
|
||||||
if (!transport.stderr) {
|
if (transport instanceof StdioClientTransport && !transport.stderr) {
|
||||||
throw new Error('transport missing stderr stream');
|
throw new Error('transport missing stderr stream');
|
||||||
}
|
}
|
||||||
transport.stderr.on('data', (data) => {
|
if (transport instanceof StdioClientTransport) {
|
||||||
// filter out INFO messages logged for each request received
|
transport.stderr!.on('data', (data) => {
|
||||||
if (!data.toString().includes('] INFO')) {
|
// filter out INFO messages logged for each request received
|
||||||
console.debug('MCP STDERR', data.toString());
|
if (!data.toString().includes('] INFO')) {
|
||||||
}
|
console.debug('MCP STDERR', data.toString());
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
const result = await mcpClient.listTools();
|
const result = await mcpClient.listTools();
|
||||||
for (const tool of result.tools) {
|
for (const tool of result.tools) {
|
||||||
// Recursively remove additionalProperties and $schema from the inputSchema
|
// Recursively remove additionalProperties and $schema from the inputSchema
|
||||||
|
|
Loading…
Reference in New Issue