@mcp-ts/sdk 1.5.1 → 1.5.3
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.
- package/README.md +89 -27
- package/dist/adapters/agui-adapter.d.mts +1 -1
- package/dist/adapters/agui-adapter.d.ts +1 -1
- package/dist/adapters/agui-adapter.js +50 -10
- package/dist/adapters/agui-adapter.js.map +1 -1
- package/dist/adapters/agui-adapter.mjs +50 -10
- package/dist/adapters/agui-adapter.mjs.map +1 -1
- package/dist/adapters/agui-middleware.d.mts +5 -1
- package/dist/adapters/agui-middleware.d.ts +5 -1
- package/dist/adapters/agui-middleware.js +116 -49
- package/dist/adapters/agui-middleware.js.map +1 -1
- package/dist/adapters/agui-middleware.mjs +117 -50
- package/dist/adapters/agui-middleware.mjs.map +1 -1
- package/dist/adapters/ai-adapter.d.mts +1 -1
- package/dist/adapters/ai-adapter.d.ts +1 -1
- package/dist/adapters/ai-adapter.js +49 -9
- package/dist/adapters/ai-adapter.js.map +1 -1
- package/dist/adapters/ai-adapter.mjs +49 -9
- package/dist/adapters/ai-adapter.mjs.map +1 -1
- package/dist/adapters/langchain-adapter.d.mts +1 -1
- package/dist/adapters/langchain-adapter.d.ts +1 -1
- package/dist/adapters/langchain-adapter.js +49 -9
- package/dist/adapters/langchain-adapter.js.map +1 -1
- package/dist/adapters/langchain-adapter.mjs +49 -9
- package/dist/adapters/langchain-adapter.mjs.map +1 -1
- package/dist/client/react.d.mts +10 -0
- package/dist/client/react.d.ts +10 -0
- package/dist/client/react.js +23 -0
- package/dist/client/react.js.map +1 -1
- package/dist/client/react.mjs +23 -0
- package/dist/client/react.mjs.map +1 -1
- package/dist/client/vue.d.mts +10 -0
- package/dist/client/vue.d.ts +10 -0
- package/dist/client/vue.js +17 -0
- package/dist/client/vue.js.map +1 -1
- package/dist/client/vue.mjs +17 -0
- package/dist/client/vue.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +123 -28
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +123 -28
- package/dist/index.mjs.map +1 -1
- package/dist/shared/index.d.mts +2 -2
- package/dist/shared/index.d.ts +2 -2
- package/dist/shared/index.js +123 -28
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +123 -28
- package/dist/shared/index.mjs.map +1 -1
- package/dist/{tool-router-XnWVxPzv.d.mts → tool-router-DK0RJblO.d.mts} +3 -0
- package/dist/{tool-router-Bo8qZbsD.d.ts → tool-router-DsKhRmJm.d.ts} +3 -0
- package/package.json +3 -3
- package/src/adapters/agui-adapter.ts +7 -7
- package/src/adapters/agui-middleware.ts +163 -59
- package/src/adapters/ai-adapter.ts +5 -5
- package/src/adapters/langchain-adapter.ts +5 -5
- package/src/client/react/use-mcp.ts +48 -0
- package/src/client/vue/use-mcp.ts +42 -0
- package/src/shared/meta-tools.ts +73 -15
- package/src/shared/tool-index.ts +85 -12
- package/src/shared/tool-router.ts +8 -7
package/dist/shared/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/shared/events.ts","../../src/shared/constants.ts","../../src/shared/errors.ts","../../src/shared/types.ts","../../src/shared/utils.ts","../../src/shared/tool-utils.ts","../../src/shared/tool-index.ts","../../src/shared/schema-compressor.ts","../../src/shared/meta-tools.ts","../../src/shared/tool-router.ts"],"names":["customAlphabet","b"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Simple event emitter pattern for MCP connection events\n * Inspired by Cloudflare's agents pattern but adapted for serverless\n */\n\nexport type Disposable = {\n dispose(): void;\n};\n\nexport type Event<T> = (listener: (event: T) => void) => Disposable;\n\n/**\n * Event emitter class for type-safe event handling\n * Similar to Cloudflare's Emitter but simplified for our use case\n */\nexport class Emitter<T> {\n private listeners: Set<(event: T) => void> = new Set();\n\n /**\n * Subscribe to events\n * @param listener - Callback function to handle events\n * @returns Disposable to unsubscribe\n */\n get event(): Event<T> {\n return (listener: (event: T) => void) => {\n this.listeners.add(listener);\n return {\n dispose: () => {\n this.listeners.delete(listener);\n },\n };\n };\n }\n\n /**\n * Fire an event to all listeners\n * @param event - Event data to emit\n */\n fire(event: T): void {\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch (error) {\n console.error('[Emitter] Error in event listener:', error);\n }\n }\n }\n\n /**\n * Clear all listeners\n */\n dispose(): void {\n this.listeners.clear();\n }\n\n /**\n * Get number of active listeners\n */\n get listenerCount(): number {\n return this.listeners.size;\n }\n}\n\n/**\n * Connection state types matching your existing ConnectionStatus\n * Extended with more granular states for better observability\n */\nexport type McpConnectionState =\n | 'DISCONNECTED' // Not connected\n | 'CONNECTING' // Establishing transport connection to MCP server\n | 'AUTHENTICATING' // OAuth flow in progress\n | 'AUTHENTICATED' // OAuth complete, pre-connect\n | 'DISCOVERING' // Discovering server capabilities (tools, resources, prompts)\n | 'CONNECTED' // Transport connection established\n | 'READY' // Fully connected and ready to use\n | 'VALIDATING' // Validating existing session\n | 'RECONNECTING' // Attempting to reconnect\n | 'INITIALIZING' // Initializing session or connection\n | 'FAILED'; // Connection error at some point\n\n/**\n * MCP Connection Event Types\n * Discriminated union for type-safe event handling\n */\nexport type McpConnectionEvent =\n | {\n type: 'state_changed';\n sessionId: string;\n serverId: string;\n serverName: string;\n serverUrl: string;\n createdAt?: number;\n state: McpConnectionState;\n previousState: McpConnectionState;\n timestamp: number;\n }\n | {\n type: 'tools_discovered';\n sessionId: string;\n serverId: string;\n toolCount: number;\n tools: any[];\n timestamp: number;\n }\n | {\n type: 'auth_required';\n sessionId: string;\n serverId: string;\n authUrl: string;\n timestamp: number;\n }\n | {\n type: 'error';\n sessionId: string;\n serverId: string;\n error: string;\n errorType: 'connection' | 'auth' | 'validation' | 'unknown';\n timestamp: number;\n }\n | {\n type: 'disconnected';\n sessionId: string;\n serverId: string;\n reason?: string;\n timestamp: number;\n }\n | {\n type: 'progress';\n sessionId: string;\n serverId: string;\n message: string;\n timestamp: number;\n };\n\n/**\n * Event fired when a tool execution returns a UI resource URI\n */\nexport interface McpAppsUIEvent {\n type: 'mcp-apps-ui';\n sessionId: string;\n resourceUri: string;\n toolName: string;\n result: unknown;\n timestamp: number;\n}\n\n/**\n * Observability event for debugging and monitoring\n */\nexport interface McpObservabilityEvent {\n type?: string;\n level?: 'debug' | 'info' | 'warn' | 'error';\n message?: string;\n displayMessage?: string;\n sessionId?: string;\n serverId?: string;\n payload?: Record<string, any>;\n metadata?: Record<string, any>; // Kept for backward compatibility\n timestamp: number;\n id?: string;\n}\n\n/**\n * DisposableStore for managing multiple disposables\n * Useful for cleanup in React hooks\n */\nexport class DisposableStore {\n private disposables: Set<Disposable> = new Set();\n\n add(disposable: Disposable): void {\n this.disposables.add(disposable);\n }\n\n dispose(): void {\n for (const disposable of this.disposables) {\n disposable.dispose();\n }\n this.disposables.clear();\n }\n}\n","/**\n * Centralized constants for MCP Redis library\n * Eliminates magic numbers and enables consistent configuration\n */\n\n// Redis TTL and Session Management\nexport const SESSION_TTL_SECONDS = 43200; // 12 hours\nexport const STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes for OAuth state\n\n// Heartbeat and Connection\nexport const DEFAULT_HEARTBEAT_INTERVAL_MS = 30000; // 30 seconds\n\n// Redis Key Prefixes\nexport const REDIS_KEY_PREFIX = 'mcp:session:';\n\n// Token Management\nexport const TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000; // 5 minute buffer before expiry\n\n// Client Information\nexport const DEFAULT_CLIENT_NAME = 'MCP Assistant';\nexport const DEFAULT_CLIENT_URI = 'https://mcp-assistant.in';\nexport const DEFAULT_LOGO_URI = 'https://mcp-assistant.in/logo.svg';\nexport const DEFAULT_POLICY_URI = 'https://mcp-assistant.in/privacy';\nexport const SOFTWARE_ID = '@mcp-ts';\nexport const SOFTWARE_VERSION = '1.3.4';\n\n// MCP Client Configuration\nexport const MCP_CLIENT_NAME = 'mcp-ts-oauth-client';\nexport const MCP_CLIENT_VERSION = '2.0';\n","/**\n * Standardized error classes for MCP Redis library\n * Provides consistent error handling across the codebase\n */\n\n/**\n * Base error class for all MCP-related errors\n */\nexport class McpError extends Error {\n constructor(\n public readonly code: string,\n message: string,\n public readonly cause?: Error\n ) {\n super(message);\n this.name = 'McpError';\n // Maintain proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n ...(this.cause ? { cause: this.cause.message } : {}),\n };\n }\n}\n\n/**\n * Thrown when OAuth authorization is required\n */\nexport class UnauthorizedError extends McpError {\n constructor(message: string = 'OAuth authorization required', cause?: Error) {\n super('UNAUTHORIZED', message, cause);\n this.name = 'UnauthorizedError';\n }\n}\n\n/**\n * Thrown when connection to MCP server fails\n */\nexport class ConnectionError extends McpError {\n constructor(message: string, cause?: Error) {\n super('CONNECTION_ERROR', message, cause);\n this.name = 'ConnectionError';\n }\n}\n\n/**\n * Thrown when session is not found or expired\n */\nexport class SessionNotFoundError extends McpError {\n constructor(sessionId: string, cause?: Error) {\n super('SESSION_NOT_FOUND', `Session not found: ${sessionId}`, cause);\n this.name = 'SessionNotFoundError';\n }\n}\n\n/**\n * Thrown when session validation fails\n */\nexport class SessionValidationError extends McpError {\n constructor(message: string, cause?: Error) {\n super('SESSION_VALIDATION_ERROR', message, cause);\n this.name = 'SessionValidationError';\n }\n}\n\n/**\n * Thrown when authentication fails\n */\nexport class AuthenticationError extends McpError {\n constructor(message: string, cause?: Error) {\n super('AUTH_ERROR', message, cause);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Thrown when OAuth state validation fails\n */\nexport class InvalidStateError extends McpError {\n constructor(message: string = 'Invalid OAuth state', cause?: Error) {\n super('INVALID_STATE', message, cause);\n this.name = 'InvalidStateError';\n }\n}\n\n/**\n * Thrown when client is not connected\n */\nexport class NotConnectedError extends McpError {\n constructor(message: string = 'Not connected to server', cause?: Error) {\n super('NOT_CONNECTED', message, cause);\n this.name = 'NotConnectedError';\n }\n}\n\n/**\n * Thrown when required configuration is missing\n */\nexport class ConfigurationError extends McpError {\n constructor(message: string, cause?: Error) {\n super('CONFIGURATION_ERROR', message, cause);\n this.name = 'ConfigurationError';\n }\n}\n\n/**\n * Thrown when tool execution fails\n */\nexport class ToolExecutionError extends McpError {\n constructor(toolName: string, message: string, cause?: Error) {\n super('TOOL_EXECUTION_ERROR', `Tool '${toolName}' failed: ${message}`, cause);\n this.name = 'ToolExecutionError';\n }\n}\n\n/**\n * RPC error codes for SSE communication\n */\nexport const RpcErrorCodes = {\n EXECUTION_ERROR: 'EXECUTION_ERROR',\n MISSING_IDENTITY: 'MISSING_IDENTITY',\n UNAUTHORIZED: 'UNAUTHORIZED',\n NO_CONNECTION: 'NO_CONNECTION',\n UNKNOWN_METHOD: 'UNKNOWN_METHOD',\n INVALID_PARAMS: 'INVALID_PARAMS',\n} as const;\n\nexport type RpcErrorCode = typeof RpcErrorCodes[keyof typeof RpcErrorCodes];\n","/**\n * Type definitions for MCP operations\n */\n\nimport { Tool, CallToolResult } from '@modelcontextprotocol/sdk/types.js';\n\n// ---------------------------------------------------------------------------\n// Core Capability Interfaces\n// ---------------------------------------------------------------------------\n\n/**\n * A client that can list and execute MCP tools.\n *\n * This is the structural interface that `ToolRouter`, adapters, and other\n * consumers use to interact with any MCP client implementation.\n * Both `MCPClient` and `createMcpClient()` satisfy this interface.\n */\nexport interface ToolClient {\n isConnected(): boolean;\n listTools(): Promise<{ tools: Tool[] }>;\n callTool(name: string, args: Record<string, unknown>): Promise<any>;\n getServerId?(): string | undefined;\n getServerName?(): string | undefined;\n getSessionId?(): string;\n}\n\n/**\n * A provider that manages multiple `ToolClient` instances.\n *\n * `MultiSessionClient` satisfies this interface. Pass it directly\n * to `ToolRouter` or adapters to aggregate tools from all connected servers.\n */\nexport interface ToolClientProvider {\n getClients(): ToolClient[];\n}\n\n// Connect API types\nexport interface ConnectRequest {\n serverUrl: string;\n callbackUrl: string;\n}\n\nexport interface ConnectSuccessResponse {\n success: true;\n sessionId: string;\n}\n\nexport interface ConnectAuthRequiredResponse {\n requiresAuth: true;\n authUrl: string;\n sessionId: string;\n}\n\nexport interface ConnectErrorResponse {\n error: string;\n}\n\nexport type ConnectResponse =\n | ConnectSuccessResponse\n | ConnectAuthRequiredResponse\n | ConnectErrorResponse;\n\n// Callback API types\nexport interface CallbackSuccessResponse {\n success: true;\n message: string;\n}\n\nexport interface CallbackErrorResponse {\n error: string;\n}\n\nexport type CallbackResponse = CallbackSuccessResponse | CallbackErrorResponse;\n\n// Disconnect API types\nexport interface DisconnectRequest {\n sessionId: string;\n}\n\nexport interface DisconnectSuccessResponse {\n success: true;\n message: string;\n}\n\nexport interface DisconnectErrorResponse {\n error: string;\n}\n\nexport type DisconnectResponse =\n | DisconnectSuccessResponse\n | DisconnectErrorResponse;\n\n// List Tools API types\nexport interface ListToolsSuccessResponse {\n tools: Tool[];\n}\n\nexport interface ListToolsErrorResponse {\n error: string;\n}\n\nexport type ListToolsResponse =\n | ListToolsSuccessResponse\n | ListToolsErrorResponse;\n\n// Call Tool API types\nexport interface CallToolRequest {\n sessionId: string;\n toolName: string;\n toolArgs: Record<string, unknown>;\n}\n\nexport interface CallToolSuccessResponse {\n content: Array<{\n type: string;\n text?: string;\n [key: string]: unknown;\n }>;\n isError: boolean;\n}\n\nexport interface CallToolErrorResponse {\n error: string;\n}\n\nexport type CallToolResponse =\n | CallToolSuccessResponse\n | CallToolErrorResponse;\n\n// Helper type guards\nexport function isConnectSuccess(\n response: ConnectResponse\n): response is ConnectSuccessResponse {\n return 'success' in response && response.success === true;\n}\n\nexport function isConnectAuthRequired(\n response: ConnectResponse\n): response is ConnectAuthRequiredResponse {\n return 'requiresAuth' in response && response.requiresAuth === true;\n}\n\nexport function isConnectError(\n response: ConnectResponse\n): response is ConnectErrorResponse {\n return 'error' in response;\n}\n\nexport function isListToolsSuccess(\n response: ListToolsResponse\n): response is ListToolsSuccessResponse {\n return 'tools' in response;\n}\n\nexport function isCallToolSuccess(\n response: CallToolResponse\n): response is CallToolSuccessResponse {\n return 'content' in response;\n}\n\n// Generic tool info type\nexport type ToolInfo = {\n name: string;\n description?: string;\n inputSchema?: unknown;\n};\n\n// Transport type\nexport type TransportType = 'sse' | 'streamable_http';\n\n// SSE/RPC types\nexport type McpRpcMethod =\n | 'connect'\n | 'disconnect'\n | 'listTools'\n | 'callTool'\n | 'getSessions'\n | 'restoreSession'\n | 'finishAuth'\n | 'listPrompts'\n | 'getPrompt'\n | 'listResources'\n | 'readResource';\n\nexport interface McpRpcRequest {\n id: string;\n method: McpRpcMethod;\n params?: McpRpcParams;\n}\n\nexport interface McpRpcResponse<T = unknown> {\n id: string;\n result?: T;\n error?: {\n code: string;\n message: string;\n };\n}\n\n// RPC Parameter Types\nexport interface ConnectParams {\n serverId?: string; // Optional - generated server-side if not provided\n serverName: string;\n serverUrl: string;\n callbackUrl: string;\n transportType?: TransportType;\n}\n\nexport interface DisconnectParams {\n sessionId: string;\n}\n\nexport interface SessionParams {\n sessionId: string;\n}\n\nexport interface CallToolParams {\n sessionId: string;\n toolName: string;\n toolArgs: Record<string, unknown>;\n}\n\nexport interface GetPromptParams {\n sessionId: string;\n name: string;\n args?: Record<string, string>;\n}\n\nexport interface ReadResourceParams {\n sessionId: string;\n uri: string;\n}\n\nexport interface FinishAuthParams {\n sessionId: string;\n code: string;\n}\n\nexport type McpRpcParams =\n | ConnectParams\n | DisconnectParams\n | SessionParams\n | CallToolParams\n | GetPromptParams\n | ReadResourceParams\n | FinishAuthParams\n | undefined;\n\n// RPC Result Types\nexport interface SessionInfo {\n sessionId: string;\n serverId?: string;\n serverName?: string;\n serverUrl: string;\n transport: TransportType;\n createdAt: number;\n /**\n * Session readiness for auto-restore.\n * false means auth is pending and should be resumed explicitly by user action.\n */\n active?: boolean;\n}\n\nexport interface SessionListResult {\n sessions: SessionInfo[];\n}\n\nexport interface ConnectResult {\n sessionId: string;\n success: boolean;\n}\n\nexport interface DisconnectResult {\n success: boolean;\n}\n\nexport interface RestoreSessionResult {\n success: boolean;\n toolCount: number;\n}\n\nexport interface FinishAuthResult {\n success: boolean;\n toolCount: number;\n}\n\nexport interface ListToolsRpcResult {\n tools: Tool[];\n}\n\nexport interface ListPromptsResult {\n prompts: Array<{\n name: string;\n description?: string;\n arguments?: Array<{\n name: string;\n description?: string;\n required?: boolean;\n }>;\n }>;\n}\n\nexport interface ListResourcesResult {\n resources: Array<{\n uri: string;\n name: string;\n description?: string;\n mimeType?: string;\n }>;\n}\n\nexport type { CallToolResult };\n","import { customAlphabet } from 'nanoid';\n\n/** first char: letters only (required by OpenAI) */\nconst firstChar = customAlphabet(\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',\n 1\n);\n\n/** remaining chars: alphanumeric */\nconst rest = customAlphabet(\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',\n 11\n);\n\n/**\n * Sanitize server name to create a valid server label\n * Must start with a letter and contain only letters, digits, '-' and '_'\n */\nexport function sanitizeServerLabel(name: string): string {\n let sanitized = name\n .replace(/[^a-zA-Z0-9-_]/g, '_')\n .replace(/_{2,}/g, '_')\n .toLowerCase();\n\n if (!/^[a-zA-Z]/.test(sanitized)) {\n sanitized = 's_' + sanitized;\n }\n\n return sanitized;\n}\n\n/**\n * Generates a standard 12-character session ID compliant with external tool restrictions.\n * First character is always a letter.\n */\nexport function generateSessionId(): string {\n return firstChar() + rest();\n}\n","/**\n * Utility functions for working with MCP tool metadata\n */\n\nimport type { ToolInfo } from './types.js';\n\nexport interface ToolUiConfig {\n resourceUri: string;\n sessionId: string;\n}\n\n/**\n * Extract UI resource URI from tool metadata\n *\n * @param tool - The tool to extract UI config from\n * @returns The resource URI if available, undefined otherwise\n *\n * @example\n * const uri = getToolUiResourceUri(tool);\n * if (uri) {\n * // Tool has UI configuration\n * }\n */\nexport function getToolUiResourceUri(tool: ToolInfo): string | undefined {\n const meta = (tool as any)._meta;\n if (!meta?.ui) return undefined;\n\n const ui = meta.ui;\n if (typeof ui !== \"object\" || !ui) return undefined;\n\n // Check visibility filter - skip if explicitly hidden from app\n if (ui.visibility && !ui.visibility.includes(\"app\")) return undefined;\n\n // Support both 'uri' and 'resourceUri' field names for flexibility\n return typeof ui.resourceUri === \"string\"\n ? ui.resourceUri\n : typeof ui.uri === \"string\"\n ? ui.uri\n : undefined;\n}\n\n/**\n * Find a tool by name within connections\n *\n * @param connections - Array of MCP connections\n * @param toolName - Name of the tool to find\n * @returns The tool if found, undefined otherwise\n *\n * @example\n * const tool = findToolByName(connections, \"get_weather\");\n */\nexport function findToolByName(\n connections: Array<{ tools: ToolInfo[] }>,\n toolName: string\n): ToolInfo | undefined {\n for (const conn of connections) {\n const tool = conn.tools.find((t) => t.name === toolName);\n if (tool) return tool;\n }\n return undefined;\n}\n","/**\n * ToolIndex — Lightweight in-memory search index for MCP tool discovery.\n *\n * Supports two search methods:\n * • BM25 – Okapi BM25 ranking over tokenized tool metadata (zero external deps)\n * • regex – Pattern matching against tool names, descriptions, and parameters\n * • embedding – (optional) cosine-similarity over caller-supplied vectors,\n * blended with BM25 scores\n *\n * @packageDocumentation\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\n\n// ---------------------------------------------------------------------------\n// Public Types\n// ---------------------------------------------------------------------------\n\n/** Compact summary returned by search — intentionally lightweight. */\nexport interface ToolSummary {\n /** Fully qualified tool name (e.g. \"tool_github_create_pr\") */\n name: string;\n /** Human-readable description */\n description: string;\n /** Server that owns this tool */\n serverName: string;\n /** Session the tool belongs to */\n sessionId: string;\n /** Estimated token cost of the full inputSchema */\n estimatedTokens: number;\n}\n\n/** A tool with routing metadata attached during indexing. */\nexport interface IndexedTool extends Tool {\n sessionId: string;\n serverName: string;\n}\n\n/**\n * An optional embedding function supplied by the consumer.\n * Should accept an array of strings and return a matching array of\n * float-number arrays (one embedding vector per input string).\n */\nexport type EmbedFn = (texts: string[]) => Promise<number[][]>;\n\nexport interface ToolIndexOptions {\n /**\n * Custom embedding function for semantic search.\n * When provided, `search()` uses cosine-similarity in addition to keywords.\n * @example\n * ```ts\n * import { embed } from 'ai';\n * const embedFn: EmbedFn = async (texts) => {\n * const { embeddings } = await embed({ model: openai('text-embedding-3-small'), values: texts });\n * return embeddings;\n * };\n * ```\n */\n embedFn?: EmbedFn;\n\n /**\n * Relative weight of keyword score vs embedding score when both are active.\n * 0 = embedding only · 1 = keyword only · 0.4 (default) blends both.\n * @default 0.4\n */\n keywordWeight?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Token Estimation\n// ---------------------------------------------------------------------------\n\n/**\n * Character-class weights for accurate-ish token estimation without a real\n * tokenizer. Empirically calibrated against cl100k_base on typical JSON\n * Schema payloads.\n *\n * | Char class | Approx chars per token |\n * |--------------------|------------------------|\n * | Whitespace / punct | 1–2 |\n * | English words | ~4 |\n * | JSON keys/values | ~3.5 |\n *\n * We walk the string once and accumulate a weighted character count, then\n * divide by a calibrated divisor.\n */\nconst CALIBRATION_DIVISOR = 3.6;\n\nfunction classifyChar(ch: string): number {\n const code = ch.charCodeAt(0);\n // whitespace / common JSON structural chars → high token density\n if (code <= 0x20 || ch === '{' || ch === '}' || ch === '[' || ch === ']' || ch === ':' || ch === ',') return 1.0;\n // digits and symbols\n if (code >= 0x21 && code <= 0x2f) return 1.5;\n if (code >= 0x30 && code <= 0x39) return 2.0;\n // uppercase (often JSON keys)\n if (code >= 0x41 && code <= 0x5a) return 3.5;\n // lowercase (natural language in descriptions)\n if (code >= 0x61 && code <= 0x7a) return 4.0;\n // everything else (unicode, emojis, etc.)\n return 2.5;\n}\n\n// ---------------------------------------------------------------------------\n// ToolIndex\n// ---------------------------------------------------------------------------\n\nexport class ToolIndex {\n /** All indexed tools keyed by name (supports duplicates). */\n private tools = new Map<string, IndexedTool[]>();\n\n /** Precomputed lightweight summaries keyed by document. */\n private toolSummaries = new Map<string, ToolSummary>();\n\n /** Pre-computed search text for keyword matching (lowercase), keyed by document. */\n private searchTexts = new Map<string, string>();\n\n /** Pre-computed IDF values per token (computed once on build). */\n private idf = new Map<string, number>();\n\n /** Per-tool TF vectors (Map<token, tf>). */\n private tfVectors = new Map<string, Map<string, number>>();\n\n /** Optional: pre-computed embedding vectors per tool. */\n private embeddings = new Map<string, number[]>();\n\n /** BM25: document lengths in tokens for each tool. */\n private docLengths = new Map<string, number>();\n\n /** BM25: average document length across the entire index. */\n private avgDocLength = 0;\n\n /** Cached total estimated token cost across all indexed tools. */\n private totalTokenCost = 0;\n\n private options: Required<ToolIndexOptions>;\n\n constructor(options: ToolIndexOptions = {}) {\n this.options = {\n embedFn: options.embedFn ?? (undefined as unknown as EmbedFn),\n keywordWeight: options.keywordWeight ?? 0.4,\n };\n }\n\n // -----------------------------------------------------------------------\n // Indexing\n // -----------------------------------------------------------------------\n\n /**\n * Build (or rebuild) the index from the given tool set.\n * Call this after connecting / reconnecting to MCP servers.\n */\n async buildIndex(tools: IndexedTool[]): Promise<void> {\n this.tools.clear();\n this.toolSummaries.clear();\n this.searchTexts.clear();\n this.idf.clear();\n this.tfVectors.clear();\n this.embeddings.clear();\n this.docLengths.clear();\n this.avgDocLength = 0;\n this.totalTokenCost = 0;\n\n // 1. Populate tool map + search text\n const allTokenSets: Map<string, Set<string>> = new Map();\n let totalLength = 0;\n\n for (const tool of tools) {\n const docKey = this.getDocumentKey(tool);\n\n if (!this.tools.has(tool.name)) {\n this.tools.set(tool.name, []);\n }\n this.tools.get(tool.name)!.push(tool);\n const estimatedTokens = ToolIndex.estimateTokens(tool);\n this.toolSummaries.set(docKey, {\n name: tool.name,\n description: tool.description ?? '',\n serverName: tool.serverName,\n sessionId: tool.sessionId,\n estimatedTokens,\n });\n this.totalTokenCost += estimatedTokens;\n\n const text = this.buildSearchableText(tool).toLowerCase();\n this.searchTexts.set(docKey, text);\n\n const tokens = this.tokenize(text);\n const tf = new Map<string, number>();\n const uniqueTokens = new Set<string>();\n\n for (const tok of tokens) {\n tf.set(tok, (tf.get(tok) ?? 0) + 1);\n uniqueTokens.add(tok);\n }\n\n // Normalize TF\n const maxTf = Math.max(...tf.values(), 1);\n for (const [k, v] of tf) {\n tf.set(k, v / maxTf);\n }\n\n this.tfVectors.set(docKey, tf);\n allTokenSets.set(docKey, uniqueTokens);\n\n const length = tokens.length;\n this.docLengths.set(docKey, length);\n totalLength += length;\n }\n\n // Compute average document length\n this.avgDocLength = totalLength / (tools.length || 1);\n\n // 2. Compute IDF\n const totalDocs = tools.length || 1;\n const dfCounts = new Map<string, number>();\n\n for (const tokenSet of allTokenSets.values()) {\n for (const tok of tokenSet) {\n dfCounts.set(tok, (dfCounts.get(tok) ?? 0) + 1);\n }\n }\n\n for (const [tok, df] of dfCounts) {\n this.idf.set(tok, Math.log(totalDocs / df) + 1);\n }\n\n // 3. Build embeddings if an embedFn was provided\n if (this.options.embedFn) {\n const names = [...this.searchTexts.keys()];\n const texts = names.map((n) => this.searchTexts.get(n)!);\n\n try {\n const vectors = await this.options.embedFn(texts);\n for (let i = 0; i < names.length; i++) {\n if (vectors[i]) {\n this.embeddings.set(names[i], vectors[i]);\n }\n }\n } catch (err) {\n console.warn('[ToolIndex] Embedding generation failed, falling back to keyword-only search:', err);\n }\n }\n }\n\n // -----------------------------------------------------------------------\n // Search\n // -----------------------------------------------------------------------\n\n /**\n * Search the index and return the top-K most relevant tools.\n *\n * When an `embedFn` is configured the final score is a weighted blend of\n * keyword TF-IDF similarity and embedding cosine-similarity:\n *\n * `score = keywordWeight × keyword_score + (1 - keywordWeight) × cosine_score`\n */\n async search(query: string, topK = 5): Promise<ToolSummary[]> {\n if (this.tools.size === 0) return [];\n\n const queryLower = query.toLowerCase();\n const queryTokens = this.tokenize(queryLower);\n\n // 1. Keyword scores (BM25)\n const keywordScores = new Map<string, number>();\n\n const k1 = 1.2;\n const b = 0.75;\n\n for (const [docKey, docTf] of this.tfVectors) {\n let score = 0;\n const docLen = this.docLengths.get(docKey) ?? 0;\n\n for (const tok of queryTokens) {\n const tfVal = docTf.get(tok) ?? 0;\n if (tfVal === 0) continue;\n\n const idf = this.idf.get(tok) ?? 0;\n\n // BM25 formula:\n // score = idf * (tf * (k1 + 1)) / (tf + k1 * (1 - b + b * (docLen / avgDocLength)))\n const numerator = tfVal * (k1 + 1);\n const denominator = tfVal + k1 * (1 - b + b * (docLen / this.avgDocLength));\n \n score += idf * (numerator / denominator);\n }\n\n keywordScores.set(docKey, score);\n }\n\n // 2. Embedding scores (optional)\n let embeddingScores: Map<string, number> | null = null;\n\n if (this.options.embedFn && this.embeddings.size > 0) {\n try {\n const [queryEmbedding] = await this.options.embedFn([queryLower]);\n if (queryEmbedding) {\n embeddingScores = new Map();\n for (const [docKey, vec] of this.embeddings) {\n embeddingScores.set(docKey, this.cosineSimilarity(queryEmbedding, vec));\n }\n }\n } catch {\n // Silently fall back to keyword only for this query\n }\n }\n\n // 3. Blend scores\n const kw = this.options.keywordWeight;\n const finalScores: Array<{ docKey: string; score: number }> = [];\n\n for (const docKey of this.toolSummaries.keys()) {\n const kwScore = keywordScores.get(docKey) ?? 0;\n const embScore = embeddingScores?.get(docKey) ?? 0;\n\n const score = embeddingScores ? kw * kwScore + (1 - kw) * embScore : kwScore;\n\n if (score > 0) {\n finalScores.push({ docKey, score });\n }\n }\n\n // 4. Sort and return top-K\n finalScores.sort((a, b) => b.score - a.score);\n\n return finalScores.slice(0, topK).map(({ docKey }) => {\n return this.toolSummaries.get(docKey)!;\n });\n }\n\n /**\n * Search tools using a regex pattern.\n * Matches against name, description, and parameter metadata.\n */\n searchRegex(pattern: string, topK = 5): ToolSummary[] {\n if (this.tools.size === 0) return [];\n\n try {\n // Handle Anthropic-style (?i) case-insensitive flag which JS doesn't support natively in string\n let flags = '';\n let cleanPattern = pattern;\n if (pattern.includes('(?i)')) {\n flags = 'i';\n cleanPattern = pattern.replace(/\\(\\?i\\)/g, '');\n }\n\n const regex = new RegExp(cleanPattern, flags || undefined);\n const matches: Array<{ docKey: string; score: number }> = [];\n\n for (const [docKey, text] of this.searchTexts) {\n const tool = this.toolSummaries.get(docKey);\n if (!tool) continue;\n\n if (regex.test(text) || regex.test(tool.name)) {\n // Use a simple heuristic for ranking regex matches: \n // 1. Exact name match (highest)\n // 2. Name starts with pattern\n // 3. Name contains pattern\n // 4. Description contains pattern (lowest)\n let score = 1;\n if (tool.name === cleanPattern) score = 10;\n else if (tool.name.startsWith(cleanPattern)) score = 5;\n else if (tool.name.toLowerCase().includes(cleanPattern.toLowerCase())) score = 2;\n\n matches.push({ docKey, score });\n }\n }\n\n matches.sort((a, b) => b.score - a.score);\n\n return matches.slice(0, topK).map(({ docKey }) => {\n return this.toolSummaries.get(docKey)!;\n });\n } catch (err) {\n console.warn('[ToolIndex] Regex search failed:', err);\n return [];\n }\n }\n\n // -----------------------------------------------------------------------\n // Accessors\n // -----------------------------------------------------------------------\n\n /**\n * Get tool definition(s) by name.\n * If namespace is provided, it tries to match sessionId or serverName.\n */\n getTool(name: string, namespace?: string): IndexedTool[] {\n const list = this.tools.get(name) ?? [];\n if (!namespace) return list;\n\n return list.filter((t) => t.sessionId === namespace || t.serverName === namespace);\n }\n\n /** All indexed tool names. */\n getToolNames(): string[] {\n return [...this.tools.keys()];\n }\n\n /** Number of indexed tools (including duplicates). */\n get size(): number {\n let count = 0;\n for (const list of this.tools.values()) {\n count += list.length;\n }\n return count;\n }\n\n /** Total estimated token cost of all indexed tool schemas. */\n getTotalTokenCost(): number {\n return this.totalTokenCost;\n }\n\n // -----------------------------------------------------------------------\n // Static Helpers\n // -----------------------------------------------------------------------\n\n /**\n * Estimate token count of a tool's full schema (name + description + inputSchema).\n *\n * Uses character-class weighted counting calibrated against cl100k_base.\n * Accuracy is typically within ±10% for JSON Schema payloads.\n */\n static estimateTokens(tool: Tool): number {\n const parts: string[] = [tool.name];\n if (tool.description) parts.push(tool.description);\n if (tool.inputSchema) parts.push(JSON.stringify(tool.inputSchema));\n\n const text = parts.join(' ');\n let weightedLen = 0;\n\n for (let i = 0; i < text.length; i++) {\n weightedLen += 1 / classifyChar(text[i]);\n }\n\n return Math.ceil(weightedLen / (1 / CALIBRATION_DIVISOR));\n }\n\n // -----------------------------------------------------------------------\n // Internals\n // -----------------------------------------------------------------------\n\n /** Build a single searchable string from tool metadata. */\n private buildSearchableText(tool: Tool): string {\n const parts: string[] = [tool.name];\n if (tool.description) parts.push(tool.description);\n\n // Include property names and descriptions from schema\n if (tool.inputSchema && typeof tool.inputSchema === 'object') {\n const schema = tool.inputSchema as Record<string, unknown>;\n const props = schema.properties as Record<string, { description?: string }> | undefined;\n if (props) {\n for (const [key, val] of Object.entries(props)) {\n parts.push(key);\n if (val && typeof val === 'object' && val.description) {\n parts.push(val.description);\n }\n }\n }\n }\n\n return parts.join(' ');\n }\n\n private getDocumentKey(tool: IndexedTool): string {\n return `${tool.sessionId}::${tool.serverName}::${tool.name}`;\n }\n\n /** Simple whitespace + camelCase + snake_case tokenizer. */\n private tokenize(text: string): string[] {\n return text\n // Split camelCase: \"getWeather\" → \"get Weather\"\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n // Split snake_case / kebab-case\n .replace(/[_-]/g, ' ')\n // Remove non-alphanumeric (except spaces)\n .replace(/[^a-z0-9\\s]/g, '')\n // Split on whitespace\n .split(/\\s+/)\n .filter((t) => t.length > 1); // drop single-char noise\n }\n\n /** Cosine similarity between two vectors. */\n private cosineSimilarity(a: number[], b: number[]): number {\n const len = Math.min(a.length, b.length);\n let dot = 0;\n let magA = 0;\n let magB = 0;\n\n for (let i = 0; i < len; i++) {\n dot += a[i] * b[i];\n magA += a[i] * a[i];\n magB += b[i] * b[i];\n }\n\n const denom = Math.sqrt(magA) * Math.sqrt(magB);\n return denom > 0 ? dot / denom : 0;\n }\n}\n","/**\n * SchemaCompressor — Utilities for reducing tool schema token overhead.\n *\n * Provides compact representations of tools (name + description only,\n * no inputSchema) and token savings estimation.\n *\n * @packageDocumentation\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport { ToolIndex } from './tool-index.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A minimal tool representation containing only what an LLM needs to\n * *decide whether* to use a tool. The full `inputSchema` is deferred.\n */\nexport interface CompactTool {\n name: string;\n description?: string;\n /**\n * Human-readable hint about the expected parameters.\n * e.g. \"(location: string, unit?: 'celsius' | 'fahrenheit')\"\n */\n parameterHint?: string;\n}\n\nexport interface CompressionStats {\n /** Estimated tokens for the *full* tool list. */\n fullTokens: number;\n /** Estimated tokens for the *compact* tool list. */\n compactTokens: number;\n /** Absolute token savings. */\n savedTokens: number;\n /** Percentage savings as a human-readable string, e.g. \"82.3%\". */\n savingsPercent: string;\n}\n\n// ---------------------------------------------------------------------------\n// SchemaCompressor\n// ---------------------------------------------------------------------------\n\nexport class SchemaCompressor {\n /**\n * Convert a full MCP Tool definition to a compact summary.\n *\n * The compact form omits `inputSchema` entirely and optionally generates\n * a short `parameterHint` from the schema's top-level properties.\n */\n static toCompact(tool: Tool): CompactTool {\n const compact: CompactTool = {\n name: tool.name,\n description: tool.description,\n };\n\n // Build parameter hint from schema\n if (tool.inputSchema && typeof tool.inputSchema === 'object') {\n const schema = tool.inputSchema as {\n properties?: Record<string, { type?: string; enum?: unknown[] }>;\n required?: string[];\n };\n\n if (schema.properties) {\n const required = new Set(schema.required ?? []);\n const parts: string[] = [];\n\n for (const [key, val] of Object.entries(schema.properties)) {\n const type = val?.type ?? 'any';\n const enumSuffix =\n val?.enum && Array.isArray(val.enum)\n ? `: ${val.enum.map((e) => `'${e}'`).join(' | ')}`\n : `: ${type}`;\n\n parts.push(required.has(key) ? `${key}${enumSuffix}` : `${key}?${enumSuffix}`);\n }\n\n if (parts.length > 0) {\n compact.parameterHint = `(${parts.join(', ')})`;\n }\n }\n }\n\n return compact;\n }\n\n /**\n * Convert an array of tools to compact form, optionally limiting the count.\n */\n static compactAll(tools: Tool[], options?: { maxTools?: number }): CompactTool[] {\n const limited = options?.maxTools ? tools.slice(0, options.maxTools) : tools;\n return limited.map((t) => SchemaCompressor.toCompact(t));\n }\n\n /**\n * Estimate token savings from using compact vs full tool schemas.\n */\n static estimateSavings(tools: Tool[]): CompressionStats {\n let fullTokens = 0;\n let compactTokens = 0;\n\n for (const tool of tools) {\n fullTokens += ToolIndex.estimateTokens(tool);\n\n // Compact form: name + description + parameterHint\n const compact = SchemaCompressor.toCompact(tool);\n const text = [compact.name, compact.description ?? '', compact.parameterHint ?? ''].join(' ');\n // Simple estimation for compact: ~4 chars per token for plain text\n compactTokens += Math.ceil(text.length / 4);\n }\n\n const saved = fullTokens - compactTokens;\n const pct = fullTokens > 0 ? ((saved / fullTokens) * 100).toFixed(1) : '0.0';\n\n return {\n fullTokens,\n compactTokens,\n savedTokens: saved,\n savingsPercent: `${pct}%`,\n };\n }\n}\n","/**\n * Meta-tools — Injectable tool definitions that let the LLM discover and\n * load MCP tools on-demand, following Anthropic's Tool Search pattern.\n *\n * Instead of injecting 50+ full tool schemas into the context window, you\n * inject just these 4 meta-tools. The LLM calls them to find and load\n * only the tools it actually needs.\n *\n * Meta-tools:\n * • `mcp_search_tool_bm25` — BM25 natural language search\n * • `mcp_search_tool_regex` — Regex pattern search\n * • `mcp_get_tool_schema` — Get full inputSchema for a discovered tool\n * • `mcp_execute_tool` — Execute a discovered tool\n *\n * @packageDocumentation\n */\n\nimport type { Tool, CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolRouter } from './tool-router.js';\n\n// ---------------------------------------------------------------------------\n// Tool Definitions\n// ---------------------------------------------------------------------------\n\n/**\n * Creates the `mcp_search_tool_bm25` tool definition.\n *\n * This tool lets the LLM search the full catalog of available MCP tools\n * using a BM25 natural-language query. Returns tool names and descriptions\n * without the full inputSchema to save context space.\n */\nexport function createSearchToolDefinition(): Tool {\n return {\n name: 'mcp_search_tool_bm25',\n description:\n 'Search the catalog of available tools using BM25 natural language ranking. ' +\n 'Returns tool names, descriptions, and server info. ' +\n 'Use this FIRST to find relevant tools before calling them. ' +\n 'Example queries: \"database query\", \"send email\", \"github pull request\".',\n inputSchema: {\n type: 'object' as const,\n properties: {\n query: {\n type: 'string',\n description: 'Natural language description of the capability you need.',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of results to return (default: 5, max: 20).',\n },\n },\n required: ['query'],\n },\n };\n}\n\n/**\n * Creates the `mcp_search_tool_regex` tool definition.\n * \n * Matches Anthropic's tool_search_tool_regex exactly (takes a 'query' regex pattern).\n */\nexport function createRegexSearchToolDefinition(): Tool {\n return {\n name: 'mcp_search_tool_regex',\n description:\n 'Search the catalog of available tools using a Python-style regex pattern. ' +\n 'Matches against tool names, descriptions, and parameter descriptions. ' +\n 'Example patterns: \"^github_\", \"weather\", \"(?i)slack\".',\n inputSchema: {\n type: 'object' as const,\n properties: {\n query: {\n type: 'string',\n description: 'Regex pattern to search for (e.g., \"^get_.*_data\", \"database\").',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of results to return (default: 5, max: 20).',\n },\n },\n required: ['query'],\n },\n };\n}\n\n/**\n * Creates the `mcp_get_tool_schema` tool definition.\n *\n * After discovering tools via `mcp_search_tool_bm25` or\n * `mcp_search_tool_regex`, the LLM calls this to load the full\n * inputSchema for a specific tool so it can construct the correct\n * arguments.\n */\nexport function createGetSchemaToolDefinition(): Tool {\n return {\n name: 'mcp_get_tool_schema',\n description:\n 'Get the full input schema (parameters) for a specific tool. ' +\n 'Call this after mcp_search_tool_bm25 to get the parameter details ' +\n 'needed to call a tool correctly.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n toolName: {\n type: 'string',\n description: 'The exact tool name returned by mcp_search_tool_bm25.',\n },\n serverName: {\n type: 'string',\n description:\n 'Optional: The server name provided in mcp_search_tool_bm25. Required if multiple tools have the same name.',\n },\n },\n required: ['toolName'],\n },\n };\n}\n\n/**\n * Creates the `mcp_execute_tool` tool definition.\n *\n * This is the execution meta-tool — the LLM calls this to execute any\n * tool discovered via `mcp_search_tool_bm25` or `mcp_search_tool_regex`.\n * The LLM should first call `mcp_get_tool_schema` to know the correct\n * arguments.\n *\n * Instead of registering every real tool with the framework, we proxy\n * all execution through a single meta-tool.\n */\nexport function createExecuteToolDefinition(): Tool {\n return {\n name: 'mcp_execute_tool',\n description:\n 'Execute a tool that was discovered via mcp_search_tool_bm25. ' +\n 'You MUST call mcp_get_tool_schema first to know the correct parameters. ' +\n 'Pass the exact tool name and its arguments.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n toolName: {\n type: 'string',\n description: 'The exact tool name from mcp_search_tool_bm25 results.',\n },\n serverName: {\n type: 'string',\n description:\n 'Optional: The server name provided in mcp_search_tool_bm25. Required if multiple tools have the same name.',\n },\n args: {\n type: 'object',\n description:\n \"Arguments matching the tool's inputSchema. Omit or pass {} if the tool takes no parameters.\",\n additionalProperties: true,\n },\n },\n required: ['toolName'],\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Meta-tool Executors\n// ---------------------------------------------------------------------------\n\n/**\n * Callback for executing a real MCP tool via the correct client.\n * Provided by adapters that wire up client routing.\n */\nexport type CallToolFn = (\n toolName: string,\n args: Record<string, unknown>,\n namespace?: string\n) => Promise<any>;\n\n/**\n * Execute a meta-tool call and return the result in MCP CallToolResult format.\n *\n * @param toolName - One of the meta-tool names (mcp_search_tool_bm25, mcp_search_tool_regex, etc.)\n * @param args - The arguments from the LLM's tool call\n * @param router - The ToolRouter to query\n * @param callToolFn - Optional callback for executing real tools (required for mcp_execute_tool)\n * @returns MCP-compatible CallToolResult, or null if this isn't a meta-tool\n */\nexport async function executeMetaTool(\n toolName: string,\n args: Record<string, unknown>,\n router: ToolRouter,\n callToolFn?: CallToolFn\n): Promise<CallToolResult | null> {\n const resolveToolSchema = (name: string, namespace?: string): { tool?: Tool; error?: CallToolResult } => {\n try {\n return { tool: router.getToolSchema(name, namespace) };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n return {\n error: {\n content: [{ type: 'text', text: errorMessage }],\n isError: true,\n },\n };\n }\n };\n\n switch (toolName) {\n case 'mcp_search_tool_bm25': {\n const query = String(args.query ?? '');\n const limit = Math.min(Number(args.limit) || 5, 20);\n\n const results = await router.searchTools(query, limit);\n\n const text = results.length === 0\n ? 'No tools found matching your query. Try different keywords.'\n : results\n .map(\n (t, i) =>\n `${i + 1}. **${t.name}** (server: ${t.serverName})\\n` +\n ` ${t.description}\\n` +\n ` Estimated tokens: ${t.estimatedTokens}`\n )\n .join('\\n');\n\n return {\n content: [{ type: 'text', text }],\n isError: false,\n };\n }\n\n case 'mcp_search_tool_regex': {\n const pattern = String(args.query ?? '');\n const limit = Math.min(Number(args.limit) || 5, 20);\n\n const results = await router.searchToolsRegex(pattern, limit);\n\n const text = results.length === 0\n ? 'No tools matched your regex pattern. Try a broader pattern.'\n : results\n .map(\n (t, i) =>\n `${i + 1}. **${t.name}** (server: ${t.serverName})\\n` +\n ` ${t.description}\\n` +\n ` Estimated tokens: ${t.estimatedTokens}`\n )\n .join('\\n');\n\n return {\n content: [{ type: 'text', text }],\n isError: false,\n };\n }\n\n case 'mcp_get_tool_schema': {\n const name = String(args.toolName ?? '');\n const namespace = String(args.serverName ?? '') || undefined;\n const { tool, error } = resolveToolSchema(name, namespace);\n\n if (error) {\n return error;\n }\n\n if (!tool) {\n return {\n content: [\n {\n type: 'text',\n text: `Tool \"${name}\" not found. Use mcp_search_tool_bm25 to find available tools first.`,\n },\n ],\n isError: true,\n };\n }\n\n const schema = {\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(schema, null, 2) }],\n isError: false,\n };\n }\n\n case 'mcp_execute_tool': {\n const targetToolName = String(args.toolName ?? '');\n const namespace = String(args.serverName ?? '') || undefined;\n const toolArgs = (args.args as Record<string, unknown>) ?? {};\n\n if (!targetToolName) {\n return {\n content: [{ type: 'text', text: 'Missing required parameter \"toolName\". Specify which tool to execute.' }],\n isError: true,\n };\n }\n\n // Verify the tool exists in our index\n const { tool, error } = resolveToolSchema(targetToolName, namespace);\n if (error) {\n return error;\n }\n\n if (!tool) {\n return {\n content: [\n {\n type: 'text',\n text: `Tool \"${targetToolName}\" not found. Use mcp_search_tool_bm25 to discover available tools first.`,\n },\n ],\n isError: true,\n };\n }\n\n if (!callToolFn) {\n return {\n content: [{ type: 'text', text: 'Tool execution is not available. No callToolFn was configured.' }],\n isError: true,\n };\n }\n\n try {\n const result = await callToolFn(targetToolName, toolArgs, namespace);\n\n // Normalize result to text\n if (result && typeof result === 'object' && 'content' in result) {\n // Already MCP CallToolResult format\n return result as CallToolResult;\n }\n\n const text = typeof result === 'string' ? result : JSON.stringify(result, null, 2);\n return {\n content: [{ type: 'text', text }],\n isError: false,\n };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n return {\n content: [{ type: 'text', text: `Tool execution failed: ${errorMessage}` }],\n isError: true,\n };\n }\n }\n\n default:\n return null;\n }\n}\n\n/** Check if a tool name is one of the meta-tools. */\nexport function isMetaTool(toolName: string): boolean {\n return (\n toolName === 'mcp_search_tool_bm25' ||\n toolName === 'mcp_search_tool_regex' ||\n toolName === 'mcp_get_tool_schema' ||\n toolName === 'mcp_execute_tool'\n );\n}\n\n/**\n * Unwraps a meta-tool proxy call (like mcp_execute_tool) to find the real target tool name and arguments.\n * Also automatically strips routing prefixes like tool_{serverId}_.\n * \n * Useful for frontend components that need to determine the actual tool being executed by an AI agent.\n */\nexport function resolveMetaToolProxy(\n toolName: string,\n args: Record<string, unknown> | null | undefined\n): { toolName: string; args: Record<string, unknown> } {\n // Unwrap mcp_execute_tool proxy arguments\n if (toolName === 'mcp_execute_tool') {\n const innerName = args?.toolName;\n const innerArgs = args?.args;\n return {\n toolName: typeof innerName === 'string' && innerName ? innerName : toolName,\n args: innerArgs && typeof innerArgs === 'object' && !Array.isArray(innerArgs)\n ? (innerArgs as Record<string, unknown>)\n : {},\n };\n }\n\n // Strip tool_<serverId>_ prefix used by AIAdapter\n const match = toolName.match(/(?:tool_[^_]+_)?(.+)$/);\n const resolvedName = match?.[1] ?? toolName;\n\n return { toolName: resolvedName, args: args ?? {} };\n}\n\n","/**\n * ToolRouter — Middleware layer for intelligent MCP tool selection.\n *\n * Sits between your AI framework adapter and MultiSessionClient to reduce\n * context window usage. Supports three strategies:\n *\n * • `all` — Pass through every tool (backward-compatible default)\n * • `search` — Expose only meta-tools; LLM discovers tools on-demand\n * • `groups` — Expose tools from active groups only\n *\n * Inspired by Anthropic's `defer_loading` + `tool_search_tool` pattern.\n *\n * @example\n * ```ts\n * import { ToolRouter } from '@mcp-ts/sdk/shared';\n * import { AIAdapter } from '@mcp-ts/sdk/adapters/ai';\n *\n * const router = new ToolRouter(multiSessionClient, {\n * strategy: 'search',\n * maxTools: 5,\n * });\n *\n * const tools = await AIAdapter.getTools(multiSessionClient, { toolRouter: router });\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolClient, ToolClientProvider } from './types.js';\nimport { ToolIndex, type IndexedTool, type ToolSummary, type EmbedFn } from './tool-index.js';\nimport { SchemaCompressor, type CompactTool } from './schema-compressor.js';\nimport {\n createSearchToolDefinition,\n createRegexSearchToolDefinition,\n createGetSchemaToolDefinition,\n createExecuteToolDefinition,\n} from './meta-tools.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ToolRouterStrategy = 'all' | 'search' | 'groups';\n\nexport interface ToolRouterOptions {\n /**\n * Strategy for tool selection.\n *\n * • `all` — Expose all tools (default, backward-compatible)\n * • `search` — Expose only meta-tools; LLM discovers real tools via search\n * • `groups` — Expose only tools from active groups\n *\n * @default 'all'\n */\n strategy?: ToolRouterStrategy;\n\n /**\n * Maximum tools to expose to the LLM at once.\n * Only applies to `groups` strategy and search results.\n * @default 40\n */\n maxTools?: number;\n\n /**\n * Tool groups configuration — map of group name to tool names.\n * When not provided, groups are auto-generated from server names.\n *\n * @example\n * ```ts\n * groups: {\n * database: ['query_db', 'list_tables', 'describe_table'],\n * github: ['create_pr', 'list_issues', 'search_code'],\n * }\n * ```\n */\n groups?: Record<string, string[]>;\n\n /**\n * Active groups (when `strategy='groups'`).\n * Only tools in these groups are exposed. Empty = all groups active.\n */\n activeGroups?: string[];\n\n /**\n * Whether to use compact schemas (name + description + parameterHint only, no inputSchema).\n * Reduces token usage but requires 2-turn flow: LLM picks tool → get schema → call.\n * @default false\n */\n compactSchemas?: boolean;\n\n /**\n * Optional embedding function for semantic search.\n * When not provided, keyword TF-IDF matching is used.\n */\n embedFn?: EmbedFn;\n\n /**\n * Weight of keyword score vs embedding score (0–1).\n * Only relevant when `embedFn` is provided.\n * @default 0.4\n */\n keywordWeight?: number;\n}\n\n/** Information about a tool group. */\nexport interface ToolGroupInfo {\n tools: string[];\n active: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Client Input Types\n// ---------------------------------------------------------------------------\n\n/**\n * Accepted client input for ToolRouter.\n * Pass a `ToolClientProvider` (e.g. MultiSessionClient), or an array of `ToolClient` instances.\n */\nexport type ToolRouterClientInput = ToolClientProvider | ToolClient[];\n\n// ---------------------------------------------------------------------------\n// ToolRouter\n// ---------------------------------------------------------------------------\n\nexport class ToolRouter {\n private index: ToolIndex;\n private allTools: IndexedTool[] = [];\n private groupsMap = new Map<string, ToolGroupInfo>();\n private strategy: ToolRouterStrategy;\n private maxTools: number;\n private compactSchemas: boolean;\n private activeGroups: Set<string>;\n private customGroups?: Record<string, string[]>;\n private initialized = false;\n\n constructor(\n private client: ToolRouterClientInput,\n private options: ToolRouterOptions = {}\n ) {\n this.strategy = options.strategy ?? 'all';\n this.maxTools = options.maxTools ?? 40;\n this.compactSchemas = options.compactSchemas ?? false;\n this.activeGroups = new Set(options.activeGroups ?? []);\n this.customGroups = options.groups;\n\n this.index = new ToolIndex({\n embedFn: options.embedFn,\n keywordWeight: options.keywordWeight,\n });\n }\n\n // -----------------------------------------------------------------------\n // Core Public API\n // -----------------------------------------------------------------------\n\n /**\n * Get tools filtered by the current strategy.\n * This is the main method adapters should call.\n *\n * - `all` → returns all tools (unchanged behavior)\n * - `search` → returns only meta-tools (mcp_search_tool_bm25, mcp_get_tool_schema, mcp_execute_tool)\n * - `groups` → returns tools from active groups only\n */\n async getFilteredTools(): Promise<Tool[]> {\n await this.ensureInitialized();\n\n switch (this.strategy) {\n case 'search':\n return this.getMetaToolDefinitions();\n\n case 'groups':\n return this.getGroupFilteredTools();\n\n case 'all':\n default:\n if (this.compactSchemas) {\n // Return tools with inputSchema stripped\n return this.allTools.map((t) => {\n const compact = SchemaCompressor.toCompact(t);\n return {\n name: compact.name,\n description:\n (compact.description ?? '') +\n (compact.parameterHint ? ` Parameters: ${compact.parameterHint}` : ''),\n inputSchema: { type: 'object' as const, properties: {} },\n };\n });\n }\n return [...this.allTools];\n }\n }\n\n /**\n * Search tools by natural-language query.\n * Works regardless of strategy.\n */\n async searchTools(query: string, topK?: number): Promise<ToolSummary[]> {\n await this.ensureInitialized();\n return this.index.search(query, topK ?? this.maxTools);\n }\n\n /**\n * Search tools by regex pattern.\n * Matches against name, description, and parameter metadata.\n */\n async searchToolsRegex(pattern: string, topK?: number): Promise<ToolSummary[]> {\n await this.ensureInitialized();\n return this.index.searchRegex(pattern, topK ?? this.maxTools);\n }\n\n /**\n * Get the full tool definition by name.\n * If tool name is ambiguous, use namespace to specify the server.\n */\n getToolSchema(toolName: string, namespace?: string): IndexedTool | undefined {\n const matches = this.index.getTool(toolName, namespace);\n\n if (matches.length === 0) return undefined;\n\n if (matches.length > 1) {\n const servers = matches.map((m) => m.serverName).join(', ');\n throw new Error(\n `Tool \"${toolName}\" is provided by multiple servers: [${servers}]. ` +\n `Please specify the desired \"serverName\" as a namespace.`\n );\n }\n\n return matches[0];\n }\n\n /**\n * Get compact (schema-less) summaries for all tools.\n */\n getCompactTools(): CompactTool[] {\n return SchemaCompressor.compactAll(this.allTools);\n }\n\n // -----------------------------------------------------------------------\n // Group Management\n // -----------------------------------------------------------------------\n\n /** Get all available groups with their tool lists and active status. */\n getGroups(): Map<string, ToolGroupInfo> {\n return new Map(this.groupsMap);\n }\n\n /** Activate specific groups. Pass empty array to activate all. */\n setActiveGroups(groups: string[]): void {\n this.activeGroups = new Set(groups);\n // Update groupsMap active flags\n for (const [name, info] of this.groupsMap) {\n info.active = this.activeGroups.size === 0 || this.activeGroups.has(name);\n }\n }\n\n /** Get the names of currently active groups. */\n getActiveGroups(): string[] {\n return [...this.activeGroups];\n }\n\n // -----------------------------------------------------------------------\n // Stats & Introspection\n // -----------------------------------------------------------------------\n\n /** Total token cost of all tools if loaded without filtering. */\n getTotalTokenCost(): number {\n return this.index.getTotalTokenCost();\n }\n\n /** Estimate token cost of the currently filtered tool set. */\n async getFilteredTokenCost(): Promise<number> {\n const tools = await this.getFilteredTools();\n let total = 0;\n for (const tool of tools) {\n total += ToolIndex.estimateTokens(tool);\n }\n return total;\n }\n\n /** Get compression stats showing savings from current strategy. */\n getCompressionStats() {\n return SchemaCompressor.estimateSavings(this.allTools);\n }\n\n /** Number of total indexed tools. */\n get totalToolCount(): number {\n return this.allTools.length;\n }\n\n /** Change strategy at runtime. */\n setStrategy(strategy: ToolRouterStrategy): void {\n this.strategy = strategy;\n }\n\n /**\n * Force a re-index of tools from all connected clients.\n * Call this after adding/removing MCP server connections.\n */\n async refresh(): Promise<void> {\n this.initialized = false;\n await this.ensureInitialized();\n }\n\n /**\n * Execute a tool by routing to the correct MCP client.\n * Used by the `mcp_execute_tool` meta-tool to proxy tool calls.\n */\n async callTool(\n toolName: string,\n args: Record<string, unknown>,\n namespace?: string\n ): Promise<any> {\n await this.ensureInitialized();\n\n const indexedTool = this.getToolSchema(toolName, namespace);\n if (!indexedTool) {\n throw new Error(\n `Tool \"${toolName}\" not found${\n namespace ? ` on server \"${namespace}\"` : ''\n }. Use mcp_search_tool_bm25 or mcp_search_tool_regex to discover available tools.`\n );\n }\n\n const clients = this.getClients();\n const targetClient =\n clients.find(\n (c) =>\n typeof c.getSessionId === 'function' &&\n c.getSessionId() === indexedTool.sessionId\n ) ?? clients.find((c) => c.isConnected());\n\n if (!targetClient) {\n throw new Error(`No connected client found for tool \"${toolName}\"`);\n }\n\n return await targetClient.callTool(toolName, args);\n }\n\n // -----------------------------------------------------------------------\n // Internals\n // -----------------------------------------------------------------------\n\n /** Lazy initialization — fetches tools from all connected clients. */\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) return;\n\n this.allTools = await this.fetchAllTools();\n await this.index.buildIndex(this.allTools);\n this.buildGroups();\n this.initialized = true;\n }\n\n /** Fetch tools from all connected MCP clients. */\n private async fetchAllTools(): Promise<IndexedTool[]> {\n const clients = this.getClients();\n const result: IndexedTool[] = [];\n\n for (const client of clients) {\n if (!client.isConnected()) continue;\n\n try {\n const { tools } = await client.listTools();\n const serverId =\n typeof client.getServerId === 'function' ? client.getServerId() ?? 'unknown' : 'unknown';\n const serverName =\n (typeof client.getServerName === 'function' ? client.getServerName() : undefined) ??\n serverId;\n const sessionId =\n typeof client.getSessionId === 'function' ? client.getSessionId() ?? 'unknown' : 'unknown';\n\n for (const tool of tools) {\n result.push({\n ...tool,\n serverName: serverName,\n sessionId,\n });\n }\n } catch (err) {\n console.warn('[ToolRouter] Failed to fetch tools from client:', err);\n }\n }\n\n return result;\n }\n\n /** Resolve the client input to a flat array of ToolClient instances. */\n private getClients(): ToolClient[] {\n if (Array.isArray(this.client)) {\n return this.client;\n }\n if (typeof (this.client as ToolClientProvider).getClients === 'function') {\n return (this.client as ToolClientProvider).getClients();\n }\n // Single client\n return [this.client as unknown as ToolClient];\n }\n\n /** Build group map from custom config or auto-detect from server names. */\n private buildGroups(): void {\n this.groupsMap.clear();\n\n if (this.customGroups) {\n // Explicit groups\n for (const [name, tools] of Object.entries(this.customGroups)) {\n this.groupsMap.set(name, {\n tools,\n active: this.activeGroups.size === 0 || this.activeGroups.has(name),\n });\n }\n } else {\n // Auto-group by server name\n const serverTools = new Map<string, string[]>();\n for (const tool of this.allTools) {\n const group = tool.serverName;\n if (!serverTools.has(group)) {\n serverTools.set(group, []);\n }\n serverTools.get(group)!.push(tool.name);\n }\n\n for (const [serverName, tools] of serverTools) {\n this.groupsMap.set(serverName, {\n tools,\n active: this.activeGroups.size === 0 || this.activeGroups.has(serverName),\n });\n }\n }\n }\n\n /** Return only tools belonging to currently active groups. */\n private getGroupFilteredTools(): Tool[] {\n const activeToolNames = new Set<string>();\n for (const [, info] of this.groupsMap) {\n if (info.active) {\n for (const name of info.tools) {\n activeToolNames.add(name);\n }\n }\n }\n\n const filtered = this.allTools.filter((t) => activeToolNames.has(t.name));\n\n if (this.compactSchemas) {\n return filtered.slice(0, this.maxTools).map((t) => {\n const compact = SchemaCompressor.toCompact(t);\n return {\n name: compact.name,\n description:\n (compact.description ?? '') +\n (compact.parameterHint ? ` Parameters: ${compact.parameterHint}` : ''),\n inputSchema: { type: 'object' as const, properties: {} },\n };\n });\n }\n\n return filtered.slice(0, this.maxTools);\n }\n\n /** The 4 meta-tool definitions exposed in `search` strategy. */\n private getMetaToolDefinitions(): Tool[] {\n return [\n createSearchToolDefinition(),\n createRegexSearchToolDefinition(),\n createGetSchemaToolDefinition(),\n createExecuteToolDefinition(),\n ];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/shared/events.ts","../../src/shared/constants.ts","../../src/shared/errors.ts","../../src/shared/types.ts","../../src/shared/utils.ts","../../src/shared/tool-utils.ts","../../src/shared/tool-index.ts","../../src/shared/schema-compressor.ts","../../src/shared/meta-tools.ts","../../src/shared/tool-router.ts"],"names":["customAlphabet","b","text"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Simple event emitter pattern for MCP connection events\n * Inspired by Cloudflare's agents pattern but adapted for serverless\n */\n\nexport type Disposable = {\n dispose(): void;\n};\n\nexport type Event<T> = (listener: (event: T) => void) => Disposable;\n\n/**\n * Event emitter class for type-safe event handling\n * Similar to Cloudflare's Emitter but simplified for our use case\n */\nexport class Emitter<T> {\n private listeners: Set<(event: T) => void> = new Set();\n\n /**\n * Subscribe to events\n * @param listener - Callback function to handle events\n * @returns Disposable to unsubscribe\n */\n get event(): Event<T> {\n return (listener: (event: T) => void) => {\n this.listeners.add(listener);\n return {\n dispose: () => {\n this.listeners.delete(listener);\n },\n };\n };\n }\n\n /**\n * Fire an event to all listeners\n * @param event - Event data to emit\n */\n fire(event: T): void {\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch (error) {\n console.error('[Emitter] Error in event listener:', error);\n }\n }\n }\n\n /**\n * Clear all listeners\n */\n dispose(): void {\n this.listeners.clear();\n }\n\n /**\n * Get number of active listeners\n */\n get listenerCount(): number {\n return this.listeners.size;\n }\n}\n\n/**\n * Connection state types matching your existing ConnectionStatus\n * Extended with more granular states for better observability\n */\nexport type McpConnectionState =\n | 'DISCONNECTED' // Not connected\n | 'CONNECTING' // Establishing transport connection to MCP server\n | 'AUTHENTICATING' // OAuth flow in progress\n | 'AUTHENTICATED' // OAuth complete, pre-connect\n | 'DISCOVERING' // Discovering server capabilities (tools, resources, prompts)\n | 'CONNECTED' // Transport connection established\n | 'READY' // Fully connected and ready to use\n | 'VALIDATING' // Validating existing session\n | 'RECONNECTING' // Attempting to reconnect\n | 'INITIALIZING' // Initializing session or connection\n | 'FAILED'; // Connection error at some point\n\n/**\n * MCP Connection Event Types\n * Discriminated union for type-safe event handling\n */\nexport type McpConnectionEvent =\n | {\n type: 'state_changed';\n sessionId: string;\n serverId: string;\n serverName: string;\n serverUrl: string;\n createdAt?: number;\n state: McpConnectionState;\n previousState: McpConnectionState;\n timestamp: number;\n }\n | {\n type: 'tools_discovered';\n sessionId: string;\n serverId: string;\n toolCount: number;\n tools: any[];\n timestamp: number;\n }\n | {\n type: 'auth_required';\n sessionId: string;\n serverId: string;\n authUrl: string;\n timestamp: number;\n }\n | {\n type: 'error';\n sessionId: string;\n serverId: string;\n error: string;\n errorType: 'connection' | 'auth' | 'validation' | 'unknown';\n timestamp: number;\n }\n | {\n type: 'disconnected';\n sessionId: string;\n serverId: string;\n reason?: string;\n timestamp: number;\n }\n | {\n type: 'progress';\n sessionId: string;\n serverId: string;\n message: string;\n timestamp: number;\n };\n\n/**\n * Event fired when a tool execution returns a UI resource URI\n */\nexport interface McpAppsUIEvent {\n type: 'mcp-apps-ui';\n sessionId: string;\n resourceUri: string;\n toolName: string;\n result: unknown;\n timestamp: number;\n}\n\n/**\n * Observability event for debugging and monitoring\n */\nexport interface McpObservabilityEvent {\n type?: string;\n level?: 'debug' | 'info' | 'warn' | 'error';\n message?: string;\n displayMessage?: string;\n sessionId?: string;\n serverId?: string;\n payload?: Record<string, any>;\n metadata?: Record<string, any>; // Kept for backward compatibility\n timestamp: number;\n id?: string;\n}\n\n/**\n * DisposableStore for managing multiple disposables\n * Useful for cleanup in React hooks\n */\nexport class DisposableStore {\n private disposables: Set<Disposable> = new Set();\n\n add(disposable: Disposable): void {\n this.disposables.add(disposable);\n }\n\n dispose(): void {\n for (const disposable of this.disposables) {\n disposable.dispose();\n }\n this.disposables.clear();\n }\n}\n","/**\n * Centralized constants for MCP Redis library\n * Eliminates magic numbers and enables consistent configuration\n */\n\n// Redis TTL and Session Management\nexport const SESSION_TTL_SECONDS = 43200; // 12 hours\nexport const STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes for OAuth state\n\n// Heartbeat and Connection\nexport const DEFAULT_HEARTBEAT_INTERVAL_MS = 30000; // 30 seconds\n\n// Redis Key Prefixes\nexport const REDIS_KEY_PREFIX = 'mcp:session:';\n\n// Token Management\nexport const TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000; // 5 minute buffer before expiry\n\n// Client Information\nexport const DEFAULT_CLIENT_NAME = 'MCP Assistant';\nexport const DEFAULT_CLIENT_URI = 'https://mcp-assistant.in';\nexport const DEFAULT_LOGO_URI = 'https://mcp-assistant.in/logo.svg';\nexport const DEFAULT_POLICY_URI = 'https://mcp-assistant.in/privacy';\nexport const SOFTWARE_ID = '@mcp-ts';\nexport const SOFTWARE_VERSION = '1.3.4';\n\n// MCP Client Configuration\nexport const MCP_CLIENT_NAME = 'mcp-ts-oauth-client';\nexport const MCP_CLIENT_VERSION = '2.0';\n","/**\n * Standardized error classes for MCP Redis library\n * Provides consistent error handling across the codebase\n */\n\n/**\n * Base error class for all MCP-related errors\n */\nexport class McpError extends Error {\n constructor(\n public readonly code: string,\n message: string,\n public readonly cause?: Error\n ) {\n super(message);\n this.name = 'McpError';\n // Maintain proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n ...(this.cause ? { cause: this.cause.message } : {}),\n };\n }\n}\n\n/**\n * Thrown when OAuth authorization is required\n */\nexport class UnauthorizedError extends McpError {\n constructor(message: string = 'OAuth authorization required', cause?: Error) {\n super('UNAUTHORIZED', message, cause);\n this.name = 'UnauthorizedError';\n }\n}\n\n/**\n * Thrown when connection to MCP server fails\n */\nexport class ConnectionError extends McpError {\n constructor(message: string, cause?: Error) {\n super('CONNECTION_ERROR', message, cause);\n this.name = 'ConnectionError';\n }\n}\n\n/**\n * Thrown when session is not found or expired\n */\nexport class SessionNotFoundError extends McpError {\n constructor(sessionId: string, cause?: Error) {\n super('SESSION_NOT_FOUND', `Session not found: ${sessionId}`, cause);\n this.name = 'SessionNotFoundError';\n }\n}\n\n/**\n * Thrown when session validation fails\n */\nexport class SessionValidationError extends McpError {\n constructor(message: string, cause?: Error) {\n super('SESSION_VALIDATION_ERROR', message, cause);\n this.name = 'SessionValidationError';\n }\n}\n\n/**\n * Thrown when authentication fails\n */\nexport class AuthenticationError extends McpError {\n constructor(message: string, cause?: Error) {\n super('AUTH_ERROR', message, cause);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Thrown when OAuth state validation fails\n */\nexport class InvalidStateError extends McpError {\n constructor(message: string = 'Invalid OAuth state', cause?: Error) {\n super('INVALID_STATE', message, cause);\n this.name = 'InvalidStateError';\n }\n}\n\n/**\n * Thrown when client is not connected\n */\nexport class NotConnectedError extends McpError {\n constructor(message: string = 'Not connected to server', cause?: Error) {\n super('NOT_CONNECTED', message, cause);\n this.name = 'NotConnectedError';\n }\n}\n\n/**\n * Thrown when required configuration is missing\n */\nexport class ConfigurationError extends McpError {\n constructor(message: string, cause?: Error) {\n super('CONFIGURATION_ERROR', message, cause);\n this.name = 'ConfigurationError';\n }\n}\n\n/**\n * Thrown when tool execution fails\n */\nexport class ToolExecutionError extends McpError {\n constructor(toolName: string, message: string, cause?: Error) {\n super('TOOL_EXECUTION_ERROR', `Tool '${toolName}' failed: ${message}`, cause);\n this.name = 'ToolExecutionError';\n }\n}\n\n/**\n * RPC error codes for SSE communication\n */\nexport const RpcErrorCodes = {\n EXECUTION_ERROR: 'EXECUTION_ERROR',\n MISSING_IDENTITY: 'MISSING_IDENTITY',\n UNAUTHORIZED: 'UNAUTHORIZED',\n NO_CONNECTION: 'NO_CONNECTION',\n UNKNOWN_METHOD: 'UNKNOWN_METHOD',\n INVALID_PARAMS: 'INVALID_PARAMS',\n} as const;\n\nexport type RpcErrorCode = typeof RpcErrorCodes[keyof typeof RpcErrorCodes];\n","/**\n * Type definitions for MCP operations\n */\n\nimport { Tool, CallToolResult } from '@modelcontextprotocol/sdk/types.js';\n\n// ---------------------------------------------------------------------------\n// Core Capability Interfaces\n// ---------------------------------------------------------------------------\n\n/**\n * A client that can list and execute MCP tools.\n *\n * This is the structural interface that `ToolRouter`, adapters, and other\n * consumers use to interact with any MCP client implementation.\n * Both `MCPClient` and `createMcpClient()` satisfy this interface.\n */\nexport interface ToolClient {\n isConnected(): boolean;\n listTools(): Promise<{ tools: Tool[] }>;\n callTool(name: string, args: Record<string, unknown>): Promise<any>;\n getServerId?(): string | undefined;\n getServerName?(): string | undefined;\n getSessionId?(): string;\n}\n\n/**\n * A provider that manages multiple `ToolClient` instances.\n *\n * `MultiSessionClient` satisfies this interface. Pass it directly\n * to `ToolRouter` or adapters to aggregate tools from all connected servers.\n */\nexport interface ToolClientProvider {\n getClients(): ToolClient[];\n}\n\n// Connect API types\nexport interface ConnectRequest {\n serverUrl: string;\n callbackUrl: string;\n}\n\nexport interface ConnectSuccessResponse {\n success: true;\n sessionId: string;\n}\n\nexport interface ConnectAuthRequiredResponse {\n requiresAuth: true;\n authUrl: string;\n sessionId: string;\n}\n\nexport interface ConnectErrorResponse {\n error: string;\n}\n\nexport type ConnectResponse =\n | ConnectSuccessResponse\n | ConnectAuthRequiredResponse\n | ConnectErrorResponse;\n\n// Callback API types\nexport interface CallbackSuccessResponse {\n success: true;\n message: string;\n}\n\nexport interface CallbackErrorResponse {\n error: string;\n}\n\nexport type CallbackResponse = CallbackSuccessResponse | CallbackErrorResponse;\n\n// Disconnect API types\nexport interface DisconnectRequest {\n sessionId: string;\n}\n\nexport interface DisconnectSuccessResponse {\n success: true;\n message: string;\n}\n\nexport interface DisconnectErrorResponse {\n error: string;\n}\n\nexport type DisconnectResponse =\n | DisconnectSuccessResponse\n | DisconnectErrorResponse;\n\n// List Tools API types\nexport interface ListToolsSuccessResponse {\n tools: Tool[];\n}\n\nexport interface ListToolsErrorResponse {\n error: string;\n}\n\nexport type ListToolsResponse =\n | ListToolsSuccessResponse\n | ListToolsErrorResponse;\n\n// Call Tool API types\nexport interface CallToolRequest {\n sessionId: string;\n toolName: string;\n toolArgs: Record<string, unknown>;\n}\n\nexport interface CallToolSuccessResponse {\n content: Array<{\n type: string;\n text?: string;\n [key: string]: unknown;\n }>;\n isError: boolean;\n}\n\nexport interface CallToolErrorResponse {\n error: string;\n}\n\nexport type CallToolResponse =\n | CallToolSuccessResponse\n | CallToolErrorResponse;\n\n// Helper type guards\nexport function isConnectSuccess(\n response: ConnectResponse\n): response is ConnectSuccessResponse {\n return 'success' in response && response.success === true;\n}\n\nexport function isConnectAuthRequired(\n response: ConnectResponse\n): response is ConnectAuthRequiredResponse {\n return 'requiresAuth' in response && response.requiresAuth === true;\n}\n\nexport function isConnectError(\n response: ConnectResponse\n): response is ConnectErrorResponse {\n return 'error' in response;\n}\n\nexport function isListToolsSuccess(\n response: ListToolsResponse\n): response is ListToolsSuccessResponse {\n return 'tools' in response;\n}\n\nexport function isCallToolSuccess(\n response: CallToolResponse\n): response is CallToolSuccessResponse {\n return 'content' in response;\n}\n\n// Generic tool info type\nexport type ToolInfo = {\n name: string;\n description?: string;\n inputSchema?: unknown;\n};\n\n// Transport type\nexport type TransportType = 'sse' | 'streamable_http';\n\n// SSE/RPC types\nexport type McpRpcMethod =\n | 'connect'\n | 'disconnect'\n | 'listTools'\n | 'callTool'\n | 'getSessions'\n | 'restoreSession'\n | 'finishAuth'\n | 'listPrompts'\n | 'getPrompt'\n | 'listResources'\n | 'readResource';\n\nexport interface McpRpcRequest {\n id: string;\n method: McpRpcMethod;\n params?: McpRpcParams;\n}\n\nexport interface McpRpcResponse<T = unknown> {\n id: string;\n result?: T;\n error?: {\n code: string;\n message: string;\n };\n}\n\n// RPC Parameter Types\nexport interface ConnectParams {\n serverId?: string; // Optional - generated server-side if not provided\n serverName: string;\n serverUrl: string;\n callbackUrl: string;\n transportType?: TransportType;\n}\n\nexport interface DisconnectParams {\n sessionId: string;\n}\n\nexport interface SessionParams {\n sessionId: string;\n}\n\nexport interface CallToolParams {\n sessionId: string;\n toolName: string;\n toolArgs: Record<string, unknown>;\n}\n\nexport interface GetPromptParams {\n sessionId: string;\n name: string;\n args?: Record<string, string>;\n}\n\nexport interface ReadResourceParams {\n sessionId: string;\n uri: string;\n}\n\nexport interface FinishAuthParams {\n sessionId: string;\n code: string;\n}\n\nexport type McpRpcParams =\n | ConnectParams\n | DisconnectParams\n | SessionParams\n | CallToolParams\n | GetPromptParams\n | ReadResourceParams\n | FinishAuthParams\n | undefined;\n\n// RPC Result Types\nexport interface SessionInfo {\n sessionId: string;\n serverId?: string;\n serverName?: string;\n serverUrl: string;\n transport: TransportType;\n createdAt: number;\n /**\n * Session readiness for auto-restore.\n * false means auth is pending and should be resumed explicitly by user action.\n */\n active?: boolean;\n}\n\nexport interface SessionListResult {\n sessions: SessionInfo[];\n}\n\nexport interface ConnectResult {\n sessionId: string;\n success: boolean;\n}\n\nexport interface DisconnectResult {\n success: boolean;\n}\n\nexport interface RestoreSessionResult {\n success: boolean;\n toolCount: number;\n}\n\nexport interface FinishAuthResult {\n success: boolean;\n toolCount: number;\n}\n\nexport interface ListToolsRpcResult {\n tools: Tool[];\n}\n\nexport interface ListPromptsResult {\n prompts: Array<{\n name: string;\n description?: string;\n arguments?: Array<{\n name: string;\n description?: string;\n required?: boolean;\n }>;\n }>;\n}\n\nexport interface ListResourcesResult {\n resources: Array<{\n uri: string;\n name: string;\n description?: string;\n mimeType?: string;\n }>;\n}\n\nexport type { CallToolResult };\n","import { customAlphabet } from 'nanoid';\n\n/** first char: letters only (required by OpenAI) */\nconst firstChar = customAlphabet(\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',\n 1\n);\n\n/** remaining chars: alphanumeric */\nconst rest = customAlphabet(\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',\n 11\n);\n\n/**\n * Sanitize server name to create a valid server label\n * Must start with a letter and contain only letters, digits, '-' and '_'\n */\nexport function sanitizeServerLabel(name: string): string {\n let sanitized = name\n .replace(/[^a-zA-Z0-9-_]/g, '_')\n .replace(/_{2,}/g, '_')\n .toLowerCase();\n\n if (!/^[a-zA-Z]/.test(sanitized)) {\n sanitized = 's_' + sanitized;\n }\n\n return sanitized;\n}\n\n/**\n * Generates a standard 12-character session ID compliant with external tool restrictions.\n * First character is always a letter.\n */\nexport function generateSessionId(): string {\n return firstChar() + rest();\n}\n","/**\n * Utility functions for working with MCP tool metadata\n */\n\nimport type { ToolInfo } from './types.js';\n\nexport interface ToolUiConfig {\n resourceUri: string;\n sessionId: string;\n}\n\n/**\n * Extract UI resource URI from tool metadata\n *\n * @param tool - The tool to extract UI config from\n * @returns The resource URI if available, undefined otherwise\n *\n * @example\n * const uri = getToolUiResourceUri(tool);\n * if (uri) {\n * // Tool has UI configuration\n * }\n */\nexport function getToolUiResourceUri(tool: ToolInfo): string | undefined {\n const meta = (tool as any)._meta;\n if (!meta?.ui) return undefined;\n\n const ui = meta.ui;\n if (typeof ui !== \"object\" || !ui) return undefined;\n\n // Check visibility filter - skip if explicitly hidden from app\n if (ui.visibility && !ui.visibility.includes(\"app\")) return undefined;\n\n // Support both 'uri' and 'resourceUri' field names for flexibility\n return typeof ui.resourceUri === \"string\"\n ? ui.resourceUri\n : typeof ui.uri === \"string\"\n ? ui.uri\n : undefined;\n}\n\n/**\n * Find a tool by name within connections\n *\n * @param connections - Array of MCP connections\n * @param toolName - Name of the tool to find\n * @returns The tool if found, undefined otherwise\n *\n * @example\n * const tool = findToolByName(connections, \"get_weather\");\n */\nexport function findToolByName(\n connections: Array<{ tools: ToolInfo[] }>,\n toolName: string\n): ToolInfo | undefined {\n for (const conn of connections) {\n const tool = conn.tools.find((t) => t.name === toolName);\n if (tool) return tool;\n }\n return undefined;\n}\n","/**\n * ToolIndex — Lightweight in-memory search index for MCP tool discovery.\n *\n * Supports two search methods:\n * • BM25 – Okapi BM25 ranking over tokenized tool metadata (zero external deps)\n * • regex – Pattern matching against tool names, descriptions, and parameters\n * • embedding – (optional) cosine-similarity over caller-supplied vectors,\n * blended with BM25 scores\n *\n * @packageDocumentation\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\n\n// ---------------------------------------------------------------------------\n// Public Types\n// ---------------------------------------------------------------------------\n\n/** Compact summary returned by search — intentionally lightweight. */\nexport interface ToolSummary {\n /** Fully qualified tool name (e.g. \"tool_github_create_pr\") */\n name: string;\n /** Human-readable description */\n description: string;\n /** Server that owns this tool */\n serverName: string;\n /** Unique ID of the server */\n serverId: string;\n /** Session the tool belongs to */\n sessionId: string;\n /** Estimated token cost of the full inputSchema */\n estimatedTokens: number;\n}\n\n/** A tool with routing metadata attached during indexing. */\nexport interface IndexedTool extends Tool {\n sessionId: string;\n serverId: string;\n serverName: string;\n}\n\n/**\n * An optional embedding function supplied by the consumer.\n * Should accept an array of strings and return a matching array of\n * float-number arrays (one embedding vector per input string).\n */\nexport type EmbedFn = (texts: string[]) => Promise<number[][]>;\n\nexport interface ToolIndexOptions {\n /**\n * Custom embedding function for semantic search.\n * When provided, `search()` uses cosine-similarity in addition to keywords.\n * @example\n * ```ts\n * import { embed } from 'ai';\n * const embedFn: EmbedFn = async (texts) => {\n * const { embeddings } = await embed({ model: openai('text-embedding-3-small'), values: texts });\n * return embeddings;\n * };\n * ```\n */\n embedFn?: EmbedFn;\n\n /**\n * Relative weight of keyword score vs embedding score when both are active.\n * 0 = embedding only · 1 = keyword only · 0.4 (default) blends both.\n * @default 0.4\n */\n keywordWeight?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Token Estimation\n// ---------------------------------------------------------------------------\n\n/**\n * Character-class weights for accurate-ish token estimation without a real\n * tokenizer. Empirically calibrated against cl100k_base on typical JSON\n * Schema payloads.\n *\n * | Char class | Approx chars per token |\n * |--------------------|------------------------|\n * | Whitespace / punct | 1–2 |\n * | English words | ~4 |\n * | JSON keys/values | ~3.5 |\n *\n * We walk the string once and accumulate a weighted character count, then\n * divide by a calibrated divisor.\n */\nconst CALIBRATION_DIVISOR = 3.6;\n\nfunction classifyChar(ch: string): number {\n const code = ch.charCodeAt(0);\n // whitespace / common JSON structural chars → high token density\n if (code <= 0x20 || ch === '{' || ch === '}' || ch === '[' || ch === ']' || ch === ':' || ch === ',') return 1.0;\n // digits and symbols\n if (code >= 0x21 && code <= 0x2f) return 1.5;\n if (code >= 0x30 && code <= 0x39) return 2.0;\n // uppercase (often JSON keys)\n if (code >= 0x41 && code <= 0x5a) return 3.5;\n // lowercase (natural language in descriptions)\n if (code >= 0x61 && code <= 0x7a) return 4.0;\n // everything else (unicode, emojis, etc.)\n return 2.5;\n}\n\n// ---------------------------------------------------------------------------\n// ToolIndex\n// ---------------------------------------------------------------------------\n\nexport class ToolIndex {\n /** All indexed tools keyed by name (supports duplicates). */\n private tools = new Map<string, IndexedTool[]>();\n\n /** Precomputed lightweight summaries keyed by document. */\n private toolSummaries = new Map<string, ToolSummary>();\n\n /** Pre-computed search text for keyword matching (lowercase), keyed by document. */\n private searchTexts = new Map<string, string>();\n\n /** Pre-computed IDF values per token (computed once on build). */\n private idf = new Map<string, number>();\n\n /** Per-tool TF vectors (Map<token, tf>). */\n private tfVectors = new Map<string, Map<string, number>>();\n\n /** Optional: pre-computed embedding vectors per tool. */\n private embeddings = new Map<string, number[]>();\n\n /** BM25: document lengths in tokens for each tool. */\n private docLengths = new Map<string, number>();\n\n /** BM25: average document length across the entire index. */\n private avgDocLength = 0;\n\n /** Cached total estimated token cost across all indexed tools. */\n private totalTokenCost = 0;\n\n private options: Required<ToolIndexOptions>;\n\n constructor(options: ToolIndexOptions = {}) {\n this.options = {\n embedFn: options.embedFn ?? (undefined as unknown as EmbedFn),\n keywordWeight: options.keywordWeight ?? 0.4,\n };\n }\n\n // -----------------------------------------------------------------------\n // Indexing\n // -----------------------------------------------------------------------\n\n /**\n * Build (or rebuild) the index from the given tool set.\n * Call this after connecting / reconnecting to MCP servers.\n */\n async buildIndex(tools: IndexedTool[]): Promise<void> {\n this.tools.clear();\n this.toolSummaries.clear();\n this.searchTexts.clear();\n this.idf.clear();\n this.tfVectors.clear();\n this.embeddings.clear();\n this.docLengths.clear();\n this.avgDocLength = 0;\n this.totalTokenCost = 0;\n\n // 1. Populate tool map + search text\n const allTokenSets: Map<string, Set<string>> = new Map();\n let totalLength = 0;\n\n for (const tool of tools) {\n const docKey = this.getDocumentKey(tool);\n\n if (!this.tools.has(tool.name)) {\n this.tools.set(tool.name, []);\n }\n this.tools.get(tool.name)!.push(tool);\n const estimatedTokens = ToolIndex.estimateTokens(tool);\n this.toolSummaries.set(docKey, {\n name: tool.name,\n description: tool.description ?? '',\n serverName: tool.serverName,\n serverId: tool.serverId,\n sessionId: tool.sessionId,\n estimatedTokens,\n });\n this.totalTokenCost += estimatedTokens;\n\n const text = this.buildSearchableText(tool).toLowerCase();\n this.searchTexts.set(docKey, text);\n\n const tokens = this.tokenize(text);\n const tf = new Map<string, number>();\n const uniqueTokens = new Set<string>();\n\n for (const tok of tokens) {\n tf.set(tok, (tf.get(tok) ?? 0) + 1);\n uniqueTokens.add(tok);\n }\n\n // Normalize TF\n const maxTf = Math.max(...tf.values(), 1);\n for (const [k, v] of tf) {\n tf.set(k, v / maxTf);\n }\n\n this.tfVectors.set(docKey, tf);\n allTokenSets.set(docKey, uniqueTokens);\n\n const length = tokens.length;\n this.docLengths.set(docKey, length);\n totalLength += length;\n }\n\n // Compute average document length\n this.avgDocLength = totalLength / (tools.length || 1);\n\n // 2. Compute IDF\n const totalDocs = tools.length || 1;\n const dfCounts = new Map<string, number>();\n\n for (const tokenSet of allTokenSets.values()) {\n for (const tok of tokenSet) {\n dfCounts.set(tok, (dfCounts.get(tok) ?? 0) + 1);\n }\n }\n\n for (const [tok, df] of dfCounts) {\n this.idf.set(tok, Math.log(totalDocs / df) + 1);\n }\n\n // 3. Build embeddings if an embedFn was provided\n if (this.options.embedFn) {\n const names = [...this.searchTexts.keys()];\n const texts = names.map((n) => this.searchTexts.get(n)!);\n\n try {\n const vectors = await this.options.embedFn(texts);\n for (let i = 0; i < names.length; i++) {\n if (vectors[i]) {\n this.embeddings.set(names[i], vectors[i]);\n }\n }\n } catch (err) {\n console.warn('[ToolIndex] Embedding generation failed, falling back to keyword-only search:', err);\n }\n }\n }\n\n // -----------------------------------------------------------------------\n // Search\n // -----------------------------------------------------------------------\n\n /**\n * Search the index and return the top-K most relevant tools.\n *\n * When an `embedFn` is configured the final score is a weighted blend of\n * keyword TF-IDF similarity and embedding cosine-similarity:\n *\n * `score = keywordWeight × keyword_score + (1 - keywordWeight) × cosine_score`\n */\n async search(query: string, topK = 5): Promise<ToolSummary[]> {\n if (this.tools.size === 0) return [];\n\n const queryLower = query.toLowerCase().trim();\n\n // Fast path: Exact tool name match (supports duplicate names across servers)\n const exactMatches = [...this.toolSummaries.values()].filter(\n (summary) => summary.name.toLowerCase() === queryLower\n );\n if (exactMatches.length > 0) {\n return exactMatches.slice(0, topK);\n }\n\n // Fast path: MCP prefix match (e.g. \"mcp__github\")\n if (queryLower.startsWith('mcp__') && queryLower.length > 5) {\n const prefixMatches = [...this.toolSummaries.values()]\n .filter((t) => t.name.toLowerCase().startsWith(queryLower))\n .slice(0, topK);\n if (prefixMatches.length > 0) return prefixMatches;\n }\n\n const queryTermsRaw = queryLower.split(/\\s+/).filter((t) => t.length > 0);\n const requiredTerms: string[] = [];\n const optionalTerms: string[] = [];\n\n for (const term of queryTermsRaw) {\n if (term.startsWith('+') && term.length > 1) {\n requiredTerms.push(term.slice(1));\n } else {\n optionalTerms.push(term);\n }\n }\n\n const allScoringTerms =\n requiredTerms.length > 0 ? [...requiredTerms, ...optionalTerms] : queryTermsRaw;\n const normalizedQueryText = allScoringTerms.join(' ').trim();\n const queryTokens = this.tokenize(allScoringTerms.join(' '));\n\n // Pre-filter: only keep documents that contain ALL required terms\n const candidateKeys = new Set<string>();\n for (const docKey of this.toolSummaries.keys()) {\n if (requiredTerms.length > 0) {\n const text = this.searchTexts.get(docKey) || '';\n const summary = this.toolSummaries.get(docKey)!;\n const nameLower = summary.name.toLowerCase();\n const matchesAll = requiredTerms.every(\n (term) => text.includes(term) || nameLower.includes(term)\n );\n if (!matchesAll) continue;\n }\n candidateKeys.add(docKey);\n }\n\n // 1. Keyword scores (BM25)\n const keywordScores = new Map<string, number>();\n\n const k1 = 1.2;\n const b = 0.75;\n\n for (const docKey of candidateKeys) {\n const docTf = this.tfVectors.get(docKey);\n if (!docTf) continue;\n \n const summary = this.toolSummaries.get(docKey)!;\n\n let score = 0;\n const docLen = this.docLengths.get(docKey) ?? 0;\n\n for (const tok of queryTokens) {\n const tfVal = docTf.get(tok) ?? 0;\n if (tfVal === 0) continue;\n\n const idf = this.idf.get(tok) ?? 0;\n // BM25 formula:\n // score = idf * (tf * (k1 + 1)) / (tf + k1 * (1 - b + b * (docLen / avgDocLength)))\n const numerator = tfVal * (k1 + 1);\n const denominator = tfVal + k1 * (1 - b + b * (docLen / this.avgDocLength));\n\n score += idf * (numerator / denominator);\n }\n\n // Name heuristics: give massive boosts for exact server/tool name matches\n const serverLower = (summary.serverName || summary.serverId || '').toLowerCase();\n const toolLower = summary.name.toLowerCase();\n\n for (const term of allScoringTerms) {\n if (serverLower.includes(term)) {\n score += 10;\n }\n if (toolLower.includes(term)) {\n score += 5;\n }\n }\n\n if (score > 0) {\n keywordScores.set(docKey, score);\n }\n }\n\n // 2. Embedding scores (optional)\n let embeddingScores: Map<string, number> | null = null;\n\n if (this.options.embedFn && this.embeddings.size > 0) {\n try {\n const [queryEmbedding] = await this.options.embedFn([normalizedQueryText]);\n if (queryEmbedding) {\n embeddingScores = new Map();\n for (const docKey of candidateKeys) {\n const vec = this.embeddings.get(docKey);\n if (vec) {\n embeddingScores.set(docKey, this.cosineSimilarity(queryEmbedding, vec));\n }\n }\n }\n } catch {\n // Silently fall back to keyword only for this query\n }\n }\n\n // 3. Blend scores\n const kw = this.options.keywordWeight;\n const finalScores: Array<{ docKey: string; score: number }> = [];\n\n for (const docKey of candidateKeys) {\n const kwScore = keywordScores.get(docKey) ?? 0;\n const embScore = embeddingScores?.get(docKey) ?? 0;\n\n const score = embeddingScores ? kw * kwScore + (1 - kw) * embScore : kwScore;\n\n if (score > 0) {\n finalScores.push({ docKey, score });\n }\n }\n\n // 4. Sort and return top-K\n finalScores.sort((a, b) => b.score - a.score);\n\n return finalScores.slice(0, topK).map(({ docKey }) => {\n return this.toolSummaries.get(docKey)!;\n });\n }\n\n /**\n * Search tools using a regex pattern.\n * Matches against name, description, and parameter metadata.\n */\n searchRegex(pattern: string, topK = 5): ToolSummary[] {\n if (this.tools.size === 0) return [];\n\n try {\n // Handle Anthropic-style (?i) case-insensitive flag which JS doesn't support natively in string\n let flags = '';\n let cleanPattern = pattern;\n if (pattern.includes('(?i)')) {\n flags = 'i';\n cleanPattern = pattern.replace(/\\(\\?i\\)/g, '');\n }\n\n const regex = new RegExp(cleanPattern, flags || undefined);\n const matches: Array<{ docKey: string; score: number }> = [];\n\n for (const [docKey, text] of this.searchTexts) {\n const tool = this.toolSummaries.get(docKey);\n if (!tool) continue;\n\n if (regex.test(text) || regex.test(tool.name)) {\n // Use a simple heuristic for ranking regex matches: \n // 1. Exact name match (highest)\n // 2. Name starts with pattern\n // 3. Name contains pattern\n // 4. Description contains pattern (lowest)\n let score = 1;\n if (tool.name === cleanPattern) score = 10;\n else if (tool.name.startsWith(cleanPattern)) score = 5;\n else if (tool.name.toLowerCase().includes(cleanPattern.toLowerCase())) score = 2;\n\n matches.push({ docKey, score });\n }\n }\n\n matches.sort((a, b) => b.score - a.score);\n\n return matches.slice(0, topK).map(({ docKey }) => {\n return this.toolSummaries.get(docKey)!;\n });\n } catch (err) {\n console.warn('[ToolIndex] Regex search failed:', err);\n return [];\n }\n }\n\n // -----------------------------------------------------------------------\n // Accessors\n // -----------------------------------------------------------------------\n\n /**\n * Get tool definition(s) by name.\n * If namespace is provided, it tries to match sessionId or serverName.\n */\n getTool(name: string, namespace?: string): IndexedTool[] {\n const list = this.tools.get(name) ?? [];\n if (!namespace) return list;\n\n return list.filter((t) => t.sessionId === namespace || t.serverId === namespace);\n }\n\n /** All indexed tool names. */\n getToolNames(): string[] {\n return [...this.tools.keys()];\n }\n\n /** Number of indexed tools (including duplicates). */\n get size(): number {\n let count = 0;\n for (const list of this.tools.values()) {\n count += list.length;\n }\n return count;\n }\n\n /** Total estimated token cost of all indexed tool schemas. */\n getTotalTokenCost(): number {\n return this.totalTokenCost;\n }\n\n // -----------------------------------------------------------------------\n // Static Helpers\n // -----------------------------------------------------------------------\n\n /**\n * Estimate token count of a tool's full schema (name + description + inputSchema).\n *\n * Uses character-class weighted counting calibrated against cl100k_base.\n * Accuracy is typically within ±10% for JSON Schema payloads.\n */\n static estimateTokens(tool: Tool): number {\n const parts: string[] = [tool.name];\n if (tool.description) parts.push(tool.description);\n if (tool.inputSchema) parts.push(JSON.stringify(tool.inputSchema));\n\n const text = parts.join(' ');\n let weightedLen = 0;\n\n for (let i = 0; i < text.length; i++) {\n weightedLen += 1 / classifyChar(text[i]);\n }\n\n return Math.ceil(weightedLen / (1 / CALIBRATION_DIVISOR));\n }\n\n // -----------------------------------------------------------------------\n // Internals\n // -----------------------------------------------------------------------\n\n /** Build a single searchable string from tool metadata. */\n private buildSearchableText(tool: Tool): string {\n const parts: string[] = [tool.name];\n if (tool.description) parts.push(tool.description);\n\n // Include property names and descriptions from schema\n if (tool.inputSchema && typeof tool.inputSchema === 'object') {\n const schema = tool.inputSchema as Record<string, unknown>;\n const props = schema.properties as Record<string, { description?: string }> | undefined;\n if (props) {\n for (const [key, val] of Object.entries(props)) {\n parts.push(key);\n if (val && typeof val === 'object' && val.description) {\n parts.push(val.description);\n }\n }\n }\n }\n\n return parts.join(' ');\n }\n\n private getDocumentKey(tool: IndexedTool): string {\n return `${tool.sessionId}::${tool.serverId}::${tool.name}`;\n }\n\n /** Simple whitespace + camelCase + snake_case tokenizer. */\n private tokenize(text: string): string[] {\n return text\n // Split camelCase: \"getWeather\" → \"get Weather\"\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n // Split snake_case / kebab-case\n .replace(/[_-]/g, ' ')\n // Remove non-alphanumeric (except spaces)\n .replace(/[^a-z0-9\\s]/g, '')\n // Split on whitespace\n .split(/\\s+/)\n .filter((t) => t.length > 1); // drop single-char noise\n }\n\n /** Cosine similarity between two vectors. */\n private cosineSimilarity(a: number[], b: number[]): number {\n const len = Math.min(a.length, b.length);\n let dot = 0;\n let magA = 0;\n let magB = 0;\n\n for (let i = 0; i < len; i++) {\n dot += a[i] * b[i];\n magA += a[i] * a[i];\n magB += b[i] * b[i];\n }\n\n const denom = Math.sqrt(magA) * Math.sqrt(magB);\n return denom > 0 ? dot / denom : 0;\n }\n}\n","/**\n * SchemaCompressor — Utilities for reducing tool schema token overhead.\n *\n * Provides compact representations of tools (name + description only,\n * no inputSchema) and token savings estimation.\n *\n * @packageDocumentation\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport { ToolIndex } from './tool-index.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A minimal tool representation containing only what an LLM needs to\n * *decide whether* to use a tool. The full `inputSchema` is deferred.\n */\nexport interface CompactTool {\n name: string;\n description?: string;\n /**\n * Human-readable hint about the expected parameters.\n * e.g. \"(location: string, unit?: 'celsius' | 'fahrenheit')\"\n */\n parameterHint?: string;\n}\n\nexport interface CompressionStats {\n /** Estimated tokens for the *full* tool list. */\n fullTokens: number;\n /** Estimated tokens for the *compact* tool list. */\n compactTokens: number;\n /** Absolute token savings. */\n savedTokens: number;\n /** Percentage savings as a human-readable string, e.g. \"82.3%\". */\n savingsPercent: string;\n}\n\n// ---------------------------------------------------------------------------\n// SchemaCompressor\n// ---------------------------------------------------------------------------\n\nexport class SchemaCompressor {\n /**\n * Convert a full MCP Tool definition to a compact summary.\n *\n * The compact form omits `inputSchema` entirely and optionally generates\n * a short `parameterHint` from the schema's top-level properties.\n */\n static toCompact(tool: Tool): CompactTool {\n const compact: CompactTool = {\n name: tool.name,\n description: tool.description,\n };\n\n // Build parameter hint from schema\n if (tool.inputSchema && typeof tool.inputSchema === 'object') {\n const schema = tool.inputSchema as {\n properties?: Record<string, { type?: string; enum?: unknown[] }>;\n required?: string[];\n };\n\n if (schema.properties) {\n const required = new Set(schema.required ?? []);\n const parts: string[] = [];\n\n for (const [key, val] of Object.entries(schema.properties)) {\n const type = val?.type ?? 'any';\n const enumSuffix =\n val?.enum && Array.isArray(val.enum)\n ? `: ${val.enum.map((e) => `'${e}'`).join(' | ')}`\n : `: ${type}`;\n\n parts.push(required.has(key) ? `${key}${enumSuffix}` : `${key}?${enumSuffix}`);\n }\n\n if (parts.length > 0) {\n compact.parameterHint = `(${parts.join(', ')})`;\n }\n }\n }\n\n return compact;\n }\n\n /**\n * Convert an array of tools to compact form, optionally limiting the count.\n */\n static compactAll(tools: Tool[], options?: { maxTools?: number }): CompactTool[] {\n const limited = options?.maxTools ? tools.slice(0, options.maxTools) : tools;\n return limited.map((t) => SchemaCompressor.toCompact(t));\n }\n\n /**\n * Estimate token savings from using compact vs full tool schemas.\n */\n static estimateSavings(tools: Tool[]): CompressionStats {\n let fullTokens = 0;\n let compactTokens = 0;\n\n for (const tool of tools) {\n fullTokens += ToolIndex.estimateTokens(tool);\n\n // Compact form: name + description + parameterHint\n const compact = SchemaCompressor.toCompact(tool);\n const text = [compact.name, compact.description ?? '', compact.parameterHint ?? ''].join(' ');\n // Simple estimation for compact: ~4 chars per token for plain text\n compactTokens += Math.ceil(text.length / 4);\n }\n\n const saved = fullTokens - compactTokens;\n const pct = fullTokens > 0 ? ((saved / fullTokens) * 100).toFixed(1) : '0.0';\n\n return {\n fullTokens,\n compactTokens,\n savedTokens: saved,\n savingsPercent: `${pct}%`,\n };\n }\n}\n","/**\n * Meta-tools — Injectable tool definitions that let the LLM discover and\n * load MCP tools on-demand, following Anthropic's Tool Search pattern.\n *\n * Instead of injecting 50+ full tool schemas into the context window, you\n * inject just these 4 meta-tools. The LLM calls them to find and load\n * only the tools it actually needs.\n *\n * Meta-tools:\n * • `mcp_search_tool_bm25` — BM25 natural language search\n * • `mcp_search_tool_regex` — Regex pattern search\n * • `mcp_get_tool_schema` — Get full inputSchema for a discovered tool\n * • `mcp_execute_tool` — Execute a discovered tool\n *\n * @packageDocumentation\n */\n\nimport type { Tool, CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolRouter } from './tool-router.js';\nimport type { IndexedTool } from './tool-index.js';\n\n// ---------------------------------------------------------------------------\n// Tool Definitions\n// ---------------------------------------------------------------------------\n\n/**\n * Creates the `mcp_search_tool_bm25` tool definition.\n *\n * This tool lets the LLM search the full catalog of available MCP tools\n * using a BM25 natural-language query. Returns tool names and descriptions\n * without the full inputSchema to save context space.\n */\nexport function createSearchToolDefinition(): Tool {\n return {\n name: 'mcp_search_tool_bm25',\n description:\n 'Search the catalog of available tools. Returns tool names, descriptions, and server info. ' +\n 'Use this FIRST to find relevant tools before calling them.\\n\\n' +\n 'Query forms:\\n' +\n '- \"select:Read,Edit,Grep\" — fetch these exact tools by name\\n' +\n '- \"notebook jupyter\" — keyword search, up to limit best matches\\n' +\n '- \"+slack send\" — require \"slack\" in the name, rank by remaining terms',\n inputSchema: {\n type: 'object' as const,\n properties: {\n query: {\n type: 'string',\n description: 'Query to find tools. Use \"select:<tool_name>\" for direct selection, or keywords to search. Prefix keywords with + to require them.',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of results to return (default: 5, max: 20).',\n },\n },\n required: ['query'],\n },\n };\n}\n\n/**\n * Creates the `mcp_search_tool_regex` tool definition.\n * \n * Matches Anthropic's tool_search_tool_regex exactly (takes a 'query' regex pattern).\n */\nexport function createRegexSearchToolDefinition(): Tool {\n return {\n name: 'mcp_search_tool_regex',\n description:\n 'Search the catalog of available tools using a Python-style regex pattern. ' +\n 'Matches against tool names, descriptions, and parameter descriptions. ' +\n 'Example patterns: \"^github_\", \"weather\", \"(?i)slack\".',\n inputSchema: {\n type: 'object' as const,\n properties: {\n query: {\n type: 'string',\n description: 'Regex pattern to search for (e.g., \"^get_.*_data\", \"database\").',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of results to return (default: 5, max: 20).',\n },\n },\n required: ['query'],\n },\n };\n}\n\n/**\n * Creates the `mcp_get_tool_schema` tool definition.\n *\n * After discovering tools via `mcp_search_tool_bm25` or\n * `mcp_search_tool_regex`, the LLM calls this to load the full\n * inputSchema for a specific tool so it can construct the correct\n * arguments.\n */\nexport function createGetSchemaToolDefinition(): Tool {\n return {\n name: 'mcp_get_tool_schema',\n description:\n 'Get the full input schema (parameters) for a specific tool. ' +\n 'Call this after mcp_search_tool_bm25 to get the parameter details ' +\n 'needed to call a tool correctly. ' +\n 'Do NOT call the discovered tool directly; after reading the schema, call mcp_execute_tool.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n toolName: {\n type: 'string',\n description: 'The exact tool name returned by mcp_search_tool_bm25.',\n },\n serverId: {\n type: 'string',\n description:\n 'Optional: The server ID provided in mcp_search_tool_bm25. Required if multiple tools have the same name.',\n },\n },\n required: ['toolName'],\n },\n };\n}\n\n/**\n * Creates the `mcp_execute_tool` tool definition.\n *\n * This is the execution meta-tool — the LLM calls this to execute any\n * tool discovered via `mcp_search_tool_bm25` or `mcp_search_tool_regex`.\n * The LLM should first call `mcp_get_tool_schema` to know the correct\n * arguments.\n *\n * Instead of registering every real tool with the framework, we proxy\n * all execution through a single meta-tool.\n */\nexport function createExecuteToolDefinition(): Tool {\n return {\n name: 'mcp_execute_tool',\n description:\n 'Execute a tool that was discovered via mcp_search_tool_bm25. ' +\n 'You MUST call mcp_get_tool_schema first to know the correct parameters. ' +\n 'Pass the exact tool name and its arguments.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n toolName: {\n type: 'string',\n description: 'The exact tool name from mcp_search_tool_bm25 results.',\n },\n serverId: {\n type: 'string',\n description:\n 'Optional: The server ID provided in mcp_search_tool_bm25. Required if multiple tools have the same name.',\n },\n args: {\n type: 'object',\n description:\n \"Arguments matching the tool's inputSchema. Omit or pass {} if the tool takes no parameters.\",\n additionalProperties: true,\n },\n },\n required: ['toolName'],\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Meta-tool Executors\n// ---------------------------------------------------------------------------\n\n/**\n * Callback for executing a real MCP tool via the correct client.\n * Provided by adapters that wire up client routing.\n */\nexport type CallToolFn = (\n toolName: string,\n args: Record<string, unknown>,\n namespace?: string\n) => Promise<any>;\n\n/**\n * Execute a meta-tool call and return the result in MCP CallToolResult format.\n *\n * @param toolName - One of the meta-tool names (mcp_search_tool_bm25, mcp_search_tool_regex, etc.)\n * @param args - The arguments from the LLM's tool call\n * @param router - The ToolRouter to query\n * @param callToolFn - Optional callback for executing real tools (required for mcp_execute_tool)\n * @returns MCP-compatible CallToolResult, or null if this isn't a meta-tool\n */\nexport async function executeMetaTool(\n toolName: string,\n args: Record<string, unknown>,\n router: ToolRouter,\n callToolFn?: CallToolFn\n): Promise<CallToolResult | null> {\n const resolveToolSchema = (name: string, namespace?: string): { tool?: IndexedTool; error?: CallToolResult } => {\n try {\n return { tool: router.getToolSchema(name, namespace) };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n return {\n error: {\n content: [{ type: 'text', text: errorMessage }],\n isError: true,\n },\n };\n }\n };\n\n switch (toolName) {\n case 'mcp_search_tool_bm25': {\n const query = String(args.query ?? '');\n const limit = Math.min(Number(args.limit) || 5, 20);\n\n // Fast path: Check for select: prefix\n const selectMatch = query.match(/^select:(.+)$/i);\n if (selectMatch) {\n const requested = selectMatch[1]!\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n\n const found: any[] = [];\n const errors: string[] = [];\n \n for (const requestedToolName of requested) {\n const { tool, error } = resolveToolSchema(requestedToolName);\n if (error) {\n const errorMsg = error.content[0]?.type === 'text' ? error.content[0].text : 'Unknown error';\n errors.push(`- **${requestedToolName}**: ${errorMsg}`);\n } else if (tool) {\n found.push(tool);\n } else {\n errors.push(`- **${requestedToolName}**: Tool not found. Try searching with mcp_search_tool_bm25.`);\n }\n }\n\n const lines: string[] = [];\n\n if (found.length > 0) {\n lines.push(...found.map((t, i) =>\n `${i + 1}. **${t.name}** (server: ${t.serverName}, serverId: ${t.serverId})\\n ${t.description}`\n ));\n }\n \n if (errors.length > 0) {\n if (lines.length > 0) lines.push(\"\"); // Add empty line spacing\n lines.push(\"Errors resolving some tools:\");\n lines.push(...errors);\n }\n\n const text = lines.length > 0 \n ? lines.join('\\n') \n : `No tools found matching select query: ${requested.join(', ')}`;\n\n return {\n content: [{ type: 'text', text }],\n isError: found.length === 0,\n };\n }\n\n const results = await router.searchTools(query, limit);\n\n const text = results.length === 0\n ? 'No tools found matching your query. Try different keywords.'\n : results\n .map(\n (t, i) =>\n `${i + 1}. **${t.name}** (server: ${t.serverName}, serverId: ${t.serverId})\\n` +\n ` ${t.description}\\n` +\n ` Estimated tokens: ${t.estimatedTokens}`\n )\n .join('\\n');\n\n return {\n content: [{ type: 'text', text }],\n isError: false,\n };\n }\n\n case 'mcp_search_tool_regex': {\n const pattern = String(args.query ?? '');\n const limit = Math.min(Number(args.limit) || 5, 20);\n\n const results = await router.searchToolsRegex(pattern, limit);\n\n const text = results.length === 0\n ? 'No tools matched your regex pattern. Try a broader pattern.'\n : results\n .map(\n (t, i) =>\n `${i + 1}. **${t.name}** (server: ${t.serverName}, serverId: ${t.serverId})\\n` +\n ` ${t.description}\\n` +\n ` Estimated tokens: ${t.estimatedTokens}`\n )\n .join('\\n');\n\n return {\n content: [{ type: 'text', text }],\n isError: false,\n };\n }\n\n case 'mcp_get_tool_schema': {\n const name = String(args.toolName ?? '');\n const namespace = String(args.serverId ?? '') || undefined;\n const { tool, error } = resolveToolSchema(name, namespace);\n\n if (error) {\n return error;\n }\n\n if (!tool) {\n return {\n content: [\n {\n type: 'text',\n text: `Tool \"${name}\" not found. Use mcp_search_tool_bm25 to find available tools first.`,\n },\n ],\n isError: true,\n };\n }\n\n const schema = {\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n executionInstructions: {\n nextTool: 'mcp_execute_tool',\n toolName: tool.name,\n serverId: tool.serverId,\n note:\n 'Do not call this discovered tool directly unless it was explicitly registered as a runtime tool. Execute it via mcp_execute_tool and pass these parameters inside args.',\n },\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(schema, null, 2) }],\n isError: false,\n };\n }\n\n case 'mcp_execute_tool': {\n const targetToolName = String(args.toolName ?? '');\n const namespace = String(args.serverId ?? '') || undefined;\n const toolArgs = (args.args as Record<string, unknown>) ?? {};\n\n if (!targetToolName) {\n return {\n content: [{ type: 'text', text: 'Missing required parameter \"toolName\". Specify which tool to execute.' }],\n isError: true,\n };\n }\n\n // Verify the tool exists in our index\n const { tool, error } = resolveToolSchema(targetToolName, namespace);\n if (error) {\n return error;\n }\n\n if (!tool) {\n return {\n content: [\n {\n type: 'text',\n text: `Tool \"${targetToolName}\" not found. Use mcp_search_tool_bm25 to discover available tools first.`,\n },\n ],\n isError: true,\n };\n }\n\n if (!callToolFn) {\n return {\n content: [{ type: 'text', text: 'Tool execution is not available. No callToolFn was configured.' }],\n isError: true,\n };\n }\n\n try {\n const result = await callToolFn(targetToolName, toolArgs, namespace);\n\n // Normalize result to text\n if (result && typeof result === 'object' && 'content' in result) {\n // Already MCP CallToolResult format\n return result as CallToolResult;\n }\n\n const text = typeof result === 'string' ? result : JSON.stringify(result, null, 2);\n return {\n content: [{ type: 'text', text }],\n isError: false,\n };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n return {\n content: [{ type: 'text', text: `Tool execution failed: ${errorMessage}` }],\n isError: true,\n };\n }\n }\n\n default:\n return null;\n }\n}\n\n/** Check if a tool name is one of the meta-tools. */\nexport function isMetaTool(toolName: string): boolean {\n return (\n toolName === 'mcp_search_tool_bm25' ||\n toolName === 'mcp_search_tool_regex' ||\n toolName === 'mcp_get_tool_schema' ||\n toolName === 'mcp_execute_tool'\n );\n}\n\n/**\n * Unwraps a meta-tool proxy call (like mcp_execute_tool) to find the real target tool name and arguments.\n * Also automatically strips routing prefixes like tool_{serverId}_.\n * \n * Useful for frontend components that need to determine the actual tool being executed by an AI agent.\n */\nexport function resolveMetaToolProxy(\n toolName: string,\n args: Record<string, unknown> | null | undefined\n): { toolName: string; args: Record<string, unknown> } {\n // Unwrap mcp_execute_tool proxy arguments\n if (toolName === 'mcp_execute_tool') {\n const innerName = args?.toolName;\n const innerArgs = args?.args;\n return {\n toolName: typeof innerName === 'string' && innerName ? innerName : toolName,\n args: innerArgs && typeof innerArgs === 'object' && !Array.isArray(innerArgs)\n ? (innerArgs as Record<string, unknown>)\n : {},\n };\n }\n\n // Strip tool_<serverId>_ prefix used by AIAdapter\n const match = toolName.match(/(?:tool_[^_]+_)?(.+)$/);\n const resolvedName = match?.[1] ?? toolName;\n\n return { toolName: resolvedName, args: args ?? {} };\n}\n\n","/**\n * ToolRouter — Middleware layer for intelligent MCP tool selection.\n *\n * Sits between your AI framework adapter and MultiSessionClient to reduce\n * context window usage. Supports three strategies:\n *\n * • `all` — Pass through every tool (backward-compatible default)\n * • `search` — Expose only meta-tools; LLM discovers tools on-demand\n * • `groups` — Expose tools from active groups only\n *\n * Inspired by Anthropic's `defer_loading` + `tool_search_tool` pattern.\n *\n * @example\n * ```ts\n * import { ToolRouter } from '@mcp-ts/sdk/shared';\n * import { AIAdapter } from '@mcp-ts/sdk/adapters/ai';\n *\n * const router = new ToolRouter(multiSessionClient, {\n * strategy: 'search',\n * maxTools: 5,\n * });\n *\n * const tools = await AIAdapter.getTools(multiSessionClient, { toolRouter: router });\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolClient, ToolClientProvider } from './types.js';\nimport { ToolIndex, type IndexedTool, type ToolSummary, type EmbedFn } from './tool-index.js';\nimport { SchemaCompressor, type CompactTool } from './schema-compressor.js';\nimport {\n createSearchToolDefinition,\n createRegexSearchToolDefinition,\n createGetSchemaToolDefinition,\n createExecuteToolDefinition,\n} from './meta-tools.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ToolRouterStrategy = 'all' | 'search' | 'groups';\n\nexport interface ToolRouterOptions {\n /**\n * Strategy for tool selection.\n *\n * • `all` — Expose all tools (default, backward-compatible)\n * • `search` — Expose only meta-tools; LLM discovers real tools via search\n * • `groups` — Expose only tools from active groups\n *\n * @default 'all'\n */\n strategy?: ToolRouterStrategy;\n\n /**\n * Maximum tools to expose to the LLM at once.\n * Only applies to `groups` strategy and search results.\n * @default 40\n */\n maxTools?: number;\n\n /**\n * Tool groups configuration — map of group name to tool names.\n * When not provided, groups are auto-generated from server names.\n *\n * @example\n * ```ts\n * groups: {\n * database: ['query_db', 'list_tables', 'describe_table'],\n * github: ['create_pr', 'list_issues', 'search_code'],\n * }\n * ```\n */\n groups?: Record<string, string[]>;\n\n /**\n * Active groups (when `strategy='groups'`).\n * Only tools in these groups are exposed. Empty = all groups active.\n */\n activeGroups?: string[];\n\n /**\n * Whether to use compact schemas (name + description + parameterHint only, no inputSchema).\n * Reduces token usage but requires 2-turn flow: LLM picks tool → get schema → call.\n * @default false\n */\n compactSchemas?: boolean;\n\n /**\n * Optional embedding function for semantic search.\n * When not provided, keyword TF-IDF matching is used.\n */\n embedFn?: EmbedFn;\n\n /**\n * Weight of keyword score vs embedding score (0–1).\n * Only relevant when `embedFn` is provided.\n * @default 0.4\n */\n keywordWeight?: number;\n}\n\n/** Information about a tool group. */\nexport interface ToolGroupInfo {\n tools: string[];\n active: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Client Input Types\n// ---------------------------------------------------------------------------\n\n/**\n * Accepted client input for ToolRouter.\n * Pass a `ToolClientProvider` (e.g. MultiSessionClient), or an array of `ToolClient` instances.\n */\nexport type ToolRouterClientInput = ToolClientProvider | ToolClient[];\n\n// ---------------------------------------------------------------------------\n// ToolRouter\n// ---------------------------------------------------------------------------\n\nexport class ToolRouter {\n private index: ToolIndex;\n private allTools: IndexedTool[] = [];\n private groupsMap = new Map<string, ToolGroupInfo>();\n private strategy: ToolRouterStrategy;\n private maxTools: number;\n private compactSchemas: boolean;\n private activeGroups: Set<string>;\n private customGroups?: Record<string, string[]>;\n private initialized = false;\n\n constructor(\n private client: ToolRouterClientInput,\n private options: ToolRouterOptions = {}\n ) {\n this.strategy = options.strategy ?? 'all';\n this.maxTools = options.maxTools ?? 40;\n this.compactSchemas = options.compactSchemas ?? false;\n this.activeGroups = new Set(options.activeGroups ?? []);\n this.customGroups = options.groups;\n\n this.index = new ToolIndex({\n embedFn: options.embedFn,\n keywordWeight: options.keywordWeight,\n });\n }\n\n // -----------------------------------------------------------------------\n // Core Public API\n // -----------------------------------------------------------------------\n\n /**\n * Get tools filtered by the current strategy.\n * This is the main method adapters should call.\n *\n * - `all` → returns all tools (unchanged behavior)\n * - `search` → returns only meta-tools (mcp_search_tool_bm25, mcp_get_tool_schema, mcp_execute_tool)\n * - `groups` → returns tools from active groups only\n */\n async getFilteredTools(): Promise<Tool[]> {\n await this.ensureInitialized();\n\n switch (this.strategy) {\n case 'search':\n return this.getMetaToolDefinitions();\n\n case 'groups':\n return this.getGroupFilteredTools();\n\n case 'all':\n default:\n if (this.compactSchemas) {\n // Return tools with inputSchema stripped\n return this.allTools.map((t) => {\n const compact = SchemaCompressor.toCompact(t);\n return {\n name: compact.name,\n description:\n (compact.description ?? '') +\n (compact.parameterHint ? ` Parameters: ${compact.parameterHint}` : ''),\n inputSchema: { type: 'object' as const, properties: {} },\n };\n });\n }\n return [...this.allTools];\n }\n }\n\n /**\n * Search tools by natural-language query.\n * Works regardless of strategy.\n */\n async searchTools(query: string, topK?: number): Promise<ToolSummary[]> {\n await this.ensureInitialized();\n return this.index.search(query, topK ?? this.maxTools);\n }\n\n /**\n * Search tools by regex pattern.\n * Matches against name, description, and parameter metadata.\n */\n async searchToolsRegex(pattern: string, topK?: number): Promise<ToolSummary[]> {\n await this.ensureInitialized();\n return this.index.searchRegex(pattern, topK ?? this.maxTools);\n }\n\n /**\n * Get the full tool definition by name.\n * If tool name is ambiguous, use namespace to specify the server.\n */\n getToolSchema(toolName: string, namespace?: string): IndexedTool | undefined {\n const matches = this.index.getTool(toolName, namespace);\n\n if (matches.length === 0) return undefined;\n\n if (matches.length > 1) {\n const servers = matches.map((m) => m.serverId).join(', ');\n throw new Error(\n `Tool \"${toolName}\" is provided by multiple servers: [${servers}]. ` +\n `Please specify the desired \"serverId\" as a namespace.`\n );\n }\n\n return matches[0];\n }\n\n /**\n * Get compact (schema-less) summaries for all tools.\n */\n getCompactTools(): CompactTool[] {\n return SchemaCompressor.compactAll(this.allTools);\n }\n\n // -----------------------------------------------------------------------\n // Group Management\n // -----------------------------------------------------------------------\n\n /** Get all available groups with their tool lists and active status. */\n getGroups(): Map<string, ToolGroupInfo> {\n return new Map(this.groupsMap);\n }\n\n /** Activate specific groups. Pass empty array to activate all. */\n setActiveGroups(groups: string[]): void {\n this.activeGroups = new Set(groups);\n // Update groupsMap active flags\n for (const [name, info] of this.groupsMap) {\n info.active = this.activeGroups.size === 0 || this.activeGroups.has(name);\n }\n }\n\n /** Get the names of currently active groups. */\n getActiveGroups(): string[] {\n return [...this.activeGroups];\n }\n\n // -----------------------------------------------------------------------\n // Stats & Introspection\n // -----------------------------------------------------------------------\n\n /** Total token cost of all tools if loaded without filtering. */\n getTotalTokenCost(): number {\n return this.index.getTotalTokenCost();\n }\n\n /** Estimate token cost of the currently filtered tool set. */\n async getFilteredTokenCost(): Promise<number> {\n const tools = await this.getFilteredTools();\n let total = 0;\n for (const tool of tools) {\n total += ToolIndex.estimateTokens(tool);\n }\n return total;\n }\n\n /** Get compression stats showing savings from current strategy. */\n getCompressionStats() {\n return SchemaCompressor.estimateSavings(this.allTools);\n }\n\n /** Number of total indexed tools. */\n get totalToolCount(): number {\n return this.allTools.length;\n }\n\n /** Change strategy at runtime. */\n setStrategy(strategy: ToolRouterStrategy): void {\n this.strategy = strategy;\n }\n\n /**\n * Force a re-index of tools from all connected clients.\n * Call this after adding/removing MCP server connections.\n */\n async refresh(): Promise<void> {\n this.initialized = false;\n await this.ensureInitialized();\n }\n\n /**\n * Execute a tool by routing to the correct MCP client.\n * Used by the `mcp_execute_tool` meta-tool to proxy tool calls.\n */\n async callTool(\n toolName: string,\n args: Record<string, unknown>,\n namespace?: string\n ): Promise<any> {\n await this.ensureInitialized();\n\n const indexedTool = this.getToolSchema(toolName, namespace);\n if (!indexedTool) {\n throw new Error(\n `Tool \"${toolName}\" not found${\n namespace ? ` on server \"${namespace}\"` : ''\n }. Use mcp_search_tool_bm25 or mcp_search_tool_regex to discover available tools.`\n );\n }\n\n const clients = this.getClients();\n const targetClient =\n clients.find(\n (c) =>\n typeof c.getSessionId === 'function' &&\n c.getSessionId() === indexedTool.sessionId\n ) ?? clients.find((c) => c.isConnected());\n\n if (!targetClient) {\n throw new Error(`No connected client found for tool \"${toolName}\"`);\n }\n\n return await targetClient.callTool(toolName, args);\n }\n\n // -----------------------------------------------------------------------\n // Internals\n // -----------------------------------------------------------------------\n\n /** Lazy initialization — fetches tools from all connected clients. */\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) return;\n\n this.allTools = await this.fetchAllTools();\n await this.index.buildIndex(this.allTools);\n this.buildGroups();\n this.initialized = true;\n }\n\n /** Fetch tools from all connected MCP clients. */\n private async fetchAllTools(): Promise<IndexedTool[]> {\n const clients = this.getClients();\n const result: IndexedTool[] = [];\n\n for (const client of clients) {\n if (!client.isConnected()) continue;\n\n try {\n const { tools } = await client.listTools();\n const serverId =\n typeof client.getServerId === 'function' ? client.getServerId() ?? 'unknown' : 'unknown';\n const serverName =\n (typeof client.getServerName === 'function' ? client.getServerName() : undefined) ??\n serverId;\n const sessionId =\n typeof client.getSessionId === 'function' ? client.getSessionId() ?? 'unknown' : 'unknown';\n\n for (const tool of tools) {\n result.push({\n ...tool,\n serverId,\n serverName: serverName,\n sessionId,\n });\n }\n } catch (err) {\n console.warn('[ToolRouter] Failed to fetch tools from client:', err);\n }\n }\n\n return result;\n }\n\n /** Resolve the client input to a flat array of ToolClient instances. */\n private getClients(): ToolClient[] {\n if (Array.isArray(this.client)) {\n return this.client;\n }\n if (typeof (this.client as ToolClientProvider).getClients === 'function') {\n return (this.client as ToolClientProvider).getClients();\n }\n // Single client\n return [this.client as unknown as ToolClient];\n }\n\n /** Build group map from custom config or auto-detect from server names. */\n private buildGroups(): void {\n this.groupsMap.clear();\n\n if (this.customGroups) {\n // Explicit groups\n for (const [name, tools] of Object.entries(this.customGroups)) {\n this.groupsMap.set(name, {\n tools,\n active: this.activeGroups.size === 0 || this.activeGroups.has(name),\n });\n }\n } else {\n // Auto-group by server ID\n const serverTools = new Map<string, string[]>();\n for (const tool of this.allTools) {\n const group = tool.serverId;\n if (!serverTools.has(group)) {\n serverTools.set(group, []);\n }\n serverTools.get(group)!.push(tool.name);\n }\n\n for (const [serverId, tools] of serverTools) {\n this.groupsMap.set(serverId, {\n tools,\n active: this.activeGroups.size === 0 || this.activeGroups.has(serverId),\n });\n }\n }\n }\n\n /** Return only tools belonging to currently active groups. */\n private getGroupFilteredTools(): Tool[] {\n const activeToolNames = new Set<string>();\n for (const [, info] of this.groupsMap) {\n if (info.active) {\n for (const name of info.tools) {\n activeToolNames.add(name);\n }\n }\n }\n\n const filtered = this.allTools.filter((t) => activeToolNames.has(t.name));\n\n if (this.compactSchemas) {\n return filtered.slice(0, this.maxTools).map((t) => {\n const compact = SchemaCompressor.toCompact(t);\n return {\n name: compact.name,\n description:\n (compact.description ?? '') +\n (compact.parameterHint ? ` Parameters: ${compact.parameterHint}` : ''),\n inputSchema: { type: 'object' as const, properties: {} },\n };\n });\n }\n\n return filtered.slice(0, this.maxTools);\n }\n\n /** The 4 meta-tool definitions exposed in `search` strategy. */\n private getMetaToolDefinitions(): Tool[] {\n return [\n createSearchToolDefinition(),\n createRegexSearchToolDefinition(),\n createGetSchemaToolDefinition(),\n createExecuteToolDefinition(),\n ];\n }\n}\n"]}
|