opensentinel 2.1.1

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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +283 -0
  3. package/dist/bot-KJ26BG56.js +15 -0
  4. package/dist/bot-KJ26BG56.js.map +1 -0
  5. package/dist/charts-MMXM6BWW.js +241 -0
  6. package/dist/charts-MMXM6BWW.js.map +1 -0
  7. package/dist/chunk-4LVWXUNC.js +1079 -0
  8. package/dist/chunk-4LVWXUNC.js.map +1 -0
  9. package/dist/chunk-4TG2IG5K.js +5249 -0
  10. package/dist/chunk-4TG2IG5K.js.map +1 -0
  11. package/dist/chunk-6DRDKB45.js +251 -0
  12. package/dist/chunk-6DRDKB45.js.map +1 -0
  13. package/dist/chunk-6SNHU3CY.js +123 -0
  14. package/dist/chunk-6SNHU3CY.js.map +1 -0
  15. package/dist/chunk-CI6Q63MM.js +1613 -0
  16. package/dist/chunk-CI6Q63MM.js.map +1 -0
  17. package/dist/chunk-CQ4JURG7.js +57 -0
  18. package/dist/chunk-CQ4JURG7.js.map +1 -0
  19. package/dist/chunk-F6QUZQGI.js +51 -0
  20. package/dist/chunk-F6QUZQGI.js.map +1 -0
  21. package/dist/chunk-GK3E2I7A.js +216 -0
  22. package/dist/chunk-GK3E2I7A.js.map +1 -0
  23. package/dist/chunk-GUBEEYDW.js +211 -0
  24. package/dist/chunk-GUBEEYDW.js.map +1 -0
  25. package/dist/chunk-GVJVEWHI.js +29 -0
  26. package/dist/chunk-GVJVEWHI.js.map +1 -0
  27. package/dist/chunk-HH2HBTQM.js +806 -0
  28. package/dist/chunk-HH2HBTQM.js.map +1 -0
  29. package/dist/chunk-JXUP2X7V.js +129 -0
  30. package/dist/chunk-JXUP2X7V.js.map +1 -0
  31. package/dist/chunk-KHNYJY2Z.js +178 -0
  32. package/dist/chunk-KHNYJY2Z.js.map +1 -0
  33. package/dist/chunk-L3F43VPB.js +652 -0
  34. package/dist/chunk-L3F43VPB.js.map +1 -0
  35. package/dist/chunk-L3PDU3XN.js +803 -0
  36. package/dist/chunk-L3PDU3XN.js.map +1 -0
  37. package/dist/chunk-NSBPE2FW.js +17 -0
  38. package/dist/chunk-NSBPE2FW.js.map +1 -0
  39. package/dist/cli.d.ts +1 -0
  40. package/dist/cli.js +52 -0
  41. package/dist/cli.js.map +1 -0
  42. package/dist/commands/setup.d.ts +9 -0
  43. package/dist/commands/setup.js +374 -0
  44. package/dist/commands/setup.js.map +1 -0
  45. package/dist/commands/start.d.ts +8 -0
  46. package/dist/commands/start.js +27 -0
  47. package/dist/commands/start.js.map +1 -0
  48. package/dist/commands/status.d.ts +8 -0
  49. package/dist/commands/status.js +57 -0
  50. package/dist/commands/status.js.map +1 -0
  51. package/dist/commands/stop.d.ts +8 -0
  52. package/dist/commands/stop.js +37 -0
  53. package/dist/commands/stop.js.map +1 -0
  54. package/dist/commands/utils.d.ts +50 -0
  55. package/dist/commands/utils.js +36 -0
  56. package/dist/commands/utils.js.map +1 -0
  57. package/dist/discord-ZOJFTVTB.js +49 -0
  58. package/dist/discord-ZOJFTVTB.js.map +1 -0
  59. package/dist/imessage-JFRB6EJ7.js +14 -0
  60. package/dist/imessage-JFRB6EJ7.js.map +1 -0
  61. package/dist/lib.d.ts +855 -0
  62. package/dist/lib.js +274 -0
  63. package/dist/lib.js.map +1 -0
  64. package/dist/mcp-LS7Q3Z5W.js +30 -0
  65. package/dist/mcp-LS7Q3Z5W.js.map +1 -0
  66. package/dist/scheduler-EZ7CZMCS.js +42 -0
  67. package/dist/scheduler-EZ7CZMCS.js.map +1 -0
  68. package/dist/signal-T3MCSULM.js +14 -0
  69. package/dist/signal-T3MCSULM.js.map +1 -0
  70. package/dist/slack-N2M4FHAJ.js +54 -0
  71. package/dist/slack-N2M4FHAJ.js.map +1 -0
  72. package/dist/src-K7GASHRH.js +430 -0
  73. package/dist/src-K7GASHRH.js.map +1 -0
  74. package/dist/tools-24GZHYRF.js +16 -0
  75. package/dist/tools-24GZHYRF.js.map +1 -0
  76. package/dist/whatsapp-VCRUPAO5.js +14 -0
  77. package/dist/whatsapp-VCRUPAO5.js.map +1 -0
  78. package/drizzle/0000_chilly_shinobi_shaw.sql +75 -0
  79. package/drizzle/0001_freezing_shape.sql +274 -0
  80. package/drizzle/meta/0000_snapshot.json +529 -0
  81. package/drizzle/meta/0001_snapshot.json +2576 -0
  82. package/drizzle/meta/_journal.json +20 -0
  83. package/package.json +98 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/mcp/client.ts","../src/core/mcp/registry.ts","../src/core/mcp/tool-bridge.ts"],"sourcesContent":["/**\n * MCP Client - Handles communication with MCP servers\n * Supports STDIO and HTTP+SSE transports\n */\n\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { nanoid } from \"nanoid\";\nimport type {\n MCPServerConfig,\n MCPServerState,\n MCPTool,\n MCPInitializeParams,\n MCPInitializeResult,\n MCPToolListResult,\n MCPToolCallParams,\n MCPToolCallResult,\n MCPToolResult,\n JsonRpcRequest,\n JsonRpcResponse,\n} from \"./types\";\n\nconst MCP_PROTOCOL_VERSION = \"2024-11-05\";\n\nexport class MCPClient {\n private config: MCPServerConfig;\n private state: MCPServerState;\n private process: ChildProcess | null = null;\n private pendingRequests: Map<string | number, {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n timeout: Timer;\n }> = new Map();\n private messageBuffer = \"\";\n private requestTimeout: number;\n\n constructor(config: MCPServerConfig, timeout = 30000) {\n this.config = config;\n this.requestTimeout = timeout;\n this.state = {\n config,\n status: \"disconnected\",\n tools: [],\n };\n }\n\n get id(): string {\n return this.config.id;\n }\n\n get name(): string {\n return this.config.name;\n }\n\n get status(): MCPServerState[\"status\"] {\n return this.state.status;\n }\n\n get tools(): MCPTool[] {\n return this.state.tools;\n }\n\n get serverInfo() {\n return this.state.serverInfo;\n }\n\n // ============================================\n // CONNECTION MANAGEMENT\n // ============================================\n\n async connect(): Promise<void> {\n if (this.state.status === \"connected\") {\n return;\n }\n\n this.state.status = \"connecting\";\n\n try {\n if (this.config.transport === \"stdio\") {\n await this.connectStdio();\n } else if (this.config.transport === \"http+sse\") {\n await this.connectHttpSse();\n } else {\n throw new Error(`Unsupported transport: ${this.config.transport}`);\n }\n\n // Initialize MCP connection\n const initResult = await this.initialize();\n this.state.capabilities = initResult.capabilities;\n this.state.serverInfo = initResult.serverInfo;\n\n // Fetch available tools\n await this.refreshTools();\n\n this.state.status = \"connected\";\n this.state.lastActivity = new Date();\n\n console.log(`[MCP] Connected to ${this.name} (${this.state.tools.length} tools)`);\n } catch (error) {\n this.state.status = \"error\";\n this.state.lastError = error instanceof Error ? error.message : \"Unknown error\";\n throw error;\n }\n }\n\n async disconnect(): Promise<void> {\n if (this.state.status === \"disconnected\") {\n return;\n }\n\n // Cancel pending requests\n for (const [, pending] of this.pendingRequests) {\n clearTimeout(pending.timeout);\n pending.reject(new Error(\"Connection closed\"));\n }\n this.pendingRequests.clear();\n\n // Kill subprocess if STDIO\n if (this.process) {\n this.process.kill();\n this.process = null;\n }\n\n this.state.status = \"disconnected\";\n this.state.tools = [];\n console.log(`[MCP] Disconnected from ${this.name}`);\n }\n\n // ============================================\n // STDIO TRANSPORT\n // ============================================\n\n private async connectStdio(): Promise<void> {\n if (!this.config.command) {\n throw new Error(\"STDIO transport requires a command\");\n }\n\n const env: Record<string, string> = {\n ...process.env as Record<string, string>,\n ...this.config.env,\n };\n\n this.process = spawn(\n this.config.command,\n this.config.args || [],\n {\n cwd: this.config.cwd || process.cwd(),\n env,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }\n );\n\n // Start reading stdout in background\n this.readStdout();\n\n // Start reading stderr in background\n this.readStderr();\n\n // Give the process a moment to start\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n\n private readStdout(): void {\n if (!this.process?.stdout) return;\n\n this.process.stdout.on(\"data\", (chunk: Buffer) => {\n this.messageBuffer += chunk.toString();\n this.processMessageBuffer();\n });\n\n this.process.stdout.on(\"error\", (error) => {\n if (this.state.status === \"connected\" || this.state.status === \"connecting\") {\n console.error(`[MCP] ${this.name} stdout error:`, error);\n }\n });\n }\n\n private readStderr(): void {\n if (!this.process?.stderr) return;\n\n this.process.stderr.on(\"data\", (chunk: Buffer) => {\n const text = chunk.toString();\n if (text.trim()) {\n console.log(`[MCP] ${this.name} stderr: ${text.trim()}`);\n }\n });\n }\n\n private processMessageBuffer(): void {\n // JSON-RPC messages are newline-delimited\n const lines = this.messageBuffer.split(\"\\n\");\n this.messageBuffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.trim()) continue;\n\n try {\n const message = JSON.parse(line) as JsonRpcResponse;\n this.handleResponse(message);\n } catch {\n console.warn(`[MCP] ${this.name} failed to parse message: ${line.slice(0, 100)}`);\n }\n }\n }\n\n private handleResponse(response: JsonRpcResponse): void {\n if (response.id === undefined || response.id === null) {\n // Notification from server, ignore for now\n return;\n }\n\n const pending = this.pendingRequests.get(response.id);\n if (!pending) {\n console.warn(`[MCP] ${this.name} received response for unknown request: ${response.id}`);\n return;\n }\n\n clearTimeout(pending.timeout);\n this.pendingRequests.delete(response.id);\n\n if (response.error) {\n pending.reject(new Error(response.error.message));\n } else {\n pending.resolve(response.result);\n }\n }\n\n private async sendRequest(method: string, params?: unknown): Promise<unknown> {\n if (!this.process?.stdin) {\n throw new Error(\"Not connected\");\n }\n\n const id = nanoid();\n const request: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id,\n method,\n params,\n };\n\n const promise = new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pendingRequests.delete(id);\n reject(new Error(`Request timeout: ${method}`));\n }, this.requestTimeout);\n\n this.pendingRequests.set(id, { resolve, reject, timeout });\n });\n\n // Write request to stdin\n const data = JSON.stringify(request) + \"\\n\";\n this.process.stdin.write(data);\n\n return promise;\n }\n\n // ============================================\n // HTTP+SSE TRANSPORT\n // ============================================\n\n private async connectHttpSse(): Promise<void> {\n if (!this.config.url) {\n throw new Error(\"HTTP+SSE transport requires a URL\");\n }\n\n // For HTTP+SSE, we don't maintain a persistent connection\n // Each request is a separate HTTP call\n // SSE is used for streaming responses (not implemented yet)\n\n // Just verify the server is reachable\n try {\n const response = await fetch(`${this.config.url}/health`, {\n headers: this.config.headers,\n });\n\n if (!response.ok) {\n throw new Error(`Server health check failed: ${response.status}`);\n }\n } catch (error) {\n // Health endpoint might not exist, try main endpoint\n const response = await fetch(this.config.url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.config.headers,\n },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: \"ping\",\n method: \"ping\",\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Server connection failed: ${response.status}`);\n }\n }\n }\n\n private async sendHttpRequest(method: string, params?: unknown): Promise<unknown> {\n if (!this.config.url) {\n throw new Error(\"HTTP+SSE transport requires a URL\");\n }\n\n const request: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id: nanoid(),\n method,\n params,\n };\n\n const response = await fetch(this.config.url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.config.headers,\n },\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP request failed: ${response.status}`);\n }\n\n const result = await response.json() as JsonRpcResponse;\n\n if (result.error) {\n throw new Error(result.error.message);\n }\n\n return result.result;\n }\n\n // ============================================\n // MCP PROTOCOL METHODS\n // ============================================\n\n private async initialize(): Promise<MCPInitializeResult> {\n const params: MCPInitializeParams = {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: {\n roots: { listChanged: true },\n },\n clientInfo: {\n name: \"OpenSentinel\",\n version: \"2.0.0\",\n },\n };\n\n const result = await this.request(\"initialize\", params) as MCPInitializeResult;\n\n // Send initialized notification\n await this.notify(\"notifications/initialized\", {});\n\n return result;\n }\n\n async refreshTools(): Promise<MCPTool[]> {\n const result = await this.request(\"tools/list\", {}) as MCPToolListResult;\n this.state.tools = result.tools || [];\n return this.state.tools;\n }\n\n async callTool(name: string, args?: Record<string, unknown>): Promise<MCPToolResult> {\n const params: MCPToolCallParams = {\n name,\n arguments: args,\n };\n\n try {\n const result = await this.request(\"tools/call\", params) as MCPToolCallResult;\n this.state.lastActivity = new Date();\n\n // Extract text content from result\n const textContent = result.content\n .filter((c) => c.type === \"text\" && c.text)\n .map((c) => c.text)\n .join(\"\\n\");\n\n return {\n success: !result.isError,\n output: textContent || JSON.stringify(result.content),\n isError: result.isError,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n }\n\n // ============================================\n // GENERIC REQUEST/NOTIFY\n // ============================================\n\n private async request(method: string, params?: unknown): Promise<unknown> {\n if (this.config.transport === \"stdio\") {\n return this.sendRequest(method, params);\n } else {\n return this.sendHttpRequest(method, params);\n }\n }\n\n private async notify(method: string, params?: unknown): Promise<void> {\n if (this.config.transport === \"stdio\" && this.process?.stdin) {\n const notification = {\n jsonrpc: \"2.0\",\n method,\n params,\n };\n this.process.stdin.write(JSON.stringify(notification) + \"\\n\");\n }\n // HTTP+SSE notifications are not typically supported\n }\n\n // ============================================\n // STATE ACCESS\n // ============================================\n\n getState(): MCPServerState {\n return { ...this.state };\n }\n}\n","/**\n * MCP Registry - Manages multiple MCP server connections\n * Aggregates tools from all connected servers\n */\n\nimport { MCPClient } from \"./client\";\nimport type {\n MCPConfig,\n MCPServerConfig,\n MCPServerState,\n MCPTool,\n MCPToolResult,\n} from \"./types\";\n\nexport class MCPRegistry {\n private clients: Map<string, MCPClient> = new Map();\n private config: MCPConfig;\n private defaultTimeout: number;\n\n constructor(config: MCPConfig) {\n this.config = config;\n this.defaultTimeout = config.settings?.timeout || 30000;\n }\n\n // ============================================\n // INITIALIZATION\n // ============================================\n\n /**\n * Connect to all enabled MCP servers\n */\n async initialize(): Promise<void> {\n const enabledServers = this.config.servers.filter((s) => s.enabled);\n\n console.log(`[MCP] Initializing ${enabledServers.length} server(s)...`);\n\n const results = await Promise.allSettled(\n enabledServers.map((config) => this.connectServer(config))\n );\n\n // Log any failures\n results.forEach((result, index) => {\n if (result.status === \"rejected\") {\n console.error(\n `[MCP] Failed to connect to ${enabledServers[index].name}:`,\n result.reason\n );\n }\n });\n\n const connected = results.filter((r) => r.status === \"fulfilled\").length;\n console.log(`[MCP] Connected to ${connected}/${enabledServers.length} servers`);\n }\n\n /**\n * Connect to a single MCP server\n */\n async connectServer(config: MCPServerConfig): Promise<void> {\n if (this.clients.has(config.id)) {\n throw new Error(`Server ${config.id} already connected`);\n }\n\n const client = new MCPClient(config, this.defaultTimeout);\n await client.connect();\n this.clients.set(config.id, client);\n }\n\n /**\n * Disconnect from a specific server\n */\n async disconnectServer(id: string): Promise<void> {\n const client = this.clients.get(id);\n if (client) {\n await client.disconnect();\n this.clients.delete(id);\n }\n }\n\n /**\n * Disconnect from all servers\n */\n async shutdown(): Promise<void> {\n console.log(\"[MCP] Shutting down all connections...\");\n await Promise.all(\n Array.from(this.clients.values()).map((client) => client.disconnect())\n );\n this.clients.clear();\n }\n\n // ============================================\n // TOOL MANAGEMENT\n // ============================================\n\n /**\n * Get all tools from all connected servers\n * Tools are prefixed with \"mcp_{serverId}_\" for routing\n */\n getAllTools(): Array<{ serverId: string; tool: MCPTool }> {\n const tools: Array<{ serverId: string; tool: MCPTool }> = [];\n\n for (const [serverId, client] of this.clients) {\n if (client.status === \"connected\") {\n for (const tool of client.tools) {\n tools.push({ serverId, tool });\n }\n }\n }\n\n return tools;\n }\n\n /**\n * Get tools from a specific server\n */\n getServerTools(serverId: string): MCPTool[] {\n const client = this.clients.get(serverId);\n return client?.tools || [];\n }\n\n /**\n * Call a tool on a specific server\n */\n async callTool(\n serverId: string,\n toolName: string,\n args?: Record<string, unknown>\n ): Promise<MCPToolResult> {\n const client = this.clients.get(serverId);\n\n if (!client) {\n return {\n success: false,\n error: `MCP server not found: ${serverId}`,\n };\n }\n\n if (client.status !== \"connected\") {\n return {\n success: false,\n error: `MCP server not connected: ${serverId}`,\n };\n }\n\n console.log(`[MCP] Calling ${serverId}:${toolName}`);\n return client.callTool(toolName, args);\n }\n\n // ============================================\n // SERVER MANAGEMENT\n // ============================================\n\n /**\n * Get status of all servers\n */\n getServerStates(): MCPServerState[] {\n return Array.from(this.clients.values()).map((client) => client.getState());\n }\n\n /**\n * Get status of a specific server\n */\n getServerState(serverId: string): MCPServerState | undefined {\n return this.clients.get(serverId)?.getState();\n }\n\n /**\n * Check if a server is connected\n */\n isConnected(serverId: string): boolean {\n const client = this.clients.get(serverId);\n return client?.status === \"connected\";\n }\n\n /**\n * Refresh tools from all connected servers\n */\n async refreshAllTools(): Promise<void> {\n await Promise.all(\n Array.from(this.clients.values())\n .filter((client) => client.status === \"connected\")\n .map((client) => client.refreshTools())\n );\n }\n\n /**\n * Add a new server configuration and optionally connect\n */\n async addServer(config: MCPServerConfig, connect = true): Promise<void> {\n if (this.clients.has(config.id)) {\n throw new Error(`Server ${config.id} already exists`);\n }\n\n this.config.servers.push(config);\n\n if (connect && config.enabled) {\n await this.connectServer(config);\n }\n }\n\n /**\n * Remove a server\n */\n async removeServer(serverId: string): Promise<void> {\n await this.disconnectServer(serverId);\n this.config.servers = this.config.servers.filter((s) => s.id !== serverId);\n }\n\n /**\n * Get the current configuration\n */\n getConfig(): MCPConfig {\n return { ...this.config };\n }\n\n /**\n * Get count of connected servers\n */\n get connectedCount(): number {\n return Array.from(this.clients.values()).filter(\n (c) => c.status === \"connected\"\n ).length;\n }\n\n /**\n * Get total tool count across all servers\n */\n get totalToolCount(): number {\n return this.getAllTools().length;\n }\n}\n\n// ============================================\n// HELPER FUNCTIONS\n// ============================================\n\n/**\n * Load MCP configuration from a file\n */\nexport async function loadMCPConfig(path: string): Promise<MCPConfig> {\n try {\n const { readFile, access } = await import(\"node:fs/promises\");\n try {\n await access(path);\n } catch {\n console.log(`[MCP] Config file not found: ${path}, using empty config`);\n return { servers: [] };\n }\n\n const content = await readFile(path, \"utf-8\");\n const config = JSON.parse(content) as MCPConfig;\n\n // Validate config\n if (!Array.isArray(config.servers)) {\n console.warn(\"[MCP] Invalid config: servers must be an array\");\n return { servers: [] };\n }\n\n return config;\n } catch (error) {\n console.error(\"[MCP] Failed to load config:\", error);\n return { servers: [] };\n }\n}\n\n/**\n * Create and initialize an MCP registry from a config file\n */\nexport async function initMCPRegistry(configPath: string): Promise<MCPRegistry> {\n const config = await loadMCPConfig(configPath);\n const registry = new MCPRegistry(config);\n await registry.initialize();\n return registry;\n}\n","/**\n * MCP Tool Bridge - Converts MCP tools to Anthropic format\n * Handles tool routing between native and MCP tools\n */\n\nimport type { Tool } from \"@anthropic-ai/sdk/resources/messages\";\nimport type { MCPRegistry } from \"./registry\";\nimport type { MCPTool, MCPToolProperty, MCPToolResult } from \"./types\";\n\n// MCP tool prefix format: mcp_{serverId}_{toolName}\nconst MCP_TOOL_PREFIX = \"mcp_\";\n\n// ============================================\n// TOOL NAME UTILITIES\n// ============================================\n\n/**\n * Create a prefixed tool name for routing\n */\nexport function createMCPToolName(serverId: string, toolName: string): string {\n // Sanitize serverId and toolName to be safe for use as identifiers\n const safeServerId = serverId.replace(/[^a-zA-Z0-9_]/g, \"_\");\n const safeToolName = toolName.replace(/[^a-zA-Z0-9_]/g, \"_\");\n return `${MCP_TOOL_PREFIX}${safeServerId}__${safeToolName}`;\n}\n\n/**\n * Check if a tool name is an MCP tool\n */\nexport function isMCPTool(name: string): boolean {\n return name.startsWith(MCP_TOOL_PREFIX);\n}\n\n/**\n * Parse an MCP tool name to get serverId and original tool name\n */\nexport function parseMCPToolName(name: string): { serverId: string; toolName: string } | null {\n if (!isMCPTool(name)) {\n return null;\n }\n\n const withoutPrefix = name.slice(MCP_TOOL_PREFIX.length);\n const separatorIndex = withoutPrefix.indexOf(\"__\");\n\n if (separatorIndex === -1) {\n return null;\n }\n\n return {\n serverId: withoutPrefix.slice(0, separatorIndex),\n toolName: withoutPrefix.slice(separatorIndex + 2),\n };\n}\n\n// ============================================\n// SCHEMA CONVERSION\n// ============================================\n\n/**\n * Convert MCP tool property to JSON Schema format\n */\nfunction convertProperty(prop: MCPToolProperty): Record<string, unknown> {\n const result: Record<string, unknown> = {\n type: prop.type,\n };\n\n if (prop.description) {\n result.description = prop.description;\n }\n\n if (prop.enum) {\n result.enum = prop.enum;\n }\n\n if (prop.items) {\n result.items = convertProperty(prop.items);\n }\n\n if (prop.properties) {\n result.properties = Object.fromEntries(\n Object.entries(prop.properties).map(([key, value]) => [\n key,\n convertProperty(value),\n ])\n );\n }\n\n if (prop.required) {\n result.required = prop.required;\n }\n\n return result;\n}\n\n/**\n * Convert MCP tool to Anthropic Tool format\n */\nexport function mcpToolToAnthropicTool(\n serverId: string,\n serverName: string,\n tool: MCPTool\n): Tool {\n const properties: Record<string, Record<string, unknown>> = {};\n\n if (tool.inputSchema.properties) {\n for (const [key, value] of Object.entries(tool.inputSchema.properties)) {\n properties[key] = convertProperty(value);\n }\n }\n\n const inputSchema: Tool.InputSchema = {\n type: \"object\",\n properties,\n required: tool.inputSchema.required || [],\n };\n\n // Create a unique name and add server context to description\n const name = createMCPToolName(serverId, tool.name);\n const description = tool.description\n ? `[${serverName}] ${tool.description}`\n : `[${serverName}] ${tool.name}`;\n\n return {\n name,\n description,\n input_schema: inputSchema,\n };\n}\n\n/**\n * Convert all tools from an MCP registry to Anthropic format\n */\nexport function mcpToolsToAnthropicTools(registry: MCPRegistry): Tool[] {\n const tools: Tool[] = [];\n const serverStates = registry.getServerStates();\n\n for (const state of serverStates) {\n if (state.status !== \"connected\") continue;\n\n const serverName = state.serverInfo?.name || state.config.name;\n\n for (const tool of state.tools) {\n tools.push(mcpToolToAnthropicTool(state.config.id, serverName, tool));\n }\n }\n\n return tools;\n}\n\n// ============================================\n// TOOL EXECUTION\n// ============================================\n\n/**\n * Execute an MCP tool call through the registry\n */\nexport async function executeMCPTool(\n registry: MCPRegistry,\n toolName: string,\n args: Record<string, unknown>\n): Promise<MCPToolResult> {\n const parsed = parseMCPToolName(toolName);\n\n if (!parsed) {\n return {\n success: false,\n error: `Invalid MCP tool name: ${toolName}`,\n };\n }\n\n return registry.callTool(parsed.serverId, parsed.toolName, args);\n}\n\n// ============================================\n// TOOL DISCOVERY\n// ============================================\n\n/**\n * Get a summary of available MCP tools for logging/display\n */\nexport function getMCPToolSummary(registry: MCPRegistry): string {\n const states = registry.getServerStates();\n const lines: string[] = [];\n\n for (const state of states) {\n const status = state.status === \"connected\" ? \"✓\" : \"✗\";\n const serverName = state.serverInfo?.name || state.config.name;\n const toolCount = state.tools.length;\n\n lines.push(` ${status} ${serverName}: ${toolCount} tools`);\n\n if (state.status === \"connected\" && state.tools.length > 0) {\n const toolNames = state.tools.map((t) => t.name).join(\", \");\n lines.push(` Tools: ${toolNames}`);\n } else if (state.lastError) {\n lines.push(` Error: ${state.lastError}`);\n }\n }\n\n if (lines.length === 0) {\n return \" No MCP servers configured\";\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Find an MCP tool by its original name (searches all servers)\n */\nexport function findMCPTool(\n registry: MCPRegistry,\n toolName: string\n): { serverId: string; tool: MCPTool } | null {\n const allTools = registry.getAllTools();\n\n for (const { serverId, tool } of allTools) {\n if (tool.name === toolName) {\n return { serverId, tool };\n }\n }\n\n return null;\n}\n"],"mappings":"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","names":[]}