@agentdevjs/mcp 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts","../src/connection-manager.ts","../src/gateway-client.ts","../src/mcp-adapter.ts","../src/client.ts","../src/config.ts","../src/mount.ts","../src/render.ts","../src/feature/index.ts"],"sourcesContent":["/**\n * MCP 集成类型定义\n *\n * 契约类型(服务器配置形状)的权威定义在 @agentdevjs/core(core/mcp-contract),\n * 此处 re-export 保持旧导入路径兼容;连接管理与调用的运行时类型定义在本包。\n */\n\n// 契约类型:权威定义在 @agentdevjs/core\nexport type {\n MCPTransportType,\n MCPServerConfig,\n MCPSstdioConfig,\n MCPHTTPConfig,\n MCPSSEConfig,\n MCPConfig,\n MCPToolMappingConfig,\n} from '@agentdevjs/core';\n\n/**\n * MCP 连接状态\n */\nexport const enum MCPConnectionState {\n /** 未连接 */\n Disconnected = 'disconnected',\n /** 连接中 */\n Connecting = 'connecting',\n /** 已连接 */\n Connected = 'connected',\n /** 连接错误 */\n Error = 'error',\n}\n\n/**\n * MCP 连接信息\n */\nexport interface MCPConnectionInfo {\n /** 服务器名称 */\n name: string;\n /** 连接状态 */\n state: MCPConnectionState;\n /** 连接时间 */\n connectedAt?: number;\n /** 最后错误 */\n lastError?: string;\n /** 工具数量 */\n toolCount: number;\n}\n\n/**\n * MCP 工具调用结果\n */\nexport interface MCPToolResult {\n /** 是否成功 */\n success: boolean;\n /** 结果内容 */\n content?: string;\n /** 结构化数据 (如果可用) */\n structuredContent?: any;\n /** 错误信息 */\n error?: string;\n /** MCP 服务器名称 */\n server: string;\n /** 调用耗时 (毫秒) */\n duration: number;\n /** 图像数据 (如果有) */\n images?: Array<{\n data: string;\n mimeType: string;\n }>;\n /** 资源数据 (如果有) */\n resources?: Array<{\n uri: string;\n mimeType: string;\n text?: string;\n }>;\n}\n\n/**\n * MCP 统计信息\n */\nexport interface MCPStatistics {\n /** 总调用次数 */\n totalCalls: number;\n /** 成功调用次数 */\n successfulCalls: number;\n /** 失败调用次数 */\n failedCalls: number;\n /** 平均耗时 (毫秒) */\n averageDuration: number;\n /** 按服务器统计 */\n byServer: Record<string, {\n totalCalls: number;\n successfulCalls: number;\n failedCalls: number;\n averageDuration: number;\n }>;\n}\n\n/**\n * MCP 客户端配置\n */\nexport interface MCPClientConfig {\n /** 配置文件路径 */\n configPath?: string;\n /** 是否自动重连 */\n autoReconnect?: boolean;\n /** 重连间隔 (毫秒) */\n reconnectInterval?: number;\n /** 最大重连次数 */\n maxReconnectAttempts?: number;\n /** 日志级别 */\n logLevel?: 'silent' | 'error' | 'warn' | 'info' | 'debug';\n}\n","import { spawn, type ChildProcess } from 'child_process';\nimport {\n Client,\n SSEClientTransport,\n StreamableHTTPClientTransport,\n} from '@modelcontextprotocol/client';\nimport { StdioClientTransport } from '@modelcontextprotocol/client/stdio';\nimport type {\n MCPServerConfig,\n MCPSstdioConfig,\n MCPHTTPConfig,\n MCPSSEConfig,\n MCPConnectionInfo,\n} from './types.js';\nimport { MCPConnectionState } from './types.js';\nimport { createLogger } from '@agentdevjs/core';\n\n/**\n * MCP 连接详情\n */\ninterface MCPConnection {\n name: string;\n config: MCPServerConfig;\n server?: Client | any;\n process?: ChildProcess;\n transport?: any;\n state: MCPConnectionState;\n connectedAt?: number;\n lastError?: string;\n reconnectAttempts: number;\n responseBuffer: string;\n nextRequestId: number;\n toolCount: number;\n allowReconnect: boolean;\n pendingRequests: Map<number, {\n resolve: (value: any) => void;\n reject: (error: Error) => void;\n timeout: NodeJS.Timeout;\n }>;\n}\n\nexport class MCPConnectionManager {\n private connections = new Map<string, MCPConnection>();\n private reconnectTimers = new Map<string, NodeJS.Timeout>();\n private readonly logger = createLogger('mcp.connection');\n\n /**\n * 连接到 MCP 服务器\n */\n async connectServer(\n name: string,\n config: MCPServerConfig\n ): Promise<Client | any> {\n // 如果已存在连接,先尝试复用\n const existing = this.connections.get(name);\n if (existing?.server && existing.state === MCPConnectionState.Connected) {\n return existing.server;\n }\n\n // 创建新连接\n const connection: MCPConnection = {\n name,\n config,\n state: MCPConnectionState.Connecting,\n reconnectAttempts: 0,\n responseBuffer: '',\n nextRequestId: 1,\n toolCount: 0,\n allowReconnect: true,\n pendingRequests: new Map(),\n };\n this.connections.set(name, connection);\n\n try {\n if (config.transport === 'stdio') {\n return await this.connectStdio(name, config as MCPSstdioConfig, connection);\n } else if (config.transport === 'sse') {\n return await this.connectSSE(name, config as MCPSSEConfig, connection);\n } else {\n return await this.connectHTTP(name, config as MCPHTTPConfig, connection);\n }\n } catch (error) {\n connection.state = MCPConnectionState.Error;\n connection.lastError = error instanceof Error ? error.message : String(error);\n throw error;\n }\n }\n\n /**\n * 连接到 stdio MCP 服务器\n */\n private async connectStdio(\n name: string,\n config: MCPSstdioConfig,\n connection: MCPConnection\n ): Promise<Client> {\n const client = new Client({\n name: `agentdev-${name}`,\n version: '0.1.0',\n });\n const transport = new StdioClientTransport({\n command: config.command,\n args: config.args,\n env: config.env,\n cwd: config.cwd,\n stderr: 'pipe',\n });\n\n await client.connect(transport);\n\n client.onerror = (error) => {\n connection.state = MCPConnectionState.Error;\n connection.lastError = error.message;\n this.log('error', `MCP server ${name} client error: ${error.message}`);\n };\n transport.onclose = () => {\n this.log(\n connection.allowReconnect ? 'warn' : 'info',\n `MCP server ${name} stdio transport closed`\n );\n connection.state = MCPConnectionState.Disconnected;\n this.rejectAllPendingRequests(connection, new Error(`MCP server ${name} disconnected`));\n if (connection.allowReconnect) {\n this.scheduleReconnect(name);\n }\n };\n\n // StdioClientTransport manages the child process internally;\n // transport.close() handles cleanup, so no need to track the process.\n connection.transport = transport;\n connection.server = client;\n connection.state = MCPConnectionState.Connected;\n connection.connectedAt = Date.now();\n connection.lastError = undefined;\n connection.reconnectAttempts = 0;\n\n this.log('info', `Connected to MCP server ${name} (stdio)`);\n return client;\n }\n\n /**\n * 连接到 HTTP MCP 服务器\n */\n private async connectSSE(\n name: string,\n config: MCPSSEConfig,\n connection: MCPConnection\n ): Promise<Client> {\n const client = new Client({\n name: `agentdev-${name}`,\n version: '0.1.0',\n });\n const transport = config.headers\n ? new SSEClientTransport(new URL(config.url), {\n eventSourceInit: { headers: config.headers } as any,\n requestInit: { headers: config.headers },\n })\n : new SSEClientTransport(new URL(config.url));\n\n await client.connect(transport);\n\n client.onerror = (error) => {\n connection.state = MCPConnectionState.Error;\n connection.lastError = error.message;\n this.log('error', `MCP server ${name} client error: ${error.message}`);\n };\n transport.onerror = (error) => {\n connection.state = MCPConnectionState.Error;\n connection.lastError = error.message;\n this.log('error', `MCP server ${name} SSE transport error: ${error.message}`);\n };\n transport.onclose = () => {\n this.log(\n connection.allowReconnect ? 'warn' : 'info',\n `MCP server ${name} SSE transport closed`\n );\n connection.state = MCPConnectionState.Disconnected;\n this.rejectAllPendingRequests(connection, new Error(`MCP server ${name} disconnected`));\n if (connection.allowReconnect) {\n this.scheduleReconnect(name);\n }\n };\n\n connection.transport = transport;\n connection.server = client;\n connection.state = MCPConnectionState.Connected;\n connection.connectedAt = Date.now();\n connection.lastError = undefined;\n connection.reconnectAttempts = 0;\n\n this.log('info', `Connected to MCP server ${name} (sse)`);\n return client;\n }\n\n /**\n * 连接到 HTTP MCP 服务器\n */\n private async connectHTTP(\n name: string,\n config: MCPHTTPConfig,\n connection: MCPConnection\n ): Promise<Client> {\n const client = new Client({\n name: `agentdev-${name}`,\n version: '0.1.0',\n });\n const transport = new StreamableHTTPClientTransport(new URL(config.url), {\n ...(config.headers ? { requestInit: { headers: config.headers } } : {}),\n reconnectionOptions: {\n maxRetries: config.retryCount ?? 3,\n initialReconnectionDelay: 1000,\n maxReconnectionDelay: 30000,\n reconnectionDelayGrowFactor: 1.5,\n },\n });\n\n await client.connect(transport);\n\n client.onerror = (error) => {\n connection.state = MCPConnectionState.Error;\n connection.lastError = error.message;\n this.log('error', `MCP server ${name} client error: ${error.message}`);\n };\n transport.onerror = (error) => {\n connection.state = MCPConnectionState.Error;\n connection.lastError = error.message;\n this.log('error', `MCP server ${name} HTTP transport error: ${error.message}`);\n };\n transport.onclose = () => {\n this.log(\n connection.allowReconnect ? 'warn' : 'info',\n `MCP server ${name} HTTP transport closed`\n );\n connection.state = MCPConnectionState.Disconnected;\n this.rejectAllPendingRequests(connection, new Error(`MCP server ${name} disconnected`));\n if (connection.allowReconnect) {\n this.scheduleReconnect(name);\n }\n };\n\n connection.transport = transport;\n connection.server = client;\n connection.state = MCPConnectionState.Connected;\n connection.connectedAt = Date.now();\n connection.lastError = undefined;\n connection.reconnectAttempts = 0;\n\n this.log('info', `Connected to MCP server ${name} (http)`);\n return client;\n }\n\n /**\n * 断开服务器连接\n */\n async disconnectServer(name: string): Promise<void> {\n const connection = this.connections.get(name);\n if (!connection) return;\n connection.allowReconnect = false;\n\n const timer = this.reconnectTimers.get(name);\n if (timer) {\n clearTimeout(timer);\n this.reconnectTimers.delete(name);\n }\n\n if (connection.transport?.close) {\n try {\n await connection.transport.close();\n } catch (error) {\n this.log('warn', `Error closing MCP transport ${name}: ${error}`);\n }\n }\n\n if (connection.process) {\n await this.stopProcess(connection.process);\n }\n\n this.rejectAllPendingRequests(connection, new Error(`MCP server ${name} disconnected`));\n this.connections.delete(name);\n this.log('info', `Disconnected MCP server ${name}`);\n }\n\n /**\n * 断开所有连接\n */\n async disconnectAll(): Promise<void> {\n const names = Array.from(this.connections.keys());\n await Promise.all(names.map(name => this.disconnectServer(name)));\n }\n\n /**\n * 列出服务器的所有工具\n */\n async listTools(name: string): Promise<Array<{\n name: string;\n description?: string;\n inputSchema?: any;\n }>> {\n const connection = this.connections.get(name);\n if (!connection || connection.state !== MCPConnectionState.Connected) {\n this.log('warn', `[MCP] Cannot list tools: ${name} not connected`);\n return [];\n }\n\n try {\n const isDirectProcess = connection.process && connection.server &&\n !(connection.server as any).request;\n\n if (isDirectProcess) {\n this.log('info', `[MCP] Using direct process communication for ${name}`);\n const response = await this.sendDirectRequest(connection, 'tools/list', {}, 300000);\n const tools = response.result?.tools || [];\n connection.toolCount = tools.length;\n this.log('info', `[MCP] Received ${tools.length} tools`);\n return tools;\n }\n\n const response = await (connection.server as Client).listTools(\n undefined,\n { timeout: 300000 }\n );\n const tools = response.tools || [];\n connection.toolCount = tools.length;\n return tools;\n } catch (error) {\n this.log('error', `[MCP] Failed to list tools from ${name}: ${error}`);\n return [];\n }\n }\n\n async callTool(\n name: string,\n serverName: string,\n args: Record<string, unknown>\n ): Promise<{\n content: any[];\n isError?: boolean;\n }> {\n this.log('info', `[MCP] callTool: ${serverName}:${name}`);\n this.log('debug', `[MCP] args: ${JSON.stringify(args)}`);\n\n const connection = this.connections.get(serverName);\n if (!connection || connection.state !== MCPConnectionState.Connected) {\n throw new Error(`MCP server ${serverName} not connected`);\n }\n\n try {\n const isDirectProcess = connection.process && connection.server &&\n !(connection.server as any).request;\n\n if (isDirectProcess) {\n this.log('info', `[MCP] Using direct process communication for tool call`);\n const response = await this.sendDirectRequest(connection, 'tools/call', {\n name,\n arguments: args,\n }, 300000);\n const result = this.normalizeToolCallResponse(response);\n this.log('info', `[MCP] Tool ${name} returned: ${result.isError ? 'ERROR' : 'OK'}`);\n return result;\n }\n\n const response = await (connection.server as Client).callTool(\n { name, arguments: args },\n { timeout: 300000 }\n );\n return this.normalizeToolCallResponse(response);\n } catch (error) {\n this.log('error', `[MCP] Failed to call tool ${name}: ${error}`);\n return {\n content: [{\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n }],\n isError: true,\n };\n }\n }\n\n getConnectionInfo(name: string): MCPConnectionInfo | undefined {\n const connection = this.connections.get(name);\n if (!connection) return undefined;\n\n return {\n name: connection.name,\n state: connection.state,\n connectedAt: connection.connectedAt,\n lastError: connection.lastError,\n toolCount: connection.toolCount,\n };\n }\n\n /**\n * 获取所有连接信息\n */\n getAllConnections(): MCPConnectionInfo[] {\n return Array.from(this.connections.keys())\n .map(name => this.getConnectionInfo(name))\n .filter((info): info is MCPConnectionInfo => info !== undefined);\n }\n\n /**\n * 检查连接状态\n */\n isConnected(name: string): boolean {\n const connection = this.connections.get(name);\n return connection?.state === MCPConnectionState.Connected;\n }\n\n /**\n * 获取服务器实例\n */\n getServer(name: string): Client | any | undefined {\n return this.connections.get(name)?.server;\n }\n\n /**\n * 安排重连\n */\n private scheduleReconnect(name: string): void {\n const existingTimer = this.reconnectTimers.get(name);\n if (existingTimer) {\n clearTimeout(existingTimer);\n }\n\n const timer = setTimeout(async () => {\n const connection = this.connections.get(name);\n if (!connection) return;\n\n if (connection.reconnectAttempts >= 3) {\n this.log('error', `Max reconnect attempts reached for MCP server ${name}`);\n return;\n }\n\n connection.reconnectAttempts++;\n this.log('info', `Reconnecting to MCP server ${name} (attempt ${connection.reconnectAttempts})`);\n\n try {\n await this.connectServer(name, connection.config);\n } catch (error) {\n this.log('error', `Failed to reconnect to MCP server ${name}: ${error}`);\n }\n }, 5000);\n\n this.reconnectTimers.set(name, timer);\n }\n\n /**\n * 日志输出\n */\n private log(level: 'error' | 'warn' | 'info' | 'debug', message: string): void {\n this.logger.child({\n tags: ['mcp-connection'],\n })[level](message);\n }\n\n private handleProcessOutput(connection: MCPConnection, chunk: string): void {\n connection.responseBuffer += chunk;\n const lines = connection.responseBuffer.split(/\\r?\\n/);\n connection.responseBuffer = lines.pop() ?? '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n try {\n const response = JSON.parse(trimmed);\n this.handleDirectResponse(connection, response);\n } catch {\n connection.responseBuffer = `${trimmed}\\n${connection.responseBuffer}`;\n return;\n }\n }\n }\n\n private handleDirectResponse(connection: MCPConnection, response: any): void {\n if (typeof response?.id !== 'number') {\n this.log('debug', `[MCP] Ignoring non-response message from ${connection.name}: ${JSON.stringify(response)}`);\n return;\n }\n\n const pending = connection.pendingRequests.get(response.id);\n if (!pending) {\n this.log('debug', `[MCP] No pending request for response id ${response.id} from ${connection.name}`);\n return;\n }\n\n clearTimeout(pending.timeout);\n connection.pendingRequests.delete(response.id);\n pending.resolve(response);\n }\n\n private async sendDirectRequest(\n connection: MCPConnection,\n method: string,\n params: Record<string, unknown>,\n timeoutMs: number\n ): Promise<any> {\n if (!connection.process?.stdin) {\n throw new Error(`MCP server ${connection.name} has no stdin`);\n }\n\n const requestId = connection.nextRequestId++;\n const request = {\n jsonrpc: '2.0',\n id: requestId,\n method,\n params,\n };\n\n this.log('debug', `[MCP] Sending direct request: ${JSON.stringify(request)}`);\n\n return await new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n connection.pendingRequests.delete(requestId);\n reject(new Error(`Timeout waiting for ${method} from ${connection.name}`));\n }, timeoutMs);\n\n connection.pendingRequests.set(requestId, { resolve, reject, timeout });\n\n try {\n connection.process!.stdin!.write(JSON.stringify(request) + '\\n');\n } catch (error) {\n clearTimeout(timeout);\n connection.pendingRequests.delete(requestId);\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n });\n }\n\n private normalizeToolCallResponse(response: any): { content: any[]; isError?: boolean } {\n if (response.error) {\n return {\n content: [{\n type: 'text',\n text: `Error: ${response.error.message || 'Unknown error'}`,\n }],\n isError: true,\n };\n }\n\n if (response.result) {\n return response.result;\n }\n\n if (response.content || response.structuredContent || response.toolResult) {\n return response;\n }\n\n return { content: [] };\n }\n\n private rejectAllPendingRequests(connection: MCPConnection, error: Error): void {\n for (const [requestId, pending] of connection.pendingRequests) {\n clearTimeout(pending.timeout);\n pending.reject(error);\n connection.pendingRequests.delete(requestId);\n }\n }\n\n private async stopProcess(process: ChildProcess): Promise<void> {\n try {\n process.stdin?.end();\n } catch {\n // best effort shutdown\n }\n\n try {\n process.stdout?.destroy();\n } catch {\n // best effort shutdown\n }\n\n if (process.exitCode !== null || process.signalCode !== null) {\n return;\n }\n\n await new Promise<void>((resolve) => {\n const timeout = setTimeout(resolve, 1500);\n process.once('exit', () => {\n clearTimeout(timeout);\n resolve();\n });\n\n try {\n process.kill();\n } catch {\n clearTimeout(timeout);\n resolve();\n }\n });\n }\n\n async dispose(): Promise<void> {\n await this.disconnectAll();\n\n for (const timer of this.reconnectTimers.values()) {\n clearTimeout(timer);\n }\n this.reconnectTimers.clear();\n }\n}\n","/**\n * Gateway discovery client — discovers Claw-hosted MCP servers\n * and converts them into standard MCPConfig entries for transparent mounting.\n *\n * When an agent runs under Claw, PROTOCLAW_SERVER_ORIGIN is set in the env.\n * This module fetches the gateway discovery endpoint, filters to connected\n * servers, and returns MCPConfig entries pointing to the gateway proxy URLs.\n */\n\nimport type { MCPServerConfig } from './types.js';\n\nexport interface GatewayServerInfo {\n id: string;\n transport: string;\n status: string;\n toolCount: number;\n url: string;\n}\n\nexport interface GatewayDiscoveryResult {\n origin: string;\n servers: GatewayServerInfo[];\n}\n\n/**\n * Discover available gateway servers from Claw's MCP Gateway.\n * Returns empty servers array if gateway is unavailable.\n * Never throws — failures are silently swallowed.\n */\nexport async function discoverGatewayServers(\n origin?: string,\n timeoutMs = 3000\n): Promise<GatewayDiscoveryResult> {\n const gatewayOrigin = origin || process.env.PROTOCLAW_SERVER_ORIGIN;\n if (!gatewayOrigin) {\n return { origin: '', servers: [] };\n }\n\n try {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n const res = await fetch(`${gatewayOrigin}/protoclaw/mcp-gateway/servers`, {\n signal: controller.signal,\n });\n clearTimeout(timer);\n if (!res.ok) {\n return { origin: gatewayOrigin, servers: [] };\n }\n const data = await res.json();\n const servers = (Array.isArray(data.servers) ? data.servers : []) as GatewayServerInfo[];\n // Only return servers that have tools (connected and discovered)\n return {\n origin: gatewayOrigin,\n servers: servers.filter(s => s.toolCount > 0),\n };\n } catch {\n // Gateway not available — silently skip\n return { origin: gatewayOrigin || '', servers: [] };\n }\n}\n\n/**\n * Convert discovered gateway servers into MCPConfig server entries.\n * Each gateway server becomes an HTTP transport pointing to the gateway proxy URL.\n */\nexport function gatewayServersToConfig(\n discovery: GatewayDiscoveryResult,\n excludeServers?: string[]\n): Record<string, MCPServerConfig> {\n const servers: Record<string, MCPServerConfig> = {};\n for (const server of discovery.servers) {\n if (excludeServers?.includes(server.id)) {\n continue;\n }\n servers[server.id] = {\n transport: 'http',\n url: server.url,\n };\n }\n return servers;\n}\n","/**\n * MCP Tool Adapter - 适配器模式实现\n *\n * 将 MCP 工具适配为现有 Tool 接口,保持架构一致性\n */\n\nimport type { Tool, ToolExecutionContext, ToolResultValue } from '@agentdevjs/core';\n\n/**\n * 注册工具的简化接口\n * 用于适配器包装\n */\ninterface RegisteredToolLike {\n name: string;\n description?: string;\n inputSchema?: any;\n outputSchema?: any;\n annotations?: any;\n handler?: (args: any, context?: any) => Promise<any> | any;\n enabled?: boolean;\n}\n\n/**\n * MCP 工具适配器配置\n */\nexport interface MCPToolAdapterConfig {\n /** MCP 服务器名称 */\n serverName: string;\n /** 是否为只读工具 */\n readOnly?: boolean;\n /** 渲染模板覆盖 */\n render?: { call?: string; result?: string };\n}\n\n/**\n * MCP 工具适配器\n *\n * 将 MCP RegisteredTool 适配为 Agent 的 Tool 接口\n * 负责格式转换和生命周期管理\n */\nexport class MCPToolAdapter implements Tool {\n readonly name: string;\n readonly description: string;\n readonly parameters?: Record<string, unknown>;\n readonly render?: { call?: string; result?: string };\n\n constructor(\n private registeredTool: RegisteredToolLike,\n private config: MCPToolAdapterConfig\n ) {\n this.name = registeredTool.name;\n this.description = registeredTool.description || `MCP tool: ${registeredTool.name}`;\n this.parameters = this.extractParameters(registeredTool);\n this.render = {\n call: config.render?.call || 'mcp-tool',\n result: config.render?.result || 'mcp-result',\n };\n }\n\n /**\n * 执行 MCP 工具\n */\n async execute(args: Record<string, unknown>, context?: ToolExecutionContext): Promise<ToolResultValue> {\n const startTime = Date.now();\n\n try {\n const handler = this.registeredTool.handler;\n const result = await handler?.(args, context);\n\n const duration = Date.now() - startTime;\n\n // 转换结果格式\n return this.formatResult(result, duration);\n } catch (error) {\n // 错误处理\n return this.formatError(error, Date.now() - startTime);\n }\n }\n\n /**\n * 格式化 MCP 工具结果\n */\n private formatResult(result: any, duration: number): Record<string, unknown> {\n // 处理错误结果\n if (result && result.isError) {\n return {\n success: false,\n error: (result.content || []).map((c: any) => c.text || '').join('\\n'),\n server: this.config.serverName,\n duration,\n };\n }\n\n // 提取文本内容\n const textContent = result.content\n .filter((c: any) => c.type === 'text')\n .map((c: any) => c.text || '')\n .join('\\n');\n\n // 返回格式化结果\n const formatted: Record<string, unknown> = {\n content: textContent,\n server: this.config.serverName,\n duration,\n };\n\n // 如果有结构化内容,附加到结果\n if ((result as any).structuredContent) {\n formatted.structuredContent = (result as any).structuredContent;\n }\n\n // 处理图像内容\n const images = result.content.filter((c: any) => c.type === 'image');\n if (images.length > 0) {\n formatted.images = images.map((c: any) => ({\n data: c.data,\n mimeType: c.mimeType,\n }));\n }\n\n // 处理资源内容\n const resources = result.content.filter((c: any) => c.type === 'resource');\n if (resources.length > 0) {\n formatted.resources = resources.map((c: any) => ({\n uri: c.uri,\n mimeType: c.mimeType,\n text: c.text,\n }));\n }\n\n return formatted;\n }\n\n /**\n * 格式化错误\n */\n private formatError(error: unknown, duration: number): Record<string, unknown> {\n const errorMessage = error instanceof Error\n ? error.message\n : String(error);\n\n return {\n success: false,\n error: `[MCP Error] ${errorMessage}`,\n server: this.config.serverName,\n duration,\n };\n }\n\n /**\n * 从 RegisteredToolLike 提取参数定义\n *\n * MCP 工具的 inputSchema 已经是 JSON Schema 格式\n * 直接返回,不需要转换\n */\n private extractParameters(tool: RegisteredToolLike): Record<string, any> | undefined {\n // 如果没有 inputSchema,返回 undefined\n if (!tool.inputSchema) return undefined;\n\n // MCP 服务器返回的 inputSchema 已经是 JSON Schema 格式\n // 例如:{ type: 'object', properties: { owner: { type: 'string', description: '...' } } }\n // 直接返回,框架会使用它来生成工具描述给 LLM\n try {\n // 验证它是有效的 JSON Schema 对象\n const schema = tool.inputSchema;\n if (typeof schema === 'object' && schema.type === 'object') {\n return schema as Record<string, any>;\n }\n\n // 如果格式不符合预期,返回 undefined 让框架使用默认处理\n console.warn(`[MCPToolAdapter] Unexpected inputSchema format for ${tool.name}:`, typeof schema);\n return undefined;\n } catch (error) {\n console.warn(`[MCPToolAdapter] Failed to extract parameters for ${tool.name}:`, error);\n return undefined;\n }\n }\n}\n\n/**\n * 批量创建 MCP 工具适配器\n */\nexport function createMCPToolAdapters(\n registeredTools: RegisteredToolLike[],\n serverName: string,\n config?: Omit<MCPToolAdapterConfig, 'serverName'>\n): Tool[] {\n return registeredTools.map(tool =>\n new MCPToolAdapter(tool, {\n serverName,\n ...config,\n })\n );\n}\n","import type { Tool } from '@agentdevjs/core';\nimport { MCPConnectionManager } from './connection-manager.js';\nimport { MCPToolAdapter, type MCPToolAdapterConfig } from './mcp-adapter.js';\nimport type { MCPServerConfig } from './types.js';\n\nexport interface MCPDiscoveredTool {\n name: string;\n description?: string;\n inputSchema?: any;\n}\n\nexport interface MCPToolCreationOptions {\n name?: string;\n description?: string;\n render?: MCPToolAdapterConfig['render'];\n transformArgs?: (args: Record<string, unknown>, context?: any) => Record<string, unknown>;\n}\n\nexport interface MCPToolDiscoveryOptions {\n filter?: (tool: MCPDiscoveredTool) => boolean;\n mapName?: (tool: MCPDiscoveredTool) => string;\n render?: MCPToolAdapterConfig['render'];\n transformArgs?: MCPToolCreationOptions['transformArgs'];\n}\n\nexport interface MCPDiscoveredToolSet {\n client: MCPClient;\n tools: Tool[];\n}\n\nexport function createDefaultMCPToolName(serverId: string, toolName: string): string {\n return `mcp_${serverId}_${toolName}`.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\nexport class MCPClient {\n private readonly manager: MCPConnectionManager;\n private connected = false;\n\n constructor(\n readonly serverId: string,\n private readonly config: MCPServerConfig,\n manager?: MCPConnectionManager\n ) {\n this.manager = manager ?? new MCPConnectionManager();\n }\n\n async connect(): Promise<void> {\n if (this.connected && this.manager.isConnected(this.serverId)) {\n return;\n }\n await this.manager.connectServer(this.serverId, this.config);\n this.connected = true;\n }\n\n async listTools(): Promise<MCPDiscoveredTool[]> {\n await this.connect();\n return await this.manager.listTools(this.serverId);\n }\n\n async callTool(name: string, args: Record<string, unknown>): Promise<any> {\n await this.connect();\n return await this.manager.callTool(name, this.serverId, args);\n }\n\n getConnectionManager(): MCPConnectionManager {\n return this.manager;\n }\n\n async dispose(): Promise<void> {\n this.connected = false;\n await this.manager.disconnectServer(this.serverId);\n }\n}\n\nexport function createMCPTool(\n client: MCPClient,\n tool: MCPDiscoveredTool,\n options: MCPToolCreationOptions = {}\n): Tool {\n return new MCPToolAdapter(\n {\n name: options.name ?? createDefaultMCPToolName(client.serverId, tool.name),\n description: options.description ?? (tool.description || `MCP tool: ${tool.name}`),\n inputSchema: tool.inputSchema,\n enabled: true,\n handler: async (args: Record<string, unknown>, context?: any) => {\n const finalArgs = options.transformArgs ? options.transformArgs(args, context) : args;\n return await client.callTool(tool.name, finalArgs);\n },\n },\n {\n serverName: client.serverId,\n render: options.render,\n }\n );\n}\n\nexport async function createMCPToolsFromClient(\n client: MCPClient,\n options: MCPToolDiscoveryOptions = {}\n): Promise<Tool[]> {\n const tools = await client.listTools();\n\n return tools\n .filter(tool => options.filter ? options.filter(tool) : true)\n .map(tool => createMCPTool(client, tool, {\n name: options.mapName?.(tool),\n description: tool.description,\n render: options.render,\n transformArgs: options.transformArgs,\n }));\n}\n\nexport async function discoverMCPTools(\n serverId: string,\n config: MCPServerConfig,\n options: MCPToolDiscoveryOptions = {},\n manager?: MCPConnectionManager\n): Promise<MCPDiscoveredToolSet> {\n const client = new MCPClient(serverId, config, manager);\n const tools = await createMCPToolsFromClient(client, options);\n return { client, tools };\n}\n","import { existsSync, readFileSync, readdirSync } from 'fs';\nimport { basename } from 'path';\nimport { cwd } from 'process';\nimport { isAbsolute, join, resolve } from 'path';\nimport type { MCPConfig, MCPServerConfig } from './types.js';\n\nexport interface LoadAllMCPConfigsOptions {\n loadDefaultDir?: boolean;\n extraConfigFiles?: string[];\n excludeServers?: string[];\n}\n\nfunction readConfigFile(configPath: string): unknown {\n try {\n if (!existsSync(configPath)) {\n return undefined;\n }\n\n const content = readFileSync(configPath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.warn(`[MCP] Failed to load config \"${configPath}\": ${errorMsg}`);\n return undefined;\n }\n}\n\n/**\n * 归一化单个 server 配置:将 MCP 标准字段 `type` 映射到 `transport`。\n * Claude Desktop / Cursor 等客户端使用 `type`,框架内部统一用 `transport`。\n */\nfunction normalizeServerConfig(server: Record<string, unknown>): Record<string, unknown> {\n if (!server.transport && typeof server.type === 'string') {\n return { ...server, transport: server.type };\n }\n return server;\n}\n\nfunction isMCPServerConfig(value: unknown): value is MCPServerConfig {\n if (!value || typeof value !== 'object') {\n return false;\n }\n\n const config = normalizeServerConfig(value as Record<string, unknown>);\n if (config.transport === 'stdio') {\n return typeof config.command === 'string' && Array.isArray(config.args);\n }\n\n if (config.transport === 'http') {\n return typeof config.url === 'string';\n }\n\n if (config.transport === 'sse') {\n return typeof config.url === 'string';\n }\n\n return false;\n}\n\nfunction isMCPConfig(value: unknown): value is MCPConfig {\n if (!value || typeof value !== 'object') {\n return false;\n }\n\n const config = value as Record<string, unknown>;\n return (\n (!!config.servers && typeof config.servers === 'object') ||\n (!!config.mcpServers && typeof config.mcpServers === 'object')\n );\n}\n\nfunction normalizeToMCPConfig(\n value: unknown,\n fallbackServerId: string\n): MCPConfig | undefined {\n if (isMCPConfig(value)) {\n const config = value as unknown as Record<string, unknown>;\n const rawServers = (config.servers ?? config.mcpServers) as Record<string, unknown> | undefined;\n if (!rawServers) {\n return undefined;\n }\n\n const servers: Record<string, MCPServerConfig> = {};\n for (const [id, server] of Object.entries(rawServers)) {\n if (server && typeof server === 'object') {\n servers[id] = normalizeServerConfig(server as Record<string, unknown>) as unknown as MCPServerConfig;\n }\n }\n\n return { servers };\n }\n\n if (isMCPServerConfig(value)) {\n return {\n servers: {\n [fallbackServerId]: value,\n },\n };\n }\n\n return undefined;\n}\n\nfunction resolveMCPConfigInput(\n input: string,\n rootDir: string = cwd()\n): { configPath: string; fallbackServerId: string } {\n let configPath: string;\n let fallbackServerId: string;\n\n if (isAbsolute(input)) {\n configPath = input;\n fallbackServerId = basename(configPath, '.json');\n } else if (input.includes('/') || input.includes('\\\\')) {\n configPath = resolve(rootDir, input);\n fallbackServerId = basename(configPath, '.json');\n } else {\n configPath = join(getDefaultMCPConfigDir(rootDir), `${input}.json`);\n fallbackServerId = input;\n }\n\n return { configPath, fallbackServerId };\n}\n\nfunction loadMCPConfigFile(configPath: string, fallbackServerId: string): MCPConfig | undefined {\n const config = readConfigFile(configPath);\n if (!config) {\n return undefined;\n }\n\n const normalized = normalizeToMCPConfig(config, fallbackServerId);\n if (!normalized || Object.keys(normalized.servers).length === 0) {\n console.warn(`[MCP] Ignoring invalid config file: ${configPath}`);\n return undefined;\n }\n\n return normalized;\n}\n\nfunction getDedupedServerId(serverId: string, existingServerIds: Set<string>): string {\n if (!existingServerIds.has(serverId)) {\n return serverId;\n }\n\n let suffix = 1;\n let nextServerId = `${serverId} (${suffix})`;\n while (existingServerIds.has(nextServerId)) {\n suffix += 1;\n nextServerId = `${serverId} (${suffix})`;\n }\n\n return nextServerId;\n}\n\nfunction mergeMCPConfig(\n merged: MCPConfig,\n config: MCPConfig,\n excludedServers: Set<string>\n): void {\n const existingServerIds = new Set(Object.keys(merged.servers));\n\n for (const [serverId, serverConfig] of Object.entries(config.servers)) {\n if (excludedServers.has(serverId)) {\n continue;\n }\n\n const dedupedServerId = getDedupedServerId(serverId, existingServerIds);\n merged.servers[dedupedServerId] = serverConfig;\n existingServerIds.add(dedupedServerId);\n }\n}\n\nexport function getDefaultMCPConfigDir(rootDir: string = cwd()): string {\n return join(rootDir, '.agentdev', 'mcps');\n}\n\nexport function loadMCPConfigFromInput(input: string, rootDir: string = cwd()): MCPConfig | undefined {\n const { configPath, fallbackServerId } = resolveMCPConfigInput(input, rootDir);\n\n if (!existsSync(configPath)) {\n console.warn(`[MCP] Config file does not exist: ${configPath}`);\n return undefined;\n }\n\n return loadMCPConfigFile(configPath, fallbackServerId);\n}\n\nexport function loadAllMCPConfigs(\n rootDir: string = cwd(),\n options: LoadAllMCPConfigsOptions = {}\n): MCPConfig | undefined {\n const shouldLoadDefaultDir = options.loadDefaultDir ?? true;\n const extraConfigFiles = Array.isArray(options.extraConfigFiles)\n ? options.extraConfigFiles.filter(Boolean)\n : [];\n const excludedServers = new Set(options.excludeServers ?? []);\n const merged: MCPConfig = { servers: {} };\n if (shouldLoadDefaultDir) {\n const configDir = getDefaultMCPConfigDir(rootDir);\n if (existsSync(configDir)) {\n const entries = readdirSync(configDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.json')) {\n continue;\n }\n\n const configPath = join(configDir, entry.name);\n const config = loadMCPConfigFile(configPath, basename(entry.name, '.json'));\n if (!config) {\n continue;\n }\n\n mergeMCPConfig(merged, config, excludedServers);\n }\n }\n }\n\n for (const configFile of extraConfigFiles) {\n const config = loadMCPConfigFromInput(configFile, rootDir);\n if (!config) {\n continue;\n }\n\n mergeMCPConfig(merged, config, excludedServers);\n }\n\n return Object.keys(merged.servers).length > 0 ? merged : undefined;\n}\n","import type { Tool } from '@agentdevjs/core';\nimport { type MCPConnectionManager } from './connection-manager.js';\nimport {\n MCPClient,\n createMCPTool,\n createDefaultMCPToolName,\n type MCPDiscoveredTool,\n type MCPToolCreationOptions,\n} from './client.js';\nimport type { MCPToolAdapterConfig } from './mcp-adapter.js';\nimport type { MCPConfig, MCPServerConfig } from './types.js';\n\nexport interface MCPToolPatch {\n enabled?: boolean;\n name?: string;\n description?: string;\n render?: MCPToolAdapterConfig['render'];\n transformArgs?: MCPToolCreationOptions['transformArgs'];\n}\n\nexport interface MCPToolManagementOptions {\n include?: string[];\n exclude?: string[];\n disable?: string[];\n rename?: Record<string, string>;\n describe?: Record<string, string>;\n render?: MCPToolAdapterConfig['render'];\n toolRender?: Record<string, MCPToolAdapterConfig['render']>;\n mapName?: (tool: MCPDiscoveredTool, client: MCPClient) => string;\n transformArgs?: MCPToolCreationOptions['transformArgs'];\n transform?: (tool: MCPDiscoveredTool, client: MCPClient) => MCPToolPatch | false | null | undefined;\n}\n\nexport interface MCPConfigMountOptions {\n manager?: MCPConnectionManager;\n clients?: Map<string, MCPClient>;\n getServerOptions?: (\n serverId: string,\n serverConfig: MCPServerConfig\n ) => MCPToolManagementOptions | undefined;\n onError?: (serverId: string, error: unknown) => void;\n}\n\nexport interface MCPMountedToolSet {\n client: MCPClient;\n tools: Tool[];\n}\n\nexport interface MCPMountedConfigResult {\n tools: Tool[];\n clients: Map<string, MCPClient>;\n}\n\nfunction applyStaticPatch(\n tool: MCPDiscoveredTool,\n client: MCPClient,\n options: MCPToolManagementOptions\n): MCPToolPatch {\n return {\n enabled: !options.disable?.includes(tool.name),\n name: options.rename?.[tool.name] ?? options.mapName?.(tool, client),\n description: options.describe?.[tool.name],\n render: options.toolRender?.[tool.name] ?? options.render,\n transformArgs: options.transformArgs,\n };\n}\n\nfunction shouldIncludeTool(tool: MCPDiscoveredTool, options: MCPToolManagementOptions): boolean {\n if (options.include && !options.include.includes(tool.name)) {\n return false;\n }\n if (options.exclude?.includes(tool.name)) {\n return false;\n }\n return true;\n}\n\nfunction mergeToolPatch(base: MCPToolPatch, override?: MCPToolPatch | false | null): MCPToolPatch | false {\n if (override === false) {\n return false;\n }\n if (!override) {\n return base;\n }\n return {\n ...base,\n ...override,\n render: override.render ?? base.render,\n transformArgs: override.transformArgs ?? base.transformArgs,\n };\n}\n\nexport async function createManagedMCPToolsFromClient(\n client: MCPClient,\n options: MCPToolManagementOptions = {}\n): Promise<Tool[]> {\n const tools = await client.listTools();\n\n return tools.flatMap(tool => {\n if (!shouldIncludeTool(tool, options)) {\n return [];\n }\n\n const staticPatch = applyStaticPatch(tool, client, options);\n const finalPatch = mergeToolPatch(staticPatch, options.transform?.(tool, client));\n if (finalPatch === false || finalPatch.enabled === false) {\n return [];\n }\n\n return createMCPTool(\n client,\n {\n ...tool,\n description: finalPatch.description ?? tool.description,\n },\n {\n name: finalPatch.name ?? createDefaultMCPToolName(client.serverId, tool.name),\n description: finalPatch.description,\n render: finalPatch.render,\n transformArgs: finalPatch.transformArgs,\n }\n );\n });\n}\n\nexport async function discoverManagedMCPTools(\n serverId: string,\n config: MCPServerConfig,\n options: MCPToolManagementOptions = {},\n manager?: MCPConnectionManager\n): Promise<MCPMountedToolSet> {\n const client = new MCPClient(serverId, config, manager);\n const tools = await createManagedMCPToolsFromClient(client, options);\n return { client, tools };\n}\n\nexport async function mountMCPToolsFromConfig(\n config: MCPConfig,\n options: MCPConfigMountOptions = {}\n): Promise<MCPMountedConfigResult> {\n const clients = options.clients ?? new Map<string, MCPClient>();\n const tools: Tool[] = [];\n\n for (const [serverId, serverConfig] of Object.entries(config.servers)) {\n try {\n const client = clients.get(serverId) ?? new MCPClient(serverId, serverConfig, options.manager);\n clients.set(serverId, client);\n\n const serverOptions = options.getServerOptions?.(serverId, serverConfig) ?? {};\n tools.push(...await createManagedMCPToolsFromClient(client, serverOptions));\n } catch (error) {\n options.onError?.(serverId, error);\n }\n }\n\n return { tools, clients };\n}\n","/**\n * MCP 工具渲染模板\n *\n * 定义 MCP 工具在 DebugHub 中的显示样式\n */\n\n/**\n * 转义 HTML\n */\nfunction escapeHtml(text: any): string {\n const str = String(text);\n const map: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#39;',\n };\n return str.replace(/[&<>\"']/g, m => map[m]);\n}\n\n/**\n * MCP 工具渲染模板\n */\nexport const MCP_RENDER_TEMPLATES = {\n /**\n * MCP 工具调用显示\n */\n 'mcp-tool': {\n call: (args: any) => {\n const server = args._server || 'unknown';\n const name = args._name || 'unknown';\n return `\n <div class=\"bash-command\" style=\"\n border-left: 3px solid #ff6b6b;\n padding-left: 8px;\n margin: 4px 0;\n \">\n <span style=\"\n color: #ff6b6b;\n font-weight: bold;\n font-size: 11px;\n text-transform: uppercase;\n \">MCP</span>\n <span class=\"file-path\" style=\"color: #c068ff;\">${escapeHtml(server)}</span>\n <span style=\"color: #888;\">::</span>\n <span style=\"color: #fff;\">${escapeHtml(name)}</span>\n </div>\n `.trim();\n },\n result: (data: any, success = true) => {\n if (!success || data.error) {\n return `\n <div class=\"bash-output\" style=\"\n border-left: 3px solid #ff4444;\n padding-left: 8px;\n color: #ff6b6b;\n \">\n <div style=\"font-weight: bold; margin-bottom: 4px;\">MCP Error</div>\n <pre style=\"margin: 0; white-space: pre-wrap;\">${escapeHtml(data.error || 'Unknown error')}</pre>\n </div>\n `.trim();\n }\n\n let content = '';\n\n // 文本内容\n if (data.content) {\n content += `<pre class=\"bash-output\" style=\"max-height: 400px; overflow: auto;\">${escapeHtml(data.content)}</pre>`;\n }\n\n // 结构化数据\n if (data.structuredContent) {\n content += `<details style=\"margin-top: 8px;\">\n <summary style=\"cursor: pointer; color: var(--accent-color);\">Structured Data</summary>\n <pre style=\"margin: 4px 0; padding: 8px; background: var(--bg-secondary);\">${escapeHtml(JSON.stringify(data.structuredContent, null, 2))}</pre>\n </details>`;\n }\n\n // 图像\n if (data.images && data.images.length > 0) {\n content += `<div style=\"margin-top: 8px;\">`;\n data.images.forEach((img: any) => {\n content += `<img src=\"data:${img.mimeType};base64,${img.data}\" style=\"max-width: 100%; border-radius: 4px;\" />`;\n });\n content += `</div>`;\n }\n\n // 资源\n if (data.resources && data.resources.length > 0) {\n content += `<div style=\"margin-top: 8px;\">\n <div style=\"font-weight: bold; margin-bottom: 4px;\">Resources:</div>`;\n data.resources.forEach((res: any) => {\n content += `<div style=\"padding: 4px; background: var(--bg-secondary); margin: 4px 0;\">\n <div style=\"font-size: 11px; color: var(--text-secondary);\">${escapeHtml(res.uri)}</div>\n ${res.text ? `<pre style=\"margin: 4px 0 0 0;\">${escapeHtml(res.text)}</pre>` : ''}\n </div>`;\n });\n content += `</div>`;\n }\n\n // 元数据\n const meta = `\n <div style=\"\n font-size: 11px;\n opacity: 0.6;\n margin-top: 8px;\n display: flex;\n gap: 12px;\n \">\n <span>Server: ${escapeHtml(data.server)}</span>\n <span>Duration: ${data.duration}ms</span>\n </div>\n `;\n\n return content + meta;\n },\n },\n\n /**\n * MCP 结果 (简化版)\n */\n 'mcp-result': {\n call: () => '<div class=\"bash-command\">MCP Tool Call</div>',\n result: (data: any, success = true) => {\n return MCP_RENDER_TEMPLATES['mcp-tool'].result(data, success);\n },\n },\n} as const;\n\n/**\n * 获取 MCP 渲染模板\n */\nexport function getMCPRenderTemplate(toolName: string): string {\n return 'mcp-tool';\n}\n\n/**\n * 渲染 MCP 工具调用\n */\nexport function renderMCPToolCall(\n serverName: string,\n toolName: string,\n args: Record<string, any>\n): string {\n const template = MCP_RENDER_TEMPLATES['mcp-tool'].call;\n if (typeof template === 'function') {\n return template({ _server: serverName, _name: toolName, ...args });\n }\n return template;\n}\n\n/**\n * 渲染 MCP 工具结果\n */\nexport function renderMCPToolResult(\n result: any,\n success = true\n): string {\n const template = MCP_RENDER_TEMPLATES['mcp-tool'].result;\n if (typeof template === 'function') {\n return template(result, success);\n }\n return template;\n}\n","/**\n * MCP Feature - MCP 服务器连接和工具注册\n *\n * 将 MCP 集成从 Agent 核心中解耦,实现可外挂功能\n *\n * @example\n * ```typescript\n * // 自动扫描 .agentdev/mcps/*.json\n * agent.use(new MCPFeature());\n *\n * // 从配置文件加载(默认路径 .agentdev/mcps)\n * agent.use(new MCPFeature('github'));\n *\n * // 从指定路径加载配置\n * agent.use(new MCPFeature('./path/to/mcps/github'));\n *\n * // 直接传入配置对象\n * agent.use(new MCPFeature({ servers: { ... } }));\n * ```\n */\n\nimport { fileURLToPath } from 'url';\nimport type {\n AgentFeature,\n FeatureInitContext,\n FeatureManifestDefinition,\n ContextInjector,\n ToolContextValue,\n PackageInfo,\n} from '@agentdevjs/core';\nimport { getPackageInfoFromSource } from '@agentdevjs/core';\nimport type { Tool } from '@agentdevjs/core';\nimport { loadAllMCPConfigs, loadMCPConfigFromInput } from '../config.js';\nimport { MCPConnectionManager } from '../connection-manager.js';\nimport { mountMCPToolsFromConfig } from '../mount.js';\nimport { discoverGatewayServers, gatewayServersToConfig } from '../gateway-client.js';\nimport type { MCPClient } from '../client.js';\nimport type { MCPConfig, MCPServerConfig } from '../types.js';\n\n// ESM 中获取 __dirname\nconst __filename = fileURLToPath(import.meta.url);\n\n/**\n * MCP Feature 配置类型\n */\nexport type MCPFeatureInput = MCPConfig | string;\n\nexport interface MCPFeatureOptions {\n excludeServers?: string[];\n}\n\nexport interface MCPFeatureConfig {\n /** 是否加载工作目录 .agentdev/mcps 下的系统 MCP 配置,默认 true */\n scanAgentdevDir?: boolean;\n /** 额外加载的 MCP 配置文件列表 */\n extraConfigFiles?: string[];\n /** 是否自动连接 Claw 托管的共享 MCP 网关服务器,默认 true */\n enableGateway?: boolean;\n}\n\n/**\n * MCP Feature 实现\n */\nexport class MCPFeature implements AgentFeature {\n readonly name = 'mcp';\n readonly source = __filename.replace(/\\\\/g, '/');\n readonly description = '连接 MCP 服务器并把发现到的远程能力挂载成标准工具。';\n\n private readonly manager = new MCPConnectionManager();\n private clients = new Map<string, MCPClient>();\n private readonly input?: MCPFeatureInput;\n private readonly options: MCPFeatureOptions;\n private config?: MCPConfig;\n private mcpContext?: Record<string, unknown>;\n\n /**\n * 缓存包信息\n */\n private _packageInfo: PackageInfo | null = null;\n\n /**\n * 获取包信息(统一打包方案)\n */\n getPackageInfo(): PackageInfo | null {\n if (!this._packageInfo) {\n this._packageInfo = getPackageInfoFromSource(this.source);\n }\n return this._packageInfo;\n }\n\n /**\n * 获取模板名称列表(统一打包方案)\n */\n getTemplateNames(): string[] {\n return ['mcp-tool'];\n }\n\n constructor(input?: MCPFeatureInput, options: MCPFeatureOptions = {}) {\n this.input = input;\n this.options = options;\n\n // Only store direct config objects; string inputs are resolved lazily in\n // resolveRuntimeConfig where workspaceDir is available for path resolution.\n if (input && typeof input !== 'string') {\n this.config = input;\n }\n }\n\n getFeatureManifest(): FeatureManifestDefinition {\n return {\n schemaVersion: 1 as const,\n settings: {\n properties: {\n scanAgentdevDir: {\n type: 'boolean',\n title: '加载 .agentdev/mcps',\n description: '是否从工作目录的 .agentdev/mcps/ 加载系统 MCP 配置文件。',\n default: true,\n },\n extraConfigFiles: {\n type: 'file',\n title: '额外 MCP 配置文件',\n description: '额外加载多个 MCP 配置文件(至多 5 个),重名 server/tool 会自动加后缀区分。',\n default: [],\n accept: '.json',\n maxItems: 5,\n },\n enableGateway: {\n type: 'boolean',\n title: '启用 Claw MCP 网关',\n description: '自动连接 Claw 主进程托管的共享 MCP 服务器。启用后,所有会话共享同一份 MCP server 连接,无需各自启动。',\n default: true,\n },\n },\n },\n };\n }\n\n private resolveFeatureConfig(featureConfig: unknown): MCPFeatureConfig {\n if (!featureConfig || typeof featureConfig !== 'object') {\n return {\n scanAgentdevDir: true,\n extraConfigFiles: [],\n enableGateway: true,\n };\n }\n\n const config = featureConfig as Record<string, unknown>;\n return {\n scanAgentdevDir: config.scanAgentdevDir === undefined ? true : config.scanAgentdevDir !== false,\n extraConfigFiles: Array.isArray(config.extraConfigFiles)\n ? config.extraConfigFiles.filter((value): value is string => typeof value === 'string' && value.length > 0)\n : [],\n enableGateway: config.enableGateway === undefined ? true : config.enableGateway !== false,\n };\n }\n\n private resolveRuntimeConfig(ctx: FeatureInitContext): MCPConfig | undefined {\n // Direct config objects set in constructor — no path resolution needed.\n if (this.config) {\n return this.config;\n }\n\n const rootDir = ctx.config?.workspaceDir;\n\n if (typeof this.input === 'string') {\n this.config = loadMCPConfigFromInput(this.input, rootDir);\n return this.config;\n }\n\n const featureConfig = this.resolveFeatureConfig(ctx.featureConfig);\n this.config = loadAllMCPConfigs(rootDir, {\n loadDefaultDir: featureConfig.scanAgentdevDir,\n extraConfigFiles: featureConfig.extraConfigFiles,\n excludeServers: this.options.excludeServers,\n });\n\n return this.config;\n }\n\n /**\n * 获取同步工具(无)\n */\n getTools(): Tool[] {\n return [];\n }\n\n /**\n * 获取异步工具(需要连接 MCP 服务器)\n */\n async getAsyncTools(ctx: FeatureInitContext): Promise<Tool[]> {\n const config = this.resolveRuntimeConfig(ctx);\n const featureConfig = this.resolveFeatureConfig(ctx.featureConfig);\n\n // Discover Claw-hosted gateway servers (if enabled).\n // An explicit input (config path or config object) pins the server set and\n // excludes gateway discovery — merging would break that explicit contract.\n let gatewayServers: Record<string, MCPServerConfig> = {};\n if (featureConfig.enableGateway && !this.input) {\n const discovery = await discoverGatewayServers();\n if (discovery.servers.length > 0) {\n gatewayServers = gatewayServersToConfig(discovery, this.options.excludeServers);\n }\n }\n\n // Merge traditional configs with gateway-discovered servers\n const hasServers = (config?.servers && Object.keys(config.servers).length > 0) || Object.keys(gatewayServers).length > 0;\n if (!hasServers) {\n return [];\n }\n\n const mergedConfig: MCPConfig = {\n enabled: true,\n servers: {\n ...(config?.servers || {}),\n ...gatewayServers,\n },\n };\n\n const result = await mountMCPToolsFromConfig(mergedConfig, {\n manager: this.manager,\n clients: this.clients,\n onError: (serverId, error) => {\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.warn(`[MCPFeature] Failed to load tools from \"${serverId}\": ${errorMsg}`);\n },\n });\n\n return result.tools;\n }\n\n /**\n * 声明上下文注入器\n * 为所有 MCP 工具注入 _mcpContext\n */\n getContextInjectors(): Map<string | RegExp, ContextInjector> {\n return new Map<string | RegExp, ContextInjector>([\n [/^mcp_/, (): ToolContextValue => ({ _mcpContext: this.mcpContext })],\n ]);\n }\n\n /**\n * 清理钩子\n */\n async onDestroy(): Promise<void> {\n for (const client of this.clients.values()) {\n await client.dispose();\n }\n this.clients.clear();\n await this.manager.dispose();\n }\n\n /**\n * 设置 MCP 上下文(运行时注入)\n */\n setMCPContext(context: Record<string, unknown>): void {\n this.mcpContext = context;\n }\n\n /**\n * 获取连接管理器(供外部使用)\n */\n getConnectionManager(): MCPConnectionManager | undefined {\n return this.manager;\n }\n}\n"],"mappings":"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","names":["MCPConnectionState","response","tools","resolve","process"]}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@agentdevjs/mcp",
3
+ "version": "0.1.0",
4
+ "description": "AgentDev MCP integration: connection manager, tool mount/adapter, MCPFeature",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "dev": "tsup --watch",
21
+ "test": "vitest run",
22
+ "test:watch": "vitest",
23
+ "typecheck": "tsc --noEmit",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "dependencies": {
27
+ "@agentdevjs/core": "^0.1.0",
28
+ "@modelcontextprotocol/client": "^2.0.0"
29
+ },
30
+ "devDependencies": {
31
+ "@types/node": "^20.11.0",
32
+ "tsup": "^8.3.5",
33
+ "tsx": "^4.7.0",
34
+ "typescript": "^5.3.3",
35
+ "vitest": "^4.1.10"
36
+ },
37
+ "engines": {
38
+ "node": ">=18.0.0"
39
+ },
40
+ "keywords": [
41
+ "agentdev",
42
+ "mcp",
43
+ "model-context-protocol"
44
+ ],
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "git+https://github.com/your-org/agentdev.git"
48
+ },
49
+ "license": "MIT"
50
+ }