@mcp-ts/sdk 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +21 -10
  2. package/dist/adapters/agui-adapter.js +0 -1
  3. package/dist/adapters/agui-adapter.js.map +1 -1
  4. package/dist/adapters/agui-adapter.mjs +0 -1
  5. package/dist/adapters/agui-adapter.mjs.map +1 -1
  6. package/dist/adapters/agui-middleware.d.mts +5 -0
  7. package/dist/adapters/agui-middleware.d.ts +5 -0
  8. package/dist/adapters/agui-middleware.js +12 -23
  9. package/dist/adapters/agui-middleware.js.map +1 -1
  10. package/dist/adapters/agui-middleware.mjs +12 -23
  11. package/dist/adapters/agui-middleware.mjs.map +1 -1
  12. package/dist/client/react.d.mts +351 -3
  13. package/dist/client/react.d.ts +351 -3
  14. package/dist/client/react.js +308 -6
  15. package/dist/client/react.js.map +1 -1
  16. package/dist/client/react.mjs +302 -7
  17. package/dist/client/react.mjs.map +1 -1
  18. package/dist/client/vue.js +1 -1
  19. package/dist/client/vue.js.map +1 -1
  20. package/dist/client/vue.mjs +1 -1
  21. package/dist/client/vue.mjs.map +1 -1
  22. package/dist/index.d.mts +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +19 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/index.mjs +18 -1
  27. package/dist/index.mjs.map +1 -1
  28. package/dist/shared/index.d.mts +38 -2
  29. package/dist/shared/index.d.ts +38 -2
  30. package/dist/shared/index.js +19 -0
  31. package/dist/shared/index.js.map +1 -1
  32. package/dist/shared/index.mjs +18 -1
  33. package/dist/shared/index.mjs.map +1 -1
  34. package/package.json +1 -1
  35. package/src/adapters/agui-adapter.ts +2 -4
  36. package/src/adapters/agui-middleware.ts +15 -27
  37. package/src/client/react/agui-subscriber.ts +275 -0
  38. package/src/client/react/index.ts +23 -4
  39. package/src/client/react/use-agui-subscriber.ts +270 -0
  40. package/src/client/react/{use-mcp-app.ts → use-app-host.ts} +2 -2
  41. package/src/client/react/use-mcp-app-iframe.ts +164 -0
  42. package/src/client/react/{useMcp.ts → use-mcp.ts} +2 -2
  43. package/src/client/vue/index.ts +1 -1
  44. package/src/shared/index.ts +6 -1
  45. package/src/shared/tool-utils.ts +61 -0
  46. /package/src/client/vue/{useMcp.ts → use-mcp.ts} +0 -0
@@ -1,6 +1,7 @@
1
1
  export { D as Disposable, a as DisposableStore, E as Emitter, b as Event, M as McpConnectionEvent, c as McpConnectionState, d as McpObservabilityEvent } from '../events-BgeztGYZ.mjs';
2
2
  export { A as AuthenticationError, C as ConfigurationError, a as ConnectionError, I as InvalidStateError, M as McpError, N as NotConnectedError, R as RpcErrorCode, b as RpcErrorCodes, S as SessionNotFoundError, c as SessionValidationError, T as ToolExecutionError, U as UnauthorizedError, s as sanitizeServerLabel } from '../utils-0qmYrqoa.mjs';
3
- export { C as CallToolParams, a as CallToolRequest, b as CallToolResponse, c as ConnectAuthRequiredResponse, d as ConnectErrorResponse, e as ConnectParams, f as ConnectRequest, g as ConnectResponse, h as ConnectResult, i as ConnectSuccessResponse, D as DisconnectParams, j as DisconnectResult, F as FinishAuthParams, k as FinishAuthResult, G as GetPromptParams, L as ListPromptsResult, l as ListResourcesResult, m as ListToolsResponse, n as ListToolsRpcResult, M as McpRpcMethod, o as McpRpcParams, p as McpRpcRequest, q as McpRpcResponse, R as ReadResourceParams, r as RestoreSessionResult, S as SessionInfo, s as SessionListResult, t as SessionParams, T as ToolInfo, u as TransportType, v as isCallToolSuccess, w as isConnectAuthRequired, x as isConnectError, y as isConnectSuccess, z as isListToolsSuccess } from '../types-CLccx9wW.mjs';
3
+ import { T as ToolInfo } from '../types-CLccx9wW.mjs';
4
+ export { C as CallToolParams, a as CallToolRequest, b as CallToolResponse, c as ConnectAuthRequiredResponse, d as ConnectErrorResponse, e as ConnectParams, f as ConnectRequest, g as ConnectResponse, h as ConnectResult, i as ConnectSuccessResponse, D as DisconnectParams, j as DisconnectResult, F as FinishAuthParams, k as FinishAuthResult, G as GetPromptParams, L as ListPromptsResult, l as ListResourcesResult, m as ListToolsResponse, n as ListToolsRpcResult, M as McpRpcMethod, o as McpRpcParams, p as McpRpcRequest, q as McpRpcResponse, R as ReadResourceParams, r as RestoreSessionResult, S as SessionInfo, s as SessionListResult, t as SessionParams, u as TransportType, v as isCallToolSuccess, w as isConnectAuthRequired, x as isConnectError, y as isConnectSuccess, z as isListToolsSuccess } from '../types-CLccx9wW.mjs';
4
5
  import '@modelcontextprotocol/sdk/types.js';
5
6
 
6
7
  /**
@@ -21,4 +22,39 @@ declare const SOFTWARE_VERSION = "1.0.0-beta.5";
21
22
  declare const MCP_CLIENT_NAME = "mcp-ts-oauth-client";
22
23
  declare const MCP_CLIENT_VERSION = "2.0";
23
24
 
24
- export { DEFAULT_CLIENT_NAME, DEFAULT_CLIENT_URI, DEFAULT_HEARTBEAT_INTERVAL_MS, DEFAULT_LOGO_URI, DEFAULT_POLICY_URI, MCP_CLIENT_NAME, MCP_CLIENT_VERSION, REDIS_KEY_PREFIX, SESSION_TTL_SECONDS, SOFTWARE_ID, SOFTWARE_VERSION, STATE_EXPIRATION_MS, TOKEN_EXPIRY_BUFFER_MS };
25
+ /**
26
+ * Utility functions for working with MCP tool metadata
27
+ */
28
+
29
+ interface ToolUiConfig {
30
+ resourceUri: string;
31
+ sessionId: string;
32
+ }
33
+ /**
34
+ * Extract UI resource URI from tool metadata
35
+ *
36
+ * @param tool - The tool to extract UI config from
37
+ * @returns The resource URI if available, undefined otherwise
38
+ *
39
+ * @example
40
+ * const uri = getToolUiResourceUri(tool);
41
+ * if (uri) {
42
+ * // Tool has UI configuration
43
+ * }
44
+ */
45
+ declare function getToolUiResourceUri(tool: ToolInfo): string | undefined;
46
+ /**
47
+ * Find a tool by name within connections
48
+ *
49
+ * @param connections - Array of MCP connections
50
+ * @param toolName - Name of the tool to find
51
+ * @returns The tool if found, undefined otherwise
52
+ *
53
+ * @example
54
+ * const tool = findToolByName(connections, "get_weather");
55
+ */
56
+ declare function findToolByName(connections: Array<{
57
+ tools: ToolInfo[];
58
+ }>, toolName: string): ToolInfo | undefined;
59
+
60
+ export { DEFAULT_CLIENT_NAME, DEFAULT_CLIENT_URI, DEFAULT_HEARTBEAT_INTERVAL_MS, DEFAULT_LOGO_URI, DEFAULT_POLICY_URI, MCP_CLIENT_NAME, MCP_CLIENT_VERSION, REDIS_KEY_PREFIX, SESSION_TTL_SECONDS, SOFTWARE_ID, SOFTWARE_VERSION, STATE_EXPIRATION_MS, TOKEN_EXPIRY_BUFFER_MS, ToolInfo, type ToolUiConfig, findToolByName, getToolUiResourceUri };
@@ -1,6 +1,7 @@
1
1
  export { D as Disposable, a as DisposableStore, E as Emitter, b as Event, M as McpConnectionEvent, c as McpConnectionState, d as McpObservabilityEvent } from '../events-BgeztGYZ.js';
2
2
  export { A as AuthenticationError, C as ConfigurationError, a as ConnectionError, I as InvalidStateError, M as McpError, N as NotConnectedError, R as RpcErrorCode, b as RpcErrorCodes, S as SessionNotFoundError, c as SessionValidationError, T as ToolExecutionError, U as UnauthorizedError, s as sanitizeServerLabel } from '../utils-0qmYrqoa.js';
3
- export { C as CallToolParams, a as CallToolRequest, b as CallToolResponse, c as ConnectAuthRequiredResponse, d as ConnectErrorResponse, e as ConnectParams, f as ConnectRequest, g as ConnectResponse, h as ConnectResult, i as ConnectSuccessResponse, D as DisconnectParams, j as DisconnectResult, F as FinishAuthParams, k as FinishAuthResult, G as GetPromptParams, L as ListPromptsResult, l as ListResourcesResult, m as ListToolsResponse, n as ListToolsRpcResult, M as McpRpcMethod, o as McpRpcParams, p as McpRpcRequest, q as McpRpcResponse, R as ReadResourceParams, r as RestoreSessionResult, S as SessionInfo, s as SessionListResult, t as SessionParams, T as ToolInfo, u as TransportType, v as isCallToolSuccess, w as isConnectAuthRequired, x as isConnectError, y as isConnectSuccess, z as isListToolsSuccess } from '../types-CLccx9wW.js';
3
+ import { T as ToolInfo } from '../types-CLccx9wW.js';
4
+ export { C as CallToolParams, a as CallToolRequest, b as CallToolResponse, c as ConnectAuthRequiredResponse, d as ConnectErrorResponse, e as ConnectParams, f as ConnectRequest, g as ConnectResponse, h as ConnectResult, i as ConnectSuccessResponse, D as DisconnectParams, j as DisconnectResult, F as FinishAuthParams, k as FinishAuthResult, G as GetPromptParams, L as ListPromptsResult, l as ListResourcesResult, m as ListToolsResponse, n as ListToolsRpcResult, M as McpRpcMethod, o as McpRpcParams, p as McpRpcRequest, q as McpRpcResponse, R as ReadResourceParams, r as RestoreSessionResult, S as SessionInfo, s as SessionListResult, t as SessionParams, u as TransportType, v as isCallToolSuccess, w as isConnectAuthRequired, x as isConnectError, y as isConnectSuccess, z as isListToolsSuccess } from '../types-CLccx9wW.js';
4
5
  import '@modelcontextprotocol/sdk/types.js';
5
6
 
6
7
  /**
@@ -21,4 +22,39 @@ declare const SOFTWARE_VERSION = "1.0.0-beta.5";
21
22
  declare const MCP_CLIENT_NAME = "mcp-ts-oauth-client";
22
23
  declare const MCP_CLIENT_VERSION = "2.0";
23
24
 
24
- export { DEFAULT_CLIENT_NAME, DEFAULT_CLIENT_URI, DEFAULT_HEARTBEAT_INTERVAL_MS, DEFAULT_LOGO_URI, DEFAULT_POLICY_URI, MCP_CLIENT_NAME, MCP_CLIENT_VERSION, REDIS_KEY_PREFIX, SESSION_TTL_SECONDS, SOFTWARE_ID, SOFTWARE_VERSION, STATE_EXPIRATION_MS, TOKEN_EXPIRY_BUFFER_MS };
25
+ /**
26
+ * Utility functions for working with MCP tool metadata
27
+ */
28
+
29
+ interface ToolUiConfig {
30
+ resourceUri: string;
31
+ sessionId: string;
32
+ }
33
+ /**
34
+ * Extract UI resource URI from tool metadata
35
+ *
36
+ * @param tool - The tool to extract UI config from
37
+ * @returns The resource URI if available, undefined otherwise
38
+ *
39
+ * @example
40
+ * const uri = getToolUiResourceUri(tool);
41
+ * if (uri) {
42
+ * // Tool has UI configuration
43
+ * }
44
+ */
45
+ declare function getToolUiResourceUri(tool: ToolInfo): string | undefined;
46
+ /**
47
+ * Find a tool by name within connections
48
+ *
49
+ * @param connections - Array of MCP connections
50
+ * @param toolName - Name of the tool to find
51
+ * @returns The tool if found, undefined otherwise
52
+ *
53
+ * @example
54
+ * const tool = findToolByName(connections, "get_weather");
55
+ */
56
+ declare function findToolByName(connections: Array<{
57
+ tools: ToolInfo[];
58
+ }>, toolName: string): ToolInfo | undefined;
59
+
60
+ export { DEFAULT_CLIENT_NAME, DEFAULT_CLIENT_URI, DEFAULT_HEARTBEAT_INTERVAL_MS, DEFAULT_LOGO_URI, DEFAULT_POLICY_URI, MCP_CLIENT_NAME, MCP_CLIENT_VERSION, REDIS_KEY_PREFIX, SESSION_TTL_SECONDS, SOFTWARE_ID, SOFTWARE_VERSION, STATE_EXPIRATION_MS, TOKEN_EXPIRY_BUFFER_MS, ToolInfo, type ToolUiConfig, findToolByName, getToolUiResourceUri };
@@ -187,6 +187,23 @@ function sanitizeServerLabel(name) {
187
187
  return sanitized;
188
188
  }
189
189
 
190
+ // src/shared/tool-utils.ts
191
+ function getToolUiResourceUri(tool) {
192
+ const meta = tool._meta;
193
+ if (!meta?.ui) return void 0;
194
+ const ui = meta.ui;
195
+ if (typeof ui !== "object" || !ui) return void 0;
196
+ if (ui.visibility && !ui.visibility.includes("app")) return void 0;
197
+ return typeof ui.resourceUri === "string" ? ui.resourceUri : typeof ui.uri === "string" ? ui.uri : void 0;
198
+ }
199
+ function findToolByName(connections, toolName) {
200
+ for (const conn of connections) {
201
+ const tool = conn.tools.find((t) => t.name === toolName);
202
+ if (tool) return tool;
203
+ }
204
+ return void 0;
205
+ }
206
+
190
207
  exports.AuthenticationError = AuthenticationError;
191
208
  exports.ConfigurationError = ConfigurationError;
192
209
  exports.ConnectionError = ConnectionError;
@@ -213,6 +230,8 @@ exports.SessionValidationError = SessionValidationError;
213
230
  exports.TOKEN_EXPIRY_BUFFER_MS = TOKEN_EXPIRY_BUFFER_MS;
214
231
  exports.ToolExecutionError = ToolExecutionError;
215
232
  exports.UnauthorizedError = UnauthorizedError;
233
+ exports.findToolByName = findToolByName;
234
+ exports.getToolUiResourceUri = getToolUiResourceUri;
216
235
  exports.isCallToolSuccess = isCallToolSuccess;
217
236
  exports.isConnectAuthRequired = isConnectAuthRequired;
218
237
  exports.isConnectError = isConnectError;
@@ -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"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Simple event emitter pattern for MCP connection events\r\n * Inspired by Cloudflare's agents pattern but adapted for serverless\r\n */\r\n\r\nexport type Disposable = {\r\n dispose(): void;\r\n};\r\n\r\nexport type Event<T> = (listener: (event: T) => void) => Disposable;\r\n\r\n/**\r\n * Event emitter class for type-safe event handling\r\n * Similar to Cloudflare's Emitter but simplified for our use case\r\n */\r\nexport class Emitter<T> {\r\n private listeners: Set<(event: T) => void> = new Set();\r\n\r\n /**\r\n * Subscribe to events\r\n * @param listener - Callback function to handle events\r\n * @returns Disposable to unsubscribe\r\n */\r\n get event(): Event<T> {\r\n return (listener: (event: T) => void) => {\r\n this.listeners.add(listener);\r\n return {\r\n dispose: () => {\r\n this.listeners.delete(listener);\r\n },\r\n };\r\n };\r\n }\r\n\r\n /**\r\n * Fire an event to all listeners\r\n * @param event - Event data to emit\r\n */\r\n fire(event: T): void {\r\n for (const listener of this.listeners) {\r\n try {\r\n listener(event);\r\n } catch (error) {\r\n console.error('[Emitter] Error in event listener:', error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear all listeners\r\n */\r\n dispose(): void {\r\n this.listeners.clear();\r\n }\r\n\r\n /**\r\n * Get number of active listeners\r\n */\r\n get listenerCount(): number {\r\n return this.listeners.size;\r\n }\r\n}\r\n\r\n/**\r\n * Connection state types matching your existing ConnectionStatus\r\n * Extended with more granular states for better observability\r\n */\r\nexport type McpConnectionState =\r\n | 'DISCONNECTED' // Not connected\r\n | 'CONNECTING' // Establishing transport connection to MCP server\r\n | 'AUTHENTICATING' // OAuth flow in progress\r\n | 'AUTHENTICATED' // OAuth complete, pre-connect\r\n | 'DISCOVERING' // Discovering server capabilities (tools, resources, prompts)\r\n | 'CONNECTED' // Transport connection established\r\n | 'READY' // Fully connected and ready to use\r\n | 'VALIDATING' // Validating existing session\r\n | 'RECONNECTING' // Attempting to reconnect\r\n | 'INITIALIZING' // Initializing session or connection\r\n | 'FAILED'; // Connection error at some point\r\n\r\n/**\r\n * MCP Connection Event Types\r\n * Discriminated union for type-safe event handling\r\n */\r\nexport type McpConnectionEvent =\r\n | {\r\n type: 'state_changed';\r\n sessionId: string;\r\n serverId: string;\r\n serverName: string;\r\n state: McpConnectionState;\r\n previousState: McpConnectionState;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'tools_discovered';\r\n sessionId: string;\r\n serverId: string;\r\n toolCount: number;\r\n tools: any[];\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'auth_required';\r\n sessionId: string;\r\n serverId: string;\r\n authUrl: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'error';\r\n sessionId: string;\r\n serverId: string;\r\n error: string;\r\n errorType: 'connection' | 'auth' | 'validation' | 'unknown';\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'disconnected';\r\n sessionId: string;\r\n serverId: string;\r\n reason?: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'progress';\r\n sessionId: string;\r\n serverId: string;\r\n message: string;\r\n timestamp: number;\r\n };\r\n\r\n/**\r\n * Event fired when a tool execution returns a UI resource URI\r\n */\r\nexport interface McpAppsUIEvent {\r\n type: 'mcp-apps-ui';\r\n sessionId: string;\r\n resourceUri: string;\r\n toolName: string;\r\n result: unknown;\r\n timestamp: number;\r\n}\r\n\r\n/**\r\n * Observability event for debugging and monitoring\r\n */\r\nexport interface McpObservabilityEvent {\r\n type?: string;\r\n level?: 'debug' | 'info' | 'warn' | 'error';\r\n message?: string;\r\n displayMessage?: string;\r\n sessionId?: string;\r\n serverId?: string;\r\n payload?: Record<string, any>;\r\n metadata?: Record<string, any>; // Kept for backward compatibility\r\n timestamp: number;\r\n id?: string;\r\n}\r\n\r\n/**\r\n * DisposableStore for managing multiple disposables\r\n * Useful for cleanup in React hooks\r\n */\r\nexport class DisposableStore {\r\n private disposables: Set<Disposable> = new Set();\r\n\r\n add(disposable: Disposable): void {\r\n this.disposables.add(disposable);\r\n }\r\n\r\n dispose(): void {\r\n for (const disposable of this.disposables) {\r\n disposable.dispose();\r\n }\r\n this.disposables.clear();\r\n }\r\n}\r\n","/**\r\n * Centralized constants for MCP Redis library\r\n * Eliminates magic numbers and enables consistent configuration\r\n */\r\n\r\n// Redis TTL and Session Management\r\nexport const SESSION_TTL_SECONDS = 43200; // 12 hours\r\nexport const STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes for OAuth state\r\n\r\n// Heartbeat and Connection\r\nexport const DEFAULT_HEARTBEAT_INTERVAL_MS = 30000; // 30 seconds\r\n\r\n// Redis Key Prefixes\r\nexport const REDIS_KEY_PREFIX = 'mcp:session:';\r\n\r\n// Token Management\r\nexport const TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000; // 5 minute buffer before expiry\r\n\r\n// Client Information\r\nexport const DEFAULT_CLIENT_NAME = 'MCP Assistant';\r\nexport const DEFAULT_CLIENT_URI = 'https://mcp-assistant.in';\r\nexport const DEFAULT_LOGO_URI = 'https://mcp-assistant.in/logo.png';\r\nexport const DEFAULT_POLICY_URI = 'https://mcp-assistant.in/privacy';\r\nexport const SOFTWARE_ID = '@mcp-ts';\r\nexport const SOFTWARE_VERSION = '1.0.0-beta.5';\r\n\r\n// MCP Client Configuration\r\nexport const MCP_CLIENT_NAME = 'mcp-ts-oauth-client';\r\nexport const MCP_CLIENT_VERSION = '2.0';\r\n","/**\r\n * Standardized error classes for MCP Redis library\r\n * Provides consistent error handling across the codebase\r\n */\r\n\r\n/**\r\n * Base error class for all MCP-related errors\r\n */\r\nexport class McpError extends Error {\r\n constructor(\r\n public readonly code: string,\r\n message: string,\r\n public readonly cause?: Error\r\n ) {\r\n super(message);\r\n this.name = 'McpError';\r\n // Maintain proper prototype chain for instanceof checks\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n\r\n toJSON() {\r\n return {\r\n name: this.name,\r\n code: this.code,\r\n message: this.message,\r\n ...(this.cause ? { cause: this.cause.message } : {}),\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth authorization is required\r\n */\r\nexport class UnauthorizedError extends McpError {\r\n constructor(message: string = 'OAuth authorization required', cause?: Error) {\r\n super('UNAUTHORIZED', message, cause);\r\n this.name = 'UnauthorizedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when connection to MCP server fails\r\n */\r\nexport class ConnectionError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONNECTION_ERROR', message, cause);\r\n this.name = 'ConnectionError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session is not found or expired\r\n */\r\nexport class SessionNotFoundError extends McpError {\r\n constructor(sessionId: string, cause?: Error) {\r\n super('SESSION_NOT_FOUND', `Session not found: ${sessionId}`, cause);\r\n this.name = 'SessionNotFoundError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session validation fails\r\n */\r\nexport class SessionValidationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('SESSION_VALIDATION_ERROR', message, cause);\r\n this.name = 'SessionValidationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when authentication fails\r\n */\r\nexport class AuthenticationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('AUTH_ERROR', message, cause);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth state validation fails\r\n */\r\nexport class InvalidStateError extends McpError {\r\n constructor(message: string = 'Invalid OAuth state', cause?: Error) {\r\n super('INVALID_STATE', message, cause);\r\n this.name = 'InvalidStateError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when client is not connected\r\n */\r\nexport class NotConnectedError extends McpError {\r\n constructor(message: string = 'Not connected to server', cause?: Error) {\r\n super('NOT_CONNECTED', message, cause);\r\n this.name = 'NotConnectedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when required configuration is missing\r\n */\r\nexport class ConfigurationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONFIGURATION_ERROR', message, cause);\r\n this.name = 'ConfigurationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when tool execution fails\r\n */\r\nexport class ToolExecutionError extends McpError {\r\n constructor(toolName: string, message: string, cause?: Error) {\r\n super('TOOL_EXECUTION_ERROR', `Tool '${toolName}' failed: ${message}`, cause);\r\n this.name = 'ToolExecutionError';\r\n }\r\n}\r\n\r\n/**\r\n * RPC error codes for SSE communication\r\n */\r\nexport const RpcErrorCodes = {\r\n EXECUTION_ERROR: 'EXECUTION_ERROR',\r\n MISSING_IDENTITY: 'MISSING_IDENTITY',\r\n UNAUTHORIZED: 'UNAUTHORIZED',\r\n NO_CONNECTION: 'NO_CONNECTION',\r\n UNKNOWN_METHOD: 'UNKNOWN_METHOD',\r\n INVALID_PARAMS: 'INVALID_PARAMS',\r\n} as const;\r\n\r\nexport type RpcErrorCode = typeof RpcErrorCodes[keyof typeof RpcErrorCodes];\r\n","/**\r\n * Type definitions for MCP operations\r\n */\r\n\r\nimport { Tool, CallToolResult } from '@modelcontextprotocol/sdk/types.js';\r\n\r\n// Connect API types\r\nexport interface ConnectRequest {\r\n serverUrl: string;\r\n callbackUrl: string;\r\n}\r\n\r\nexport interface ConnectSuccessResponse {\r\n success: true;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectAuthRequiredResponse {\r\n requiresAuth: true;\r\n authUrl: string;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ConnectResponse =\r\n | ConnectSuccessResponse\r\n | ConnectAuthRequiredResponse\r\n | ConnectErrorResponse;\r\n\r\n// Callback API types\r\nexport interface CallbackSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface CallbackErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallbackResponse = CallbackSuccessResponse | CallbackErrorResponse;\r\n\r\n// Disconnect API types\r\nexport interface DisconnectRequest {\r\n sessionId: string;\r\n}\r\n\r\nexport interface DisconnectSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface DisconnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type DisconnectResponse =\r\n | DisconnectSuccessResponse\r\n | DisconnectErrorResponse;\r\n\r\n// List Tools API types\r\nexport interface ListToolsSuccessResponse {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListToolsErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ListToolsResponse =\r\n | ListToolsSuccessResponse\r\n | ListToolsErrorResponse;\r\n\r\n// Call Tool API types\r\nexport interface CallToolRequest {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface CallToolSuccessResponse {\r\n content: Array<{\r\n type: string;\r\n text?: string;\r\n [key: string]: unknown;\r\n }>;\r\n isError: boolean;\r\n}\r\n\r\nexport interface CallToolErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallToolResponse =\r\n | CallToolSuccessResponse\r\n | CallToolErrorResponse;\r\n\r\n// Helper type guards\r\nexport function isConnectSuccess(\r\n response: ConnectResponse\r\n): response is ConnectSuccessResponse {\r\n return 'success' in response && response.success === true;\r\n}\r\n\r\nexport function isConnectAuthRequired(\r\n response: ConnectResponse\r\n): response is ConnectAuthRequiredResponse {\r\n return 'requiresAuth' in response && response.requiresAuth === true;\r\n}\r\n\r\nexport function isConnectError(\r\n response: ConnectResponse\r\n): response is ConnectErrorResponse {\r\n return 'error' in response;\r\n}\r\n\r\nexport function isListToolsSuccess(\r\n response: ListToolsResponse\r\n): response is ListToolsSuccessResponse {\r\n return 'tools' in response;\r\n}\r\n\r\nexport function isCallToolSuccess(\r\n response: CallToolResponse\r\n): response is CallToolSuccessResponse {\r\n return 'content' in response;\r\n}\r\n\r\n// Generic tool info type\r\nexport type ToolInfo = {\r\n name: string;\r\n description?: string;\r\n inputSchema?: unknown;\r\n};\r\n\r\n// Transport type\r\nexport type TransportType = 'sse' | 'streamable_http';\r\n\r\n// SSE/RPC types\r\nexport type McpRpcMethod =\r\n | 'connect'\r\n | 'disconnect'\r\n | 'listTools'\r\n | 'callTool'\r\n | 'getSessions'\r\n | 'restoreSession'\r\n | 'finishAuth'\r\n | 'listPrompts'\r\n | 'getPrompt'\r\n | 'listResources'\r\n | 'readResource';\r\n\r\nexport interface McpRpcRequest {\r\n id: string;\r\n method: McpRpcMethod;\r\n params?: McpRpcParams;\r\n}\r\n\r\nexport interface McpRpcResponse<T = unknown> {\r\n id: string;\r\n result?: T;\r\n error?: {\r\n code: string;\r\n message: string;\r\n };\r\n}\r\n\r\n// RPC Parameter Types\r\nexport interface ConnectParams {\r\n serverId?: string; // Optional - generated server-side if not provided\r\n serverName: string;\r\n serverUrl: string;\r\n callbackUrl: string;\r\n transportType?: TransportType;\r\n}\r\n\r\nexport interface DisconnectParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface SessionParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface CallToolParams {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface GetPromptParams {\r\n sessionId: string;\r\n name: string;\r\n args?: Record<string, string>;\r\n}\r\n\r\nexport interface ReadResourceParams {\r\n sessionId: string;\r\n uri: string;\r\n}\r\n\r\nexport interface FinishAuthParams {\r\n sessionId: string;\r\n code: string;\r\n}\r\n\r\nexport type McpRpcParams =\r\n | ConnectParams\r\n | DisconnectParams\r\n | SessionParams\r\n | CallToolParams\r\n | GetPromptParams\r\n | ReadResourceParams\r\n | FinishAuthParams\r\n | undefined;\r\n\r\n// RPC Result Types\r\nexport interface SessionInfo {\r\n sessionId: string;\r\n serverId?: string;\r\n serverName?: string;\r\n serverUrl: string;\r\n transport: TransportType;\r\n}\r\n\r\nexport interface SessionListResult {\r\n sessions: SessionInfo[];\r\n}\r\n\r\nexport interface ConnectResult {\r\n sessionId: string;\r\n success: boolean;\r\n}\r\n\r\nexport interface DisconnectResult {\r\n success: boolean;\r\n}\r\n\r\nexport interface RestoreSessionResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface FinishAuthResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface ListToolsRpcResult {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListPromptsResult {\r\n prompts: Array<{\r\n name: string;\r\n description?: string;\r\n arguments?: Array<{\r\n name: string;\r\n description?: string;\r\n required?: boolean;\r\n }>;\r\n }>;\r\n}\r\n\r\nexport interface ListResourcesResult {\r\n resources: Array<{\r\n uri: string;\r\n name: string;\r\n description?: string;\r\n mimeType?: string;\r\n }>;\r\n}\r\n\r\nexport type { CallToolResult };\r\n","/**\r\n * Sanitize server name to create a valid server label\r\n * Must start with a letter and contain only letters, digits, '-' and '_'\r\n */\r\nexport function sanitizeServerLabel(name: string): string {\r\n let sanitized = name\r\n .replace(/[^a-zA-Z0-9-_]/g, '_')\r\n .replace(/_{2,}/g, '_')\r\n .toLowerCase();\r\n\r\n if (!/^[a-zA-Z]/.test(sanitized)) {\r\n sanitized = 's_' + sanitized;\r\n }\r\n\r\n return sanitized;\r\n}\r\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"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Simple event emitter pattern for MCP connection events\r\n * Inspired by Cloudflare's agents pattern but adapted for serverless\r\n */\r\n\r\nexport type Disposable = {\r\n dispose(): void;\r\n};\r\n\r\nexport type Event<T> = (listener: (event: T) => void) => Disposable;\r\n\r\n/**\r\n * Event emitter class for type-safe event handling\r\n * Similar to Cloudflare's Emitter but simplified for our use case\r\n */\r\nexport class Emitter<T> {\r\n private listeners: Set<(event: T) => void> = new Set();\r\n\r\n /**\r\n * Subscribe to events\r\n * @param listener - Callback function to handle events\r\n * @returns Disposable to unsubscribe\r\n */\r\n get event(): Event<T> {\r\n return (listener: (event: T) => void) => {\r\n this.listeners.add(listener);\r\n return {\r\n dispose: () => {\r\n this.listeners.delete(listener);\r\n },\r\n };\r\n };\r\n }\r\n\r\n /**\r\n * Fire an event to all listeners\r\n * @param event - Event data to emit\r\n */\r\n fire(event: T): void {\r\n for (const listener of this.listeners) {\r\n try {\r\n listener(event);\r\n } catch (error) {\r\n console.error('[Emitter] Error in event listener:', error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear all listeners\r\n */\r\n dispose(): void {\r\n this.listeners.clear();\r\n }\r\n\r\n /**\r\n * Get number of active listeners\r\n */\r\n get listenerCount(): number {\r\n return this.listeners.size;\r\n }\r\n}\r\n\r\n/**\r\n * Connection state types matching your existing ConnectionStatus\r\n * Extended with more granular states for better observability\r\n */\r\nexport type McpConnectionState =\r\n | 'DISCONNECTED' // Not connected\r\n | 'CONNECTING' // Establishing transport connection to MCP server\r\n | 'AUTHENTICATING' // OAuth flow in progress\r\n | 'AUTHENTICATED' // OAuth complete, pre-connect\r\n | 'DISCOVERING' // Discovering server capabilities (tools, resources, prompts)\r\n | 'CONNECTED' // Transport connection established\r\n | 'READY' // Fully connected and ready to use\r\n | 'VALIDATING' // Validating existing session\r\n | 'RECONNECTING' // Attempting to reconnect\r\n | 'INITIALIZING' // Initializing session or connection\r\n | 'FAILED'; // Connection error at some point\r\n\r\n/**\r\n * MCP Connection Event Types\r\n * Discriminated union for type-safe event handling\r\n */\r\nexport type McpConnectionEvent =\r\n | {\r\n type: 'state_changed';\r\n sessionId: string;\r\n serverId: string;\r\n serverName: string;\r\n state: McpConnectionState;\r\n previousState: McpConnectionState;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'tools_discovered';\r\n sessionId: string;\r\n serverId: string;\r\n toolCount: number;\r\n tools: any[];\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'auth_required';\r\n sessionId: string;\r\n serverId: string;\r\n authUrl: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'error';\r\n sessionId: string;\r\n serverId: string;\r\n error: string;\r\n errorType: 'connection' | 'auth' | 'validation' | 'unknown';\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'disconnected';\r\n sessionId: string;\r\n serverId: string;\r\n reason?: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'progress';\r\n sessionId: string;\r\n serverId: string;\r\n message: string;\r\n timestamp: number;\r\n };\r\n\r\n/**\r\n * Event fired when a tool execution returns a UI resource URI\r\n */\r\nexport interface McpAppsUIEvent {\r\n type: 'mcp-apps-ui';\r\n sessionId: string;\r\n resourceUri: string;\r\n toolName: string;\r\n result: unknown;\r\n timestamp: number;\r\n}\r\n\r\n/**\r\n * Observability event for debugging and monitoring\r\n */\r\nexport interface McpObservabilityEvent {\r\n type?: string;\r\n level?: 'debug' | 'info' | 'warn' | 'error';\r\n message?: string;\r\n displayMessage?: string;\r\n sessionId?: string;\r\n serverId?: string;\r\n payload?: Record<string, any>;\r\n metadata?: Record<string, any>; // Kept for backward compatibility\r\n timestamp: number;\r\n id?: string;\r\n}\r\n\r\n/**\r\n * DisposableStore for managing multiple disposables\r\n * Useful for cleanup in React hooks\r\n */\r\nexport class DisposableStore {\r\n private disposables: Set<Disposable> = new Set();\r\n\r\n add(disposable: Disposable): void {\r\n this.disposables.add(disposable);\r\n }\r\n\r\n dispose(): void {\r\n for (const disposable of this.disposables) {\r\n disposable.dispose();\r\n }\r\n this.disposables.clear();\r\n }\r\n}\r\n","/**\r\n * Centralized constants for MCP Redis library\r\n * Eliminates magic numbers and enables consistent configuration\r\n */\r\n\r\n// Redis TTL and Session Management\r\nexport const SESSION_TTL_SECONDS = 43200; // 12 hours\r\nexport const STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes for OAuth state\r\n\r\n// Heartbeat and Connection\r\nexport const DEFAULT_HEARTBEAT_INTERVAL_MS = 30000; // 30 seconds\r\n\r\n// Redis Key Prefixes\r\nexport const REDIS_KEY_PREFIX = 'mcp:session:';\r\n\r\n// Token Management\r\nexport const TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000; // 5 minute buffer before expiry\r\n\r\n// Client Information\r\nexport const DEFAULT_CLIENT_NAME = 'MCP Assistant';\r\nexport const DEFAULT_CLIENT_URI = 'https://mcp-assistant.in';\r\nexport const DEFAULT_LOGO_URI = 'https://mcp-assistant.in/logo.png';\r\nexport const DEFAULT_POLICY_URI = 'https://mcp-assistant.in/privacy';\r\nexport const SOFTWARE_ID = '@mcp-ts';\r\nexport const SOFTWARE_VERSION = '1.0.0-beta.5';\r\n\r\n// MCP Client Configuration\r\nexport const MCP_CLIENT_NAME = 'mcp-ts-oauth-client';\r\nexport const MCP_CLIENT_VERSION = '2.0';\r\n","/**\r\n * Standardized error classes for MCP Redis library\r\n * Provides consistent error handling across the codebase\r\n */\r\n\r\n/**\r\n * Base error class for all MCP-related errors\r\n */\r\nexport class McpError extends Error {\r\n constructor(\r\n public readonly code: string,\r\n message: string,\r\n public readonly cause?: Error\r\n ) {\r\n super(message);\r\n this.name = 'McpError';\r\n // Maintain proper prototype chain for instanceof checks\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n\r\n toJSON() {\r\n return {\r\n name: this.name,\r\n code: this.code,\r\n message: this.message,\r\n ...(this.cause ? { cause: this.cause.message } : {}),\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth authorization is required\r\n */\r\nexport class UnauthorizedError extends McpError {\r\n constructor(message: string = 'OAuth authorization required', cause?: Error) {\r\n super('UNAUTHORIZED', message, cause);\r\n this.name = 'UnauthorizedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when connection to MCP server fails\r\n */\r\nexport class ConnectionError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONNECTION_ERROR', message, cause);\r\n this.name = 'ConnectionError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session is not found or expired\r\n */\r\nexport class SessionNotFoundError extends McpError {\r\n constructor(sessionId: string, cause?: Error) {\r\n super('SESSION_NOT_FOUND', `Session not found: ${sessionId}`, cause);\r\n this.name = 'SessionNotFoundError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session validation fails\r\n */\r\nexport class SessionValidationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('SESSION_VALIDATION_ERROR', message, cause);\r\n this.name = 'SessionValidationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when authentication fails\r\n */\r\nexport class AuthenticationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('AUTH_ERROR', message, cause);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth state validation fails\r\n */\r\nexport class InvalidStateError extends McpError {\r\n constructor(message: string = 'Invalid OAuth state', cause?: Error) {\r\n super('INVALID_STATE', message, cause);\r\n this.name = 'InvalidStateError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when client is not connected\r\n */\r\nexport class NotConnectedError extends McpError {\r\n constructor(message: string = 'Not connected to server', cause?: Error) {\r\n super('NOT_CONNECTED', message, cause);\r\n this.name = 'NotConnectedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when required configuration is missing\r\n */\r\nexport class ConfigurationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONFIGURATION_ERROR', message, cause);\r\n this.name = 'ConfigurationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when tool execution fails\r\n */\r\nexport class ToolExecutionError extends McpError {\r\n constructor(toolName: string, message: string, cause?: Error) {\r\n super('TOOL_EXECUTION_ERROR', `Tool '${toolName}' failed: ${message}`, cause);\r\n this.name = 'ToolExecutionError';\r\n }\r\n}\r\n\r\n/**\r\n * RPC error codes for SSE communication\r\n */\r\nexport const RpcErrorCodes = {\r\n EXECUTION_ERROR: 'EXECUTION_ERROR',\r\n MISSING_IDENTITY: 'MISSING_IDENTITY',\r\n UNAUTHORIZED: 'UNAUTHORIZED',\r\n NO_CONNECTION: 'NO_CONNECTION',\r\n UNKNOWN_METHOD: 'UNKNOWN_METHOD',\r\n INVALID_PARAMS: 'INVALID_PARAMS',\r\n} as const;\r\n\r\nexport type RpcErrorCode = typeof RpcErrorCodes[keyof typeof RpcErrorCodes];\r\n","/**\r\n * Type definitions for MCP operations\r\n */\r\n\r\nimport { Tool, CallToolResult } from '@modelcontextprotocol/sdk/types.js';\r\n\r\n// Connect API types\r\nexport interface ConnectRequest {\r\n serverUrl: string;\r\n callbackUrl: string;\r\n}\r\n\r\nexport interface ConnectSuccessResponse {\r\n success: true;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectAuthRequiredResponse {\r\n requiresAuth: true;\r\n authUrl: string;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ConnectResponse =\r\n | ConnectSuccessResponse\r\n | ConnectAuthRequiredResponse\r\n | ConnectErrorResponse;\r\n\r\n// Callback API types\r\nexport interface CallbackSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface CallbackErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallbackResponse = CallbackSuccessResponse | CallbackErrorResponse;\r\n\r\n// Disconnect API types\r\nexport interface DisconnectRequest {\r\n sessionId: string;\r\n}\r\n\r\nexport interface DisconnectSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface DisconnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type DisconnectResponse =\r\n | DisconnectSuccessResponse\r\n | DisconnectErrorResponse;\r\n\r\n// List Tools API types\r\nexport interface ListToolsSuccessResponse {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListToolsErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ListToolsResponse =\r\n | ListToolsSuccessResponse\r\n | ListToolsErrorResponse;\r\n\r\n// Call Tool API types\r\nexport interface CallToolRequest {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface CallToolSuccessResponse {\r\n content: Array<{\r\n type: string;\r\n text?: string;\r\n [key: string]: unknown;\r\n }>;\r\n isError: boolean;\r\n}\r\n\r\nexport interface CallToolErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallToolResponse =\r\n | CallToolSuccessResponse\r\n | CallToolErrorResponse;\r\n\r\n// Helper type guards\r\nexport function isConnectSuccess(\r\n response: ConnectResponse\r\n): response is ConnectSuccessResponse {\r\n return 'success' in response && response.success === true;\r\n}\r\n\r\nexport function isConnectAuthRequired(\r\n response: ConnectResponse\r\n): response is ConnectAuthRequiredResponse {\r\n return 'requiresAuth' in response && response.requiresAuth === true;\r\n}\r\n\r\nexport function isConnectError(\r\n response: ConnectResponse\r\n): response is ConnectErrorResponse {\r\n return 'error' in response;\r\n}\r\n\r\nexport function isListToolsSuccess(\r\n response: ListToolsResponse\r\n): response is ListToolsSuccessResponse {\r\n return 'tools' in response;\r\n}\r\n\r\nexport function isCallToolSuccess(\r\n response: CallToolResponse\r\n): response is CallToolSuccessResponse {\r\n return 'content' in response;\r\n}\r\n\r\n// Generic tool info type\r\nexport type ToolInfo = {\r\n name: string;\r\n description?: string;\r\n inputSchema?: unknown;\r\n};\r\n\r\n// Transport type\r\nexport type TransportType = 'sse' | 'streamable_http';\r\n\r\n// SSE/RPC types\r\nexport type McpRpcMethod =\r\n | 'connect'\r\n | 'disconnect'\r\n | 'listTools'\r\n | 'callTool'\r\n | 'getSessions'\r\n | 'restoreSession'\r\n | 'finishAuth'\r\n | 'listPrompts'\r\n | 'getPrompt'\r\n | 'listResources'\r\n | 'readResource';\r\n\r\nexport interface McpRpcRequest {\r\n id: string;\r\n method: McpRpcMethod;\r\n params?: McpRpcParams;\r\n}\r\n\r\nexport interface McpRpcResponse<T = unknown> {\r\n id: string;\r\n result?: T;\r\n error?: {\r\n code: string;\r\n message: string;\r\n };\r\n}\r\n\r\n// RPC Parameter Types\r\nexport interface ConnectParams {\r\n serverId?: string; // Optional - generated server-side if not provided\r\n serverName: string;\r\n serverUrl: string;\r\n callbackUrl: string;\r\n transportType?: TransportType;\r\n}\r\n\r\nexport interface DisconnectParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface SessionParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface CallToolParams {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface GetPromptParams {\r\n sessionId: string;\r\n name: string;\r\n args?: Record<string, string>;\r\n}\r\n\r\nexport interface ReadResourceParams {\r\n sessionId: string;\r\n uri: string;\r\n}\r\n\r\nexport interface FinishAuthParams {\r\n sessionId: string;\r\n code: string;\r\n}\r\n\r\nexport type McpRpcParams =\r\n | ConnectParams\r\n | DisconnectParams\r\n | SessionParams\r\n | CallToolParams\r\n | GetPromptParams\r\n | ReadResourceParams\r\n | FinishAuthParams\r\n | undefined;\r\n\r\n// RPC Result Types\r\nexport interface SessionInfo {\r\n sessionId: string;\r\n serverId?: string;\r\n serverName?: string;\r\n serverUrl: string;\r\n transport: TransportType;\r\n}\r\n\r\nexport interface SessionListResult {\r\n sessions: SessionInfo[];\r\n}\r\n\r\nexport interface ConnectResult {\r\n sessionId: string;\r\n success: boolean;\r\n}\r\n\r\nexport interface DisconnectResult {\r\n success: boolean;\r\n}\r\n\r\nexport interface RestoreSessionResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface FinishAuthResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface ListToolsRpcResult {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListPromptsResult {\r\n prompts: Array<{\r\n name: string;\r\n description?: string;\r\n arguments?: Array<{\r\n name: string;\r\n description?: string;\r\n required?: boolean;\r\n }>;\r\n }>;\r\n}\r\n\r\nexport interface ListResourcesResult {\r\n resources: Array<{\r\n uri: string;\r\n name: string;\r\n description?: string;\r\n mimeType?: string;\r\n }>;\r\n}\r\n\r\nexport type { CallToolResult };\r\n","/**\r\n * Sanitize server name to create a valid server label\r\n * Must start with a letter and contain only letters, digits, '-' and '_'\r\n */\r\nexport function sanitizeServerLabel(name: string): string {\r\n let sanitized = name\r\n .replace(/[^a-zA-Z0-9-_]/g, '_')\r\n .replace(/_{2,}/g, '_')\r\n .toLowerCase();\r\n\r\n if (!/^[a-zA-Z]/.test(sanitized)) {\r\n sanitized = 's_' + sanitized;\r\n }\r\n\r\n return sanitized;\r\n}\r\n","/**\r\n * Utility functions for working with MCP tool metadata\r\n */\r\n\r\nimport type { ToolInfo } from './types.js';\r\n\r\nexport interface ToolUiConfig {\r\n resourceUri: string;\r\n sessionId: string;\r\n}\r\n\r\n/**\r\n * Extract UI resource URI from tool metadata\r\n *\r\n * @param tool - The tool to extract UI config from\r\n * @returns The resource URI if available, undefined otherwise\r\n *\r\n * @example\r\n * const uri = getToolUiResourceUri(tool);\r\n * if (uri) {\r\n * // Tool has UI configuration\r\n * }\r\n */\r\nexport function getToolUiResourceUri(tool: ToolInfo): string | undefined {\r\n const meta = (tool as any)._meta;\r\n if (!meta?.ui) return undefined;\r\n\r\n const ui = meta.ui;\r\n if (typeof ui !== \"object\" || !ui) return undefined;\r\n\r\n // Check visibility filter - skip if explicitly hidden from app\r\n if (ui.visibility && !ui.visibility.includes(\"app\")) return undefined;\r\n\r\n // Support both 'uri' and 'resourceUri' field names for flexibility\r\n return typeof ui.resourceUri === \"string\"\r\n ? ui.resourceUri\r\n : typeof ui.uri === \"string\"\r\n ? ui.uri\r\n : undefined;\r\n}\r\n\r\n/**\r\n * Find a tool by name within connections\r\n *\r\n * @param connections - Array of MCP connections\r\n * @param toolName - Name of the tool to find\r\n * @returns The tool if found, undefined otherwise\r\n *\r\n * @example\r\n * const tool = findToolByName(connections, \"get_weather\");\r\n */\r\nexport function findToolByName(\r\n connections: Array<{ tools: ToolInfo[] }>,\r\n toolName: string\r\n): ToolInfo | undefined {\r\n for (const conn of connections) {\r\n const tool = conn.tools.find((t) => t.name === toolName);\r\n if (tool) return tool;\r\n }\r\n return undefined;\r\n}\r\n"]}
@@ -185,6 +185,23 @@ function sanitizeServerLabel(name) {
185
185
  return sanitized;
186
186
  }
187
187
 
188
- export { AuthenticationError, ConfigurationError, ConnectionError, DEFAULT_CLIENT_NAME, DEFAULT_CLIENT_URI, DEFAULT_HEARTBEAT_INTERVAL_MS, DEFAULT_LOGO_URI, DEFAULT_POLICY_URI, DisposableStore, Emitter, InvalidStateError, MCP_CLIENT_NAME, MCP_CLIENT_VERSION, McpError, NotConnectedError, REDIS_KEY_PREFIX, RpcErrorCodes, SESSION_TTL_SECONDS, SOFTWARE_ID, SOFTWARE_VERSION, STATE_EXPIRATION_MS, SessionNotFoundError, SessionValidationError, TOKEN_EXPIRY_BUFFER_MS, ToolExecutionError, UnauthorizedError, isCallToolSuccess, isConnectAuthRequired, isConnectError, isConnectSuccess, isListToolsSuccess, sanitizeServerLabel };
188
+ // src/shared/tool-utils.ts
189
+ function getToolUiResourceUri(tool) {
190
+ const meta = tool._meta;
191
+ if (!meta?.ui) return void 0;
192
+ const ui = meta.ui;
193
+ if (typeof ui !== "object" || !ui) return void 0;
194
+ if (ui.visibility && !ui.visibility.includes("app")) return void 0;
195
+ return typeof ui.resourceUri === "string" ? ui.resourceUri : typeof ui.uri === "string" ? ui.uri : void 0;
196
+ }
197
+ function findToolByName(connections, toolName) {
198
+ for (const conn of connections) {
199
+ const tool = conn.tools.find((t) => t.name === toolName);
200
+ if (tool) return tool;
201
+ }
202
+ return void 0;
203
+ }
204
+
205
+ export { AuthenticationError, ConfigurationError, ConnectionError, DEFAULT_CLIENT_NAME, DEFAULT_CLIENT_URI, DEFAULT_HEARTBEAT_INTERVAL_MS, DEFAULT_LOGO_URI, DEFAULT_POLICY_URI, DisposableStore, Emitter, InvalidStateError, MCP_CLIENT_NAME, MCP_CLIENT_VERSION, McpError, NotConnectedError, REDIS_KEY_PREFIX, RpcErrorCodes, SESSION_TTL_SECONDS, SOFTWARE_ID, SOFTWARE_VERSION, STATE_EXPIRATION_MS, SessionNotFoundError, SessionValidationError, TOKEN_EXPIRY_BUFFER_MS, ToolExecutionError, UnauthorizedError, findToolByName, getToolUiResourceUri, isCallToolSuccess, isConnectAuthRequired, isConnectError, isConnectSuccess, isListToolsSuccess, sanitizeServerLabel };
189
206
  //# sourceMappingURL=index.mjs.map
190
207
  //# sourceMappingURL=index.mjs.map
@@ -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"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * Simple event emitter pattern for MCP connection events\r\n * Inspired by Cloudflare's agents pattern but adapted for serverless\r\n */\r\n\r\nexport type Disposable = {\r\n dispose(): void;\r\n};\r\n\r\nexport type Event<T> = (listener: (event: T) => void) => Disposable;\r\n\r\n/**\r\n * Event emitter class for type-safe event handling\r\n * Similar to Cloudflare's Emitter but simplified for our use case\r\n */\r\nexport class Emitter<T> {\r\n private listeners: Set<(event: T) => void> = new Set();\r\n\r\n /**\r\n * Subscribe to events\r\n * @param listener - Callback function to handle events\r\n * @returns Disposable to unsubscribe\r\n */\r\n get event(): Event<T> {\r\n return (listener: (event: T) => void) => {\r\n this.listeners.add(listener);\r\n return {\r\n dispose: () => {\r\n this.listeners.delete(listener);\r\n },\r\n };\r\n };\r\n }\r\n\r\n /**\r\n * Fire an event to all listeners\r\n * @param event - Event data to emit\r\n */\r\n fire(event: T): void {\r\n for (const listener of this.listeners) {\r\n try {\r\n listener(event);\r\n } catch (error) {\r\n console.error('[Emitter] Error in event listener:', error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear all listeners\r\n */\r\n dispose(): void {\r\n this.listeners.clear();\r\n }\r\n\r\n /**\r\n * Get number of active listeners\r\n */\r\n get listenerCount(): number {\r\n return this.listeners.size;\r\n }\r\n}\r\n\r\n/**\r\n * Connection state types matching your existing ConnectionStatus\r\n * Extended with more granular states for better observability\r\n */\r\nexport type McpConnectionState =\r\n | 'DISCONNECTED' // Not connected\r\n | 'CONNECTING' // Establishing transport connection to MCP server\r\n | 'AUTHENTICATING' // OAuth flow in progress\r\n | 'AUTHENTICATED' // OAuth complete, pre-connect\r\n | 'DISCOVERING' // Discovering server capabilities (tools, resources, prompts)\r\n | 'CONNECTED' // Transport connection established\r\n | 'READY' // Fully connected and ready to use\r\n | 'VALIDATING' // Validating existing session\r\n | 'RECONNECTING' // Attempting to reconnect\r\n | 'INITIALIZING' // Initializing session or connection\r\n | 'FAILED'; // Connection error at some point\r\n\r\n/**\r\n * MCP Connection Event Types\r\n * Discriminated union for type-safe event handling\r\n */\r\nexport type McpConnectionEvent =\r\n | {\r\n type: 'state_changed';\r\n sessionId: string;\r\n serverId: string;\r\n serverName: string;\r\n state: McpConnectionState;\r\n previousState: McpConnectionState;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'tools_discovered';\r\n sessionId: string;\r\n serverId: string;\r\n toolCount: number;\r\n tools: any[];\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'auth_required';\r\n sessionId: string;\r\n serverId: string;\r\n authUrl: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'error';\r\n sessionId: string;\r\n serverId: string;\r\n error: string;\r\n errorType: 'connection' | 'auth' | 'validation' | 'unknown';\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'disconnected';\r\n sessionId: string;\r\n serverId: string;\r\n reason?: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'progress';\r\n sessionId: string;\r\n serverId: string;\r\n message: string;\r\n timestamp: number;\r\n };\r\n\r\n/**\r\n * Event fired when a tool execution returns a UI resource URI\r\n */\r\nexport interface McpAppsUIEvent {\r\n type: 'mcp-apps-ui';\r\n sessionId: string;\r\n resourceUri: string;\r\n toolName: string;\r\n result: unknown;\r\n timestamp: number;\r\n}\r\n\r\n/**\r\n * Observability event for debugging and monitoring\r\n */\r\nexport interface McpObservabilityEvent {\r\n type?: string;\r\n level?: 'debug' | 'info' | 'warn' | 'error';\r\n message?: string;\r\n displayMessage?: string;\r\n sessionId?: string;\r\n serverId?: string;\r\n payload?: Record<string, any>;\r\n metadata?: Record<string, any>; // Kept for backward compatibility\r\n timestamp: number;\r\n id?: string;\r\n}\r\n\r\n/**\r\n * DisposableStore for managing multiple disposables\r\n * Useful for cleanup in React hooks\r\n */\r\nexport class DisposableStore {\r\n private disposables: Set<Disposable> = new Set();\r\n\r\n add(disposable: Disposable): void {\r\n this.disposables.add(disposable);\r\n }\r\n\r\n dispose(): void {\r\n for (const disposable of this.disposables) {\r\n disposable.dispose();\r\n }\r\n this.disposables.clear();\r\n }\r\n}\r\n","/**\r\n * Centralized constants for MCP Redis library\r\n * Eliminates magic numbers and enables consistent configuration\r\n */\r\n\r\n// Redis TTL and Session Management\r\nexport const SESSION_TTL_SECONDS = 43200; // 12 hours\r\nexport const STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes for OAuth state\r\n\r\n// Heartbeat and Connection\r\nexport const DEFAULT_HEARTBEAT_INTERVAL_MS = 30000; // 30 seconds\r\n\r\n// Redis Key Prefixes\r\nexport const REDIS_KEY_PREFIX = 'mcp:session:';\r\n\r\n// Token Management\r\nexport const TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000; // 5 minute buffer before expiry\r\n\r\n// Client Information\r\nexport const DEFAULT_CLIENT_NAME = 'MCP Assistant';\r\nexport const DEFAULT_CLIENT_URI = 'https://mcp-assistant.in';\r\nexport const DEFAULT_LOGO_URI = 'https://mcp-assistant.in/logo.png';\r\nexport const DEFAULT_POLICY_URI = 'https://mcp-assistant.in/privacy';\r\nexport const SOFTWARE_ID = '@mcp-ts';\r\nexport const SOFTWARE_VERSION = '1.0.0-beta.5';\r\n\r\n// MCP Client Configuration\r\nexport const MCP_CLIENT_NAME = 'mcp-ts-oauth-client';\r\nexport const MCP_CLIENT_VERSION = '2.0';\r\n","/**\r\n * Standardized error classes for MCP Redis library\r\n * Provides consistent error handling across the codebase\r\n */\r\n\r\n/**\r\n * Base error class for all MCP-related errors\r\n */\r\nexport class McpError extends Error {\r\n constructor(\r\n public readonly code: string,\r\n message: string,\r\n public readonly cause?: Error\r\n ) {\r\n super(message);\r\n this.name = 'McpError';\r\n // Maintain proper prototype chain for instanceof checks\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n\r\n toJSON() {\r\n return {\r\n name: this.name,\r\n code: this.code,\r\n message: this.message,\r\n ...(this.cause ? { cause: this.cause.message } : {}),\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth authorization is required\r\n */\r\nexport class UnauthorizedError extends McpError {\r\n constructor(message: string = 'OAuth authorization required', cause?: Error) {\r\n super('UNAUTHORIZED', message, cause);\r\n this.name = 'UnauthorizedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when connection to MCP server fails\r\n */\r\nexport class ConnectionError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONNECTION_ERROR', message, cause);\r\n this.name = 'ConnectionError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session is not found or expired\r\n */\r\nexport class SessionNotFoundError extends McpError {\r\n constructor(sessionId: string, cause?: Error) {\r\n super('SESSION_NOT_FOUND', `Session not found: ${sessionId}`, cause);\r\n this.name = 'SessionNotFoundError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session validation fails\r\n */\r\nexport class SessionValidationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('SESSION_VALIDATION_ERROR', message, cause);\r\n this.name = 'SessionValidationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when authentication fails\r\n */\r\nexport class AuthenticationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('AUTH_ERROR', message, cause);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth state validation fails\r\n */\r\nexport class InvalidStateError extends McpError {\r\n constructor(message: string = 'Invalid OAuth state', cause?: Error) {\r\n super('INVALID_STATE', message, cause);\r\n this.name = 'InvalidStateError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when client is not connected\r\n */\r\nexport class NotConnectedError extends McpError {\r\n constructor(message: string = 'Not connected to server', cause?: Error) {\r\n super('NOT_CONNECTED', message, cause);\r\n this.name = 'NotConnectedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when required configuration is missing\r\n */\r\nexport class ConfigurationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONFIGURATION_ERROR', message, cause);\r\n this.name = 'ConfigurationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when tool execution fails\r\n */\r\nexport class ToolExecutionError extends McpError {\r\n constructor(toolName: string, message: string, cause?: Error) {\r\n super('TOOL_EXECUTION_ERROR', `Tool '${toolName}' failed: ${message}`, cause);\r\n this.name = 'ToolExecutionError';\r\n }\r\n}\r\n\r\n/**\r\n * RPC error codes for SSE communication\r\n */\r\nexport const RpcErrorCodes = {\r\n EXECUTION_ERROR: 'EXECUTION_ERROR',\r\n MISSING_IDENTITY: 'MISSING_IDENTITY',\r\n UNAUTHORIZED: 'UNAUTHORIZED',\r\n NO_CONNECTION: 'NO_CONNECTION',\r\n UNKNOWN_METHOD: 'UNKNOWN_METHOD',\r\n INVALID_PARAMS: 'INVALID_PARAMS',\r\n} as const;\r\n\r\nexport type RpcErrorCode = typeof RpcErrorCodes[keyof typeof RpcErrorCodes];\r\n","/**\r\n * Type definitions for MCP operations\r\n */\r\n\r\nimport { Tool, CallToolResult } from '@modelcontextprotocol/sdk/types.js';\r\n\r\n// Connect API types\r\nexport interface ConnectRequest {\r\n serverUrl: string;\r\n callbackUrl: string;\r\n}\r\n\r\nexport interface ConnectSuccessResponse {\r\n success: true;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectAuthRequiredResponse {\r\n requiresAuth: true;\r\n authUrl: string;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ConnectResponse =\r\n | ConnectSuccessResponse\r\n | ConnectAuthRequiredResponse\r\n | ConnectErrorResponse;\r\n\r\n// Callback API types\r\nexport interface CallbackSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface CallbackErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallbackResponse = CallbackSuccessResponse | CallbackErrorResponse;\r\n\r\n// Disconnect API types\r\nexport interface DisconnectRequest {\r\n sessionId: string;\r\n}\r\n\r\nexport interface DisconnectSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface DisconnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type DisconnectResponse =\r\n | DisconnectSuccessResponse\r\n | DisconnectErrorResponse;\r\n\r\n// List Tools API types\r\nexport interface ListToolsSuccessResponse {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListToolsErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ListToolsResponse =\r\n | ListToolsSuccessResponse\r\n | ListToolsErrorResponse;\r\n\r\n// Call Tool API types\r\nexport interface CallToolRequest {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface CallToolSuccessResponse {\r\n content: Array<{\r\n type: string;\r\n text?: string;\r\n [key: string]: unknown;\r\n }>;\r\n isError: boolean;\r\n}\r\n\r\nexport interface CallToolErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallToolResponse =\r\n | CallToolSuccessResponse\r\n | CallToolErrorResponse;\r\n\r\n// Helper type guards\r\nexport function isConnectSuccess(\r\n response: ConnectResponse\r\n): response is ConnectSuccessResponse {\r\n return 'success' in response && response.success === true;\r\n}\r\n\r\nexport function isConnectAuthRequired(\r\n response: ConnectResponse\r\n): response is ConnectAuthRequiredResponse {\r\n return 'requiresAuth' in response && response.requiresAuth === true;\r\n}\r\n\r\nexport function isConnectError(\r\n response: ConnectResponse\r\n): response is ConnectErrorResponse {\r\n return 'error' in response;\r\n}\r\n\r\nexport function isListToolsSuccess(\r\n response: ListToolsResponse\r\n): response is ListToolsSuccessResponse {\r\n return 'tools' in response;\r\n}\r\n\r\nexport function isCallToolSuccess(\r\n response: CallToolResponse\r\n): response is CallToolSuccessResponse {\r\n return 'content' in response;\r\n}\r\n\r\n// Generic tool info type\r\nexport type ToolInfo = {\r\n name: string;\r\n description?: string;\r\n inputSchema?: unknown;\r\n};\r\n\r\n// Transport type\r\nexport type TransportType = 'sse' | 'streamable_http';\r\n\r\n// SSE/RPC types\r\nexport type McpRpcMethod =\r\n | 'connect'\r\n | 'disconnect'\r\n | 'listTools'\r\n | 'callTool'\r\n | 'getSessions'\r\n | 'restoreSession'\r\n | 'finishAuth'\r\n | 'listPrompts'\r\n | 'getPrompt'\r\n | 'listResources'\r\n | 'readResource';\r\n\r\nexport interface McpRpcRequest {\r\n id: string;\r\n method: McpRpcMethod;\r\n params?: McpRpcParams;\r\n}\r\n\r\nexport interface McpRpcResponse<T = unknown> {\r\n id: string;\r\n result?: T;\r\n error?: {\r\n code: string;\r\n message: string;\r\n };\r\n}\r\n\r\n// RPC Parameter Types\r\nexport interface ConnectParams {\r\n serverId?: string; // Optional - generated server-side if not provided\r\n serverName: string;\r\n serverUrl: string;\r\n callbackUrl: string;\r\n transportType?: TransportType;\r\n}\r\n\r\nexport interface DisconnectParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface SessionParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface CallToolParams {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface GetPromptParams {\r\n sessionId: string;\r\n name: string;\r\n args?: Record<string, string>;\r\n}\r\n\r\nexport interface ReadResourceParams {\r\n sessionId: string;\r\n uri: string;\r\n}\r\n\r\nexport interface FinishAuthParams {\r\n sessionId: string;\r\n code: string;\r\n}\r\n\r\nexport type McpRpcParams =\r\n | ConnectParams\r\n | DisconnectParams\r\n | SessionParams\r\n | CallToolParams\r\n | GetPromptParams\r\n | ReadResourceParams\r\n | FinishAuthParams\r\n | undefined;\r\n\r\n// RPC Result Types\r\nexport interface SessionInfo {\r\n sessionId: string;\r\n serverId?: string;\r\n serverName?: string;\r\n serverUrl: string;\r\n transport: TransportType;\r\n}\r\n\r\nexport interface SessionListResult {\r\n sessions: SessionInfo[];\r\n}\r\n\r\nexport interface ConnectResult {\r\n sessionId: string;\r\n success: boolean;\r\n}\r\n\r\nexport interface DisconnectResult {\r\n success: boolean;\r\n}\r\n\r\nexport interface RestoreSessionResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface FinishAuthResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface ListToolsRpcResult {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListPromptsResult {\r\n prompts: Array<{\r\n name: string;\r\n description?: string;\r\n arguments?: Array<{\r\n name: string;\r\n description?: string;\r\n required?: boolean;\r\n }>;\r\n }>;\r\n}\r\n\r\nexport interface ListResourcesResult {\r\n resources: Array<{\r\n uri: string;\r\n name: string;\r\n description?: string;\r\n mimeType?: string;\r\n }>;\r\n}\r\n\r\nexport type { CallToolResult };\r\n","/**\r\n * Sanitize server name to create a valid server label\r\n * Must start with a letter and contain only letters, digits, '-' and '_'\r\n */\r\nexport function sanitizeServerLabel(name: string): string {\r\n let sanitized = name\r\n .replace(/[^a-zA-Z0-9-_]/g, '_')\r\n .replace(/_{2,}/g, '_')\r\n .toLowerCase();\r\n\r\n if (!/^[a-zA-Z]/.test(sanitized)) {\r\n sanitized = 's_' + sanitized;\r\n }\r\n\r\n return sanitized;\r\n}\r\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"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * Simple event emitter pattern for MCP connection events\r\n * Inspired by Cloudflare's agents pattern but adapted for serverless\r\n */\r\n\r\nexport type Disposable = {\r\n dispose(): void;\r\n};\r\n\r\nexport type Event<T> = (listener: (event: T) => void) => Disposable;\r\n\r\n/**\r\n * Event emitter class for type-safe event handling\r\n * Similar to Cloudflare's Emitter but simplified for our use case\r\n */\r\nexport class Emitter<T> {\r\n private listeners: Set<(event: T) => void> = new Set();\r\n\r\n /**\r\n * Subscribe to events\r\n * @param listener - Callback function to handle events\r\n * @returns Disposable to unsubscribe\r\n */\r\n get event(): Event<T> {\r\n return (listener: (event: T) => void) => {\r\n this.listeners.add(listener);\r\n return {\r\n dispose: () => {\r\n this.listeners.delete(listener);\r\n },\r\n };\r\n };\r\n }\r\n\r\n /**\r\n * Fire an event to all listeners\r\n * @param event - Event data to emit\r\n */\r\n fire(event: T): void {\r\n for (const listener of this.listeners) {\r\n try {\r\n listener(event);\r\n } catch (error) {\r\n console.error('[Emitter] Error in event listener:', error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear all listeners\r\n */\r\n dispose(): void {\r\n this.listeners.clear();\r\n }\r\n\r\n /**\r\n * Get number of active listeners\r\n */\r\n get listenerCount(): number {\r\n return this.listeners.size;\r\n }\r\n}\r\n\r\n/**\r\n * Connection state types matching your existing ConnectionStatus\r\n * Extended with more granular states for better observability\r\n */\r\nexport type McpConnectionState =\r\n | 'DISCONNECTED' // Not connected\r\n | 'CONNECTING' // Establishing transport connection to MCP server\r\n | 'AUTHENTICATING' // OAuth flow in progress\r\n | 'AUTHENTICATED' // OAuth complete, pre-connect\r\n | 'DISCOVERING' // Discovering server capabilities (tools, resources, prompts)\r\n | 'CONNECTED' // Transport connection established\r\n | 'READY' // Fully connected and ready to use\r\n | 'VALIDATING' // Validating existing session\r\n | 'RECONNECTING' // Attempting to reconnect\r\n | 'INITIALIZING' // Initializing session or connection\r\n | 'FAILED'; // Connection error at some point\r\n\r\n/**\r\n * MCP Connection Event Types\r\n * Discriminated union for type-safe event handling\r\n */\r\nexport type McpConnectionEvent =\r\n | {\r\n type: 'state_changed';\r\n sessionId: string;\r\n serverId: string;\r\n serverName: string;\r\n state: McpConnectionState;\r\n previousState: McpConnectionState;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'tools_discovered';\r\n sessionId: string;\r\n serverId: string;\r\n toolCount: number;\r\n tools: any[];\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'auth_required';\r\n sessionId: string;\r\n serverId: string;\r\n authUrl: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'error';\r\n sessionId: string;\r\n serverId: string;\r\n error: string;\r\n errorType: 'connection' | 'auth' | 'validation' | 'unknown';\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'disconnected';\r\n sessionId: string;\r\n serverId: string;\r\n reason?: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'progress';\r\n sessionId: string;\r\n serverId: string;\r\n message: string;\r\n timestamp: number;\r\n };\r\n\r\n/**\r\n * Event fired when a tool execution returns a UI resource URI\r\n */\r\nexport interface McpAppsUIEvent {\r\n type: 'mcp-apps-ui';\r\n sessionId: string;\r\n resourceUri: string;\r\n toolName: string;\r\n result: unknown;\r\n timestamp: number;\r\n}\r\n\r\n/**\r\n * Observability event for debugging and monitoring\r\n */\r\nexport interface McpObservabilityEvent {\r\n type?: string;\r\n level?: 'debug' | 'info' | 'warn' | 'error';\r\n message?: string;\r\n displayMessage?: string;\r\n sessionId?: string;\r\n serverId?: string;\r\n payload?: Record<string, any>;\r\n metadata?: Record<string, any>; // Kept for backward compatibility\r\n timestamp: number;\r\n id?: string;\r\n}\r\n\r\n/**\r\n * DisposableStore for managing multiple disposables\r\n * Useful for cleanup in React hooks\r\n */\r\nexport class DisposableStore {\r\n private disposables: Set<Disposable> = new Set();\r\n\r\n add(disposable: Disposable): void {\r\n this.disposables.add(disposable);\r\n }\r\n\r\n dispose(): void {\r\n for (const disposable of this.disposables) {\r\n disposable.dispose();\r\n }\r\n this.disposables.clear();\r\n }\r\n}\r\n","/**\r\n * Centralized constants for MCP Redis library\r\n * Eliminates magic numbers and enables consistent configuration\r\n */\r\n\r\n// Redis TTL and Session Management\r\nexport const SESSION_TTL_SECONDS = 43200; // 12 hours\r\nexport const STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes for OAuth state\r\n\r\n// Heartbeat and Connection\r\nexport const DEFAULT_HEARTBEAT_INTERVAL_MS = 30000; // 30 seconds\r\n\r\n// Redis Key Prefixes\r\nexport const REDIS_KEY_PREFIX = 'mcp:session:';\r\n\r\n// Token Management\r\nexport const TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000; // 5 minute buffer before expiry\r\n\r\n// Client Information\r\nexport const DEFAULT_CLIENT_NAME = 'MCP Assistant';\r\nexport const DEFAULT_CLIENT_URI = 'https://mcp-assistant.in';\r\nexport const DEFAULT_LOGO_URI = 'https://mcp-assistant.in/logo.png';\r\nexport const DEFAULT_POLICY_URI = 'https://mcp-assistant.in/privacy';\r\nexport const SOFTWARE_ID = '@mcp-ts';\r\nexport const SOFTWARE_VERSION = '1.0.0-beta.5';\r\n\r\n// MCP Client Configuration\r\nexport const MCP_CLIENT_NAME = 'mcp-ts-oauth-client';\r\nexport const MCP_CLIENT_VERSION = '2.0';\r\n","/**\r\n * Standardized error classes for MCP Redis library\r\n * Provides consistent error handling across the codebase\r\n */\r\n\r\n/**\r\n * Base error class for all MCP-related errors\r\n */\r\nexport class McpError extends Error {\r\n constructor(\r\n public readonly code: string,\r\n message: string,\r\n public readonly cause?: Error\r\n ) {\r\n super(message);\r\n this.name = 'McpError';\r\n // Maintain proper prototype chain for instanceof checks\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n\r\n toJSON() {\r\n return {\r\n name: this.name,\r\n code: this.code,\r\n message: this.message,\r\n ...(this.cause ? { cause: this.cause.message } : {}),\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth authorization is required\r\n */\r\nexport class UnauthorizedError extends McpError {\r\n constructor(message: string = 'OAuth authorization required', cause?: Error) {\r\n super('UNAUTHORIZED', message, cause);\r\n this.name = 'UnauthorizedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when connection to MCP server fails\r\n */\r\nexport class ConnectionError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONNECTION_ERROR', message, cause);\r\n this.name = 'ConnectionError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session is not found or expired\r\n */\r\nexport class SessionNotFoundError extends McpError {\r\n constructor(sessionId: string, cause?: Error) {\r\n super('SESSION_NOT_FOUND', `Session not found: ${sessionId}`, cause);\r\n this.name = 'SessionNotFoundError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session validation fails\r\n */\r\nexport class SessionValidationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('SESSION_VALIDATION_ERROR', message, cause);\r\n this.name = 'SessionValidationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when authentication fails\r\n */\r\nexport class AuthenticationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('AUTH_ERROR', message, cause);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth state validation fails\r\n */\r\nexport class InvalidStateError extends McpError {\r\n constructor(message: string = 'Invalid OAuth state', cause?: Error) {\r\n super('INVALID_STATE', message, cause);\r\n this.name = 'InvalidStateError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when client is not connected\r\n */\r\nexport class NotConnectedError extends McpError {\r\n constructor(message: string = 'Not connected to server', cause?: Error) {\r\n super('NOT_CONNECTED', message, cause);\r\n this.name = 'NotConnectedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when required configuration is missing\r\n */\r\nexport class ConfigurationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONFIGURATION_ERROR', message, cause);\r\n this.name = 'ConfigurationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when tool execution fails\r\n */\r\nexport class ToolExecutionError extends McpError {\r\n constructor(toolName: string, message: string, cause?: Error) {\r\n super('TOOL_EXECUTION_ERROR', `Tool '${toolName}' failed: ${message}`, cause);\r\n this.name = 'ToolExecutionError';\r\n }\r\n}\r\n\r\n/**\r\n * RPC error codes for SSE communication\r\n */\r\nexport const RpcErrorCodes = {\r\n EXECUTION_ERROR: 'EXECUTION_ERROR',\r\n MISSING_IDENTITY: 'MISSING_IDENTITY',\r\n UNAUTHORIZED: 'UNAUTHORIZED',\r\n NO_CONNECTION: 'NO_CONNECTION',\r\n UNKNOWN_METHOD: 'UNKNOWN_METHOD',\r\n INVALID_PARAMS: 'INVALID_PARAMS',\r\n} as const;\r\n\r\nexport type RpcErrorCode = typeof RpcErrorCodes[keyof typeof RpcErrorCodes];\r\n","/**\r\n * Type definitions for MCP operations\r\n */\r\n\r\nimport { Tool, CallToolResult } from '@modelcontextprotocol/sdk/types.js';\r\n\r\n// Connect API types\r\nexport interface ConnectRequest {\r\n serverUrl: string;\r\n callbackUrl: string;\r\n}\r\n\r\nexport interface ConnectSuccessResponse {\r\n success: true;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectAuthRequiredResponse {\r\n requiresAuth: true;\r\n authUrl: string;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ConnectResponse =\r\n | ConnectSuccessResponse\r\n | ConnectAuthRequiredResponse\r\n | ConnectErrorResponse;\r\n\r\n// Callback API types\r\nexport interface CallbackSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface CallbackErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallbackResponse = CallbackSuccessResponse | CallbackErrorResponse;\r\n\r\n// Disconnect API types\r\nexport interface DisconnectRequest {\r\n sessionId: string;\r\n}\r\n\r\nexport interface DisconnectSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface DisconnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type DisconnectResponse =\r\n | DisconnectSuccessResponse\r\n | DisconnectErrorResponse;\r\n\r\n// List Tools API types\r\nexport interface ListToolsSuccessResponse {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListToolsErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ListToolsResponse =\r\n | ListToolsSuccessResponse\r\n | ListToolsErrorResponse;\r\n\r\n// Call Tool API types\r\nexport interface CallToolRequest {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface CallToolSuccessResponse {\r\n content: Array<{\r\n type: string;\r\n text?: string;\r\n [key: string]: unknown;\r\n }>;\r\n isError: boolean;\r\n}\r\n\r\nexport interface CallToolErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallToolResponse =\r\n | CallToolSuccessResponse\r\n | CallToolErrorResponse;\r\n\r\n// Helper type guards\r\nexport function isConnectSuccess(\r\n response: ConnectResponse\r\n): response is ConnectSuccessResponse {\r\n return 'success' in response && response.success === true;\r\n}\r\n\r\nexport function isConnectAuthRequired(\r\n response: ConnectResponse\r\n): response is ConnectAuthRequiredResponse {\r\n return 'requiresAuth' in response && response.requiresAuth === true;\r\n}\r\n\r\nexport function isConnectError(\r\n response: ConnectResponse\r\n): response is ConnectErrorResponse {\r\n return 'error' in response;\r\n}\r\n\r\nexport function isListToolsSuccess(\r\n response: ListToolsResponse\r\n): response is ListToolsSuccessResponse {\r\n return 'tools' in response;\r\n}\r\n\r\nexport function isCallToolSuccess(\r\n response: CallToolResponse\r\n): response is CallToolSuccessResponse {\r\n return 'content' in response;\r\n}\r\n\r\n// Generic tool info type\r\nexport type ToolInfo = {\r\n name: string;\r\n description?: string;\r\n inputSchema?: unknown;\r\n};\r\n\r\n// Transport type\r\nexport type TransportType = 'sse' | 'streamable_http';\r\n\r\n// SSE/RPC types\r\nexport type McpRpcMethod =\r\n | 'connect'\r\n | 'disconnect'\r\n | 'listTools'\r\n | 'callTool'\r\n | 'getSessions'\r\n | 'restoreSession'\r\n | 'finishAuth'\r\n | 'listPrompts'\r\n | 'getPrompt'\r\n | 'listResources'\r\n | 'readResource';\r\n\r\nexport interface McpRpcRequest {\r\n id: string;\r\n method: McpRpcMethod;\r\n params?: McpRpcParams;\r\n}\r\n\r\nexport interface McpRpcResponse<T = unknown> {\r\n id: string;\r\n result?: T;\r\n error?: {\r\n code: string;\r\n message: string;\r\n };\r\n}\r\n\r\n// RPC Parameter Types\r\nexport interface ConnectParams {\r\n serverId?: string; // Optional - generated server-side if not provided\r\n serverName: string;\r\n serverUrl: string;\r\n callbackUrl: string;\r\n transportType?: TransportType;\r\n}\r\n\r\nexport interface DisconnectParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface SessionParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface CallToolParams {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface GetPromptParams {\r\n sessionId: string;\r\n name: string;\r\n args?: Record<string, string>;\r\n}\r\n\r\nexport interface ReadResourceParams {\r\n sessionId: string;\r\n uri: string;\r\n}\r\n\r\nexport interface FinishAuthParams {\r\n sessionId: string;\r\n code: string;\r\n}\r\n\r\nexport type McpRpcParams =\r\n | ConnectParams\r\n | DisconnectParams\r\n | SessionParams\r\n | CallToolParams\r\n | GetPromptParams\r\n | ReadResourceParams\r\n | FinishAuthParams\r\n | undefined;\r\n\r\n// RPC Result Types\r\nexport interface SessionInfo {\r\n sessionId: string;\r\n serverId?: string;\r\n serverName?: string;\r\n serverUrl: string;\r\n transport: TransportType;\r\n}\r\n\r\nexport interface SessionListResult {\r\n sessions: SessionInfo[];\r\n}\r\n\r\nexport interface ConnectResult {\r\n sessionId: string;\r\n success: boolean;\r\n}\r\n\r\nexport interface DisconnectResult {\r\n success: boolean;\r\n}\r\n\r\nexport interface RestoreSessionResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface FinishAuthResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface ListToolsRpcResult {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListPromptsResult {\r\n prompts: Array<{\r\n name: string;\r\n description?: string;\r\n arguments?: Array<{\r\n name: string;\r\n description?: string;\r\n required?: boolean;\r\n }>;\r\n }>;\r\n}\r\n\r\nexport interface ListResourcesResult {\r\n resources: Array<{\r\n uri: string;\r\n name: string;\r\n description?: string;\r\n mimeType?: string;\r\n }>;\r\n}\r\n\r\nexport type { CallToolResult };\r\n","/**\r\n * Sanitize server name to create a valid server label\r\n * Must start with a letter and contain only letters, digits, '-' and '_'\r\n */\r\nexport function sanitizeServerLabel(name: string): string {\r\n let sanitized = name\r\n .replace(/[^a-zA-Z0-9-_]/g, '_')\r\n .replace(/_{2,}/g, '_')\r\n .toLowerCase();\r\n\r\n if (!/^[a-zA-Z]/.test(sanitized)) {\r\n sanitized = 's_' + sanitized;\r\n }\r\n\r\n return sanitized;\r\n}\r\n","/**\r\n * Utility functions for working with MCP tool metadata\r\n */\r\n\r\nimport type { ToolInfo } from './types.js';\r\n\r\nexport interface ToolUiConfig {\r\n resourceUri: string;\r\n sessionId: string;\r\n}\r\n\r\n/**\r\n * Extract UI resource URI from tool metadata\r\n *\r\n * @param tool - The tool to extract UI config from\r\n * @returns The resource URI if available, undefined otherwise\r\n *\r\n * @example\r\n * const uri = getToolUiResourceUri(tool);\r\n * if (uri) {\r\n * // Tool has UI configuration\r\n * }\r\n */\r\nexport function getToolUiResourceUri(tool: ToolInfo): string | undefined {\r\n const meta = (tool as any)._meta;\r\n if (!meta?.ui) return undefined;\r\n\r\n const ui = meta.ui;\r\n if (typeof ui !== \"object\" || !ui) return undefined;\r\n\r\n // Check visibility filter - skip if explicitly hidden from app\r\n if (ui.visibility && !ui.visibility.includes(\"app\")) return undefined;\r\n\r\n // Support both 'uri' and 'resourceUri' field names for flexibility\r\n return typeof ui.resourceUri === \"string\"\r\n ? ui.resourceUri\r\n : typeof ui.uri === \"string\"\r\n ? ui.uri\r\n : undefined;\r\n}\r\n\r\n/**\r\n * Find a tool by name within connections\r\n *\r\n * @param connections - Array of MCP connections\r\n * @param toolName - Name of the tool to find\r\n * @returns The tool if found, undefined otherwise\r\n *\r\n * @example\r\n * const tool = findToolByName(connections, \"get_weather\");\r\n */\r\nexport function findToolByName(\r\n connections: Array<{ tools: ToolInfo[] }>,\r\n toolName: string\r\n): ToolInfo | undefined {\r\n for (const conn of connections) {\r\n const tool = conn.tools.find((t) => t.name === toolName);\r\n if (tool) return tool;\r\n }\r\n return undefined;\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-ts/sdk",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -189,12 +189,10 @@ export class AguiAdapter {
189
189
  parameters: cleanSchema(tool.inputSchema),
190
190
  _meta: { ...mcpTool._meta, sessionId: (client as any).getSessionId?.() },
191
191
  handler: async (args: any) => {
192
- console.log(`[AguiAdapter] Executing MCP tool: ${mcpToolName}`, args);
193
-
194
- // IMPORTANT: call the actual MCP tool. (Previously this mistakenly returned the listTools() result.)
192
+ // Call the actual MCP tool
195
193
  const callResult = await (client as any).callTool(mcpToolName, args ?? {});
196
194
 
197
- // Return the raw result object so middleware can inspect `_meta` (e.g. for UI triggers).
195
+ // Return the raw result object so middleware can inspect `_meta` (e.g. for UI triggers)
198
196
  return callResult;
199
197
  }
200
198
  }
@@ -84,7 +84,17 @@ export class McpMiddleware extends Middleware {
84
84
  }));
85
85
  }
86
86
 
87
+ /**
88
+ * Extract base tool name from prefixed format for event emission
89
+ * e.g., "tool_abc123_get-time" -> "get-time"
90
+ */
91
+ private getBaseToolName(toolName: string): string {
92
+ const match = toolName.match(/^tool_[^_]+_(.+)$/);
93
+ return match ? match[1] : toolName;
94
+ }
95
+
87
96
  private isMcpTool(toolName: string): boolean {
97
+ // Direct comparison - tool names should match as-is
88
98
  return this.tools.some(t => t.name === toolName);
89
99
  }
90
100
 
@@ -116,7 +126,6 @@ export class McpMiddleware extends Middleware {
116
126
  }
117
127
 
118
128
  try {
119
- console.log(`[McpMiddleware] Executing tool: ${toolName}`, args);
120
129
  // Result can be a string (legacy) or an object (MCP Result with content array)
121
130
  const result = await tool.handler(args);
122
131
 
@@ -131,7 +140,6 @@ export class McpMiddleware extends Middleware {
131
140
  resultStr = String(result);
132
141
  }
133
142
 
134
- console.log(`[McpMiddleware] Tool result:`, resultStr.slice(0, 200));
135
143
  return { resultStr, rawResult: result };
136
144
  } catch (error: any) {
137
145
  console.error(`[McpMiddleware] Error executing tool:`, error);
@@ -168,7 +176,6 @@ export class McpMiddleware extends Middleware {
168
176
  if (this.isMcpTool(e.toolCallName)) {
169
177
  pendingMcpCalls.add(e.toolCallId);
170
178
  }
171
- console.log(`[McpMiddleware] TOOL_CALL_START: ${e.toolCallName} (id: ${e.toolCallId}, isMCP: ${this.isMcpTool(e.toolCallName)})`);
172
179
  }
173
180
  }
174
181
 
@@ -181,8 +188,7 @@ export class McpMiddleware extends Middleware {
181
188
  }
182
189
 
183
190
  if (event.type === EventType.TOOL_CALL_END) {
184
- const e = event as ToolCallEndEvent;
185
- console.log(`[McpMiddleware] TOOL_CALL_END: ${toolCallNames.get(e.toolCallId) ?? 'unknown'} (id: ${e.toolCallId})`);
191
+ // Track tool call end event
186
192
  }
187
193
 
188
194
  // Workaround: Extract parallel tool calls from MESSAGES_SNAPSHOT
@@ -208,7 +214,6 @@ export class McpMiddleware extends Middleware {
208
214
  toolCallArgsBuffer.set(tc.id, tc.function.arguments || '{}');
209
215
  if (this.isMcpTool(tc.function.name)) {
210
216
  pendingMcpCalls.add(tc.id);
211
- console.log(`[McpMiddleware] MESSAGES_SNAPSHOT: Discovered ${tc.function.name} (id: ${tc.id})`);
212
217
  }
213
218
  }
214
219
  }
@@ -229,8 +234,6 @@ export class McpMiddleware extends Middleware {
229
234
  if (!toolName) return;
230
235
 
231
236
  const args = this.parseArgs(toolCallArgsBuffer.get(toolCallId) || '{}');
232
- console.log(`[McpMiddleware] Executing pending tool: ${toolName}`);
233
-
234
237
  const { resultStr, rawResult } = await this.executeTool(toolName, args);
235
238
  results.push({
236
239
  toolCallId,
@@ -259,11 +262,14 @@ export class McpMiddleware extends Middleware {
259
262
  toolDef?._meta?.['ui/resourceUri'];
260
263
 
261
264
  if (resourceUri) {
265
+ // Extract base name for event emission to match metadata
266
+ const baseToolName = this.getBaseToolName(toolName);
267
+
262
268
  const payload: McpAppUiEventPayload = {
263
269
  toolCallId,
264
270
  resourceUri,
265
271
  sessionId,
266
- toolName,
272
+ toolName: baseToolName, // Use base name to match metadata
267
273
  result: rawResult ?? result,
268
274
  };
269
275
 
@@ -274,8 +280,6 @@ export class McpMiddleware extends Middleware {
274
280
  timestamp: Date.now(),
275
281
  role: 'tool',
276
282
  } as any);
277
-
278
- console.log(`[McpMiddleware] Emitting CustomEvent(${MCP_APP_UI_EVENT}) for: ${toolName} (session: ${sessionId})`);
279
283
  }
280
284
 
281
285
  observer.next({
@@ -286,7 +290,6 @@ export class McpMiddleware extends Middleware {
286
290
  role: 'tool',
287
291
  timestamp: Date.now(),
288
292
  } as any);
289
- console.log(`[McpMiddleware] Emitting TOOL_CALL_RESULT for: ${toolName}`);
290
293
  }
291
294
  }
292
295
 
@@ -303,14 +306,9 @@ export class McpMiddleware extends Middleware {
303
306
  this.ensureIds(input);
304
307
  const anyInput = input as any;
305
308
 
306
- console.log(`[McpMiddleware] === NEW RUN ===`);
307
- console.log(`[McpMiddleware] threadId: ${anyInput.threadId}, runId: ${anyInput.runId}`);
308
- console.log(`[McpMiddleware] messages: ${input.messages?.length ?? 0}, tools: ${this.tools?.length ?? 0}`);
309
-
310
309
  // Inject MCP tools
311
310
  if (this.toolSchemas?.length) {
312
311
  input.tools = [...(input.tools || []), ...this.toolSchemas];
313
- console.log(`[McpMiddleware] Injected ${this.toolSchemas.length} tools:`, this.toolSchemas.map((t: Tool) => t.name));
314
312
  }
315
313
 
316
314
  const handleRunFinished = async () => {
@@ -327,8 +325,6 @@ export class McpMiddleware extends Middleware {
327
325
  return;
328
326
  }
329
327
 
330
- console.log(`[McpMiddleware] RUN_FINISHED with ${state.pendingMcpCalls.size} pending calls`);
331
-
332
328
  // Reconstruct the Assistant Message that triggered these tools
333
329
  const toolCalls = [];
334
330
  for (const toolCallId of state.pendingMcpCalls) {
@@ -352,16 +348,12 @@ export class McpMiddleware extends Middleware {
352
348
  tool_calls: toolCalls.length > 0 ? toolCalls : undefined
353
349
  };
354
350
  input.messages.push(assistantMsg as any);
355
- console.log(`[McpMiddleware] Added assistant message to history before tools: ${state.textContent?.slice(0, 50)}... [${toolCalls.length} tools]`);
356
351
  }
357
352
 
358
353
  // Execute tools and emit results (no RUN_FINISHED yet - continuation follows)
359
354
  const results = await this.executeTools(state);
360
355
  this.emitToolResults(observer, results);
361
356
 
362
- // Prepare continuation
363
- console.log(`[McpMiddleware] Triggering continuation with ${results.length} results`);
364
-
365
357
  // Add tool result messages to history
366
358
  for (const { toolCallId, result, messageId } of results) {
367
359
  input.messages.push({
@@ -378,7 +370,6 @@ export class McpMiddleware extends Middleware {
378
370
  state.textContent = ''; // Clear text content for next turn
379
371
 
380
372
  anyInput.runId = this.generateId('mcp_run');
381
- console.log(`[McpMiddleware] === CONTINUATION RUN === messages: ${input.messages.length}`);
382
373
 
383
374
  // Subscribe to continuation
384
375
  next.run(input).subscribe({
@@ -388,7 +379,6 @@ export class McpMiddleware extends Middleware {
388
379
  this.handleToolCallEvent(event, state);
389
380
 
390
381
  if (event.type === EventType.RUN_ERROR) {
391
- console.log(`[McpMiddleware] RUN_ERROR received in continuation`);
392
382
  state.error = true;
393
383
  observer.next(event);
394
384
  observer.complete();
@@ -396,7 +386,6 @@ export class McpMiddleware extends Middleware {
396
386
  }
397
387
 
398
388
  if (event.type === EventType.RUN_STARTED) {
399
- console.log(`[McpMiddleware] Filtering RUN_STARTED from continuation`);
400
389
  return;
401
390
  }
402
391
 
@@ -428,7 +417,6 @@ export class McpMiddleware extends Middleware {
428
417
  this.handleToolCallEvent(event, state);
429
418
 
430
419
  if (event.type === EventType.RUN_ERROR) {
431
- console.log(`[McpMiddleware] RUN_ERROR received`);
432
420
  state.error = true;
433
421
  observer.next(event);
434
422
  observer.complete();