@mcp-ts/sdk 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/adapters/agui-adapter.d.mts +19 -42
- package/dist/adapters/agui-adapter.d.ts +19 -42
- package/dist/adapters/agui-adapter.js +69 -69
- package/dist/adapters/agui-adapter.js.map +1 -1
- package/dist/adapters/agui-adapter.mjs +69 -70
- package/dist/adapters/agui-adapter.mjs.map +1 -1
- package/dist/adapters/agui-middleware.d.mts +24 -136
- package/dist/adapters/agui-middleware.d.ts +24 -136
- package/dist/adapters/agui-middleware.js +275 -350
- package/dist/adapters/agui-middleware.js.map +1 -1
- package/dist/adapters/agui-middleware.mjs +275 -350
- package/dist/adapters/agui-middleware.mjs.map +1 -1
- package/dist/client/index.d.mts +2 -2
- package/dist/client/index.d.ts +2 -2
- package/dist/client/react.d.mts +2 -2
- package/dist/client/react.d.ts +2 -2
- package/dist/client/vue.d.mts +2 -2
- package/dist/client/vue.d.ts +2 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.d.mts +3 -3
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.js +2 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +2 -1
- package/dist/server/index.mjs.map +1 -1
- package/dist/shared/index.d.mts +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs.map +1 -1
- package/dist/{types-SbDlA2VX.d.mts → types-CLccx9wW.d.mts} +1 -1
- package/dist/{types-SbDlA2VX.d.ts → types-CLccx9wW.d.ts} +1 -1
- package/package.json +2 -2
- package/src/adapters/agui-adapter.ts +98 -109
- package/src/adapters/agui-middleware.ts +424 -512
- package/src/server/handlers/sse-handler.ts +4 -1
- package/src/server/storage/types.ts +1 -1
- package/src/shared/types.ts +1 -1
package/dist/shared/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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-BP6WyRNh.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-
|
|
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';
|
|
4
4
|
import '@modelcontextprotocol/sdk/types.js';
|
|
5
5
|
|
|
6
6
|
/**
|
package/dist/shared/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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-BP6WyRNh.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-
|
|
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';
|
|
4
4
|
import '@modelcontextprotocol/sdk/types.js';
|
|
5
5
|
|
|
6
6
|
/**
|
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"],"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 * 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 } 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;\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\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"],"names":[],"mappings":";;;;;;;AAeO,IAAM,UAAN,MAAiB;AAAA,EAAjB,WAAA,GAAA;AACL,IAAA,aAAA,CAAA,IAAA,EAAQ,WAAA,sBAAyC,GAAA,EAAI,CAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOrD,IAAI,KAAA,GAAkB;AACpB,IAAA,OAAO,CAAC,QAAA,KAAiC;AACvC,MAAA,IAAA,CAAK,SAAA,CAAU,IAAI,QAAQ,CAAA;AAC3B,MAAA,OAAO;AAAA,QACL,SAAS,MAAM;AACb,UAAA,IAAA,CAAK,SAAA,CAAU,OAAO,QAAQ,CAAA;AAAA,QAChC;AAAA,OACF;AAAA,IACF,CAAA;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,KAAA,EAAgB;AACnB,IAAA,KAAA,MAAW,QAAA,IAAY,KAAK,SAAA,EAAW;AACrC,MAAA,IAAI;AACF,QAAA,QAAA,CAAS,KAAK,CAAA;AAAA,MAChB,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,sCAAsC,KAAK,CAAA;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,aAAA,GAAwB;AAC1B,IAAA,OAAO,KAAK,SAAA,CAAU,IAAA;AAAA,EACxB;AACF;AA2FO,IAAM,kBAAN,MAAsB;AAAA,EAAtB,WAAA,GAAA;AACL,IAAA,aAAA,CAAA,IAAA,EAAQ,aAAA,sBAAmC,GAAA,EAAI,CAAA;AAAA,EAAA;AAAA,EAE/C,IAAI,UAAA,EAA8B;AAChC,IAAA,IAAA,CAAK,WAAA,CAAY,IAAI,UAAU,CAAA;AAAA,EACjC;AAAA,EAEA,OAAA,GAAgB;AACd,IAAA,KAAA,MAAW,UAAA,IAAc,KAAK,WAAA,EAAa;AACzC,MAAA,UAAA,CAAW,OAAA,EAAQ;AAAA,IACrB;AACA,IAAA,IAAA,CAAK,YAAY,KAAA,EAAM;AAAA,EACzB;AACF;;;AC/JO,IAAM,mBAAA,GAAsB;AAC5B,IAAM,mBAAA,GAAsB,KAAK,EAAA,GAAK;AAGtC,IAAM,6BAAA,GAAgC;AAGtC,IAAM,gBAAA,GAAmB;AAGzB,IAAM,sBAAA,GAAyB,IAAI,EAAA,GAAK;AAGxC,IAAM,mBAAA,GAAsB;AAC5B,IAAM,kBAAA,GAAqB;AAC3B,IAAM,gBAAA,GAAmB;AACzB,IAAM,kBAAA,GAAqB;AAC3B,IAAM,WAAA,GAAc;AACpB,IAAM,gBAAA,GAAmB;AAGzB,IAAM,eAAA,GAAkB;AACxB,IAAM,kBAAA,GAAqB;;;ACpB3B,IAAM,QAAA,GAAN,cAAuB,KAAA,CAAM;AAAA,EAChC,WAAA,CACoB,IAAA,EAChB,OAAA,EACgB,KAAA,EAClB;AACE,IAAA,KAAA,CAAM,OAAO,CAAA;AAJG,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAEA,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,UAAA;AAEZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EACpD;AAAA,EAEA,MAAA,GAAS;AACL,IAAA,OAAO;AAAA,MACH,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,GAAI,KAAK,KAAA,GAAQ,EAAE,OAAO,IAAA,CAAK,KAAA,CAAM,OAAA,EAAQ,GAAI;AAAC,KACtD;AAAA,EACJ;AACJ;AAKO,IAAM,iBAAA,GAAN,cAAgC,QAAA,CAAS;AAAA,EAC5C,WAAA,CAAY,OAAA,GAAkB,8BAAA,EAAgC,KAAA,EAAe;AACzE,IAAA,KAAA,CAAM,cAAA,EAAgB,SAAS,KAAK,CAAA;AACpC,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AAAA,EAChB;AACJ;AAKO,IAAM,eAAA,GAAN,cAA8B,QAAA,CAAS;AAAA,EAC1C,WAAA,CAAY,SAAiB,KAAA,EAAe;AACxC,IAAA,KAAA,CAAM,kBAAA,EAAoB,SAAS,KAAK,CAAA;AACxC,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AAAA,EAChB;AACJ;AAKO,IAAM,oBAAA,GAAN,cAAmC,QAAA,CAAS;AAAA,EAC/C,WAAA,CAAY,WAAmB,KAAA,EAAe;AAC1C,IAAA,KAAA,CAAM,mBAAA,EAAqB,CAAA,mBAAA,EAAsB,SAAS,CAAA,CAAA,EAAI,KAAK,CAAA;AACnE,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AAAA,EAChB;AACJ;AAKO,IAAM,sBAAA,GAAN,cAAqC,QAAA,CAAS;AAAA,EACjD,WAAA,CAAY,SAAiB,KAAA,EAAe;AACxC,IAAA,KAAA,CAAM,0BAAA,EAA4B,SAAS,KAAK,CAAA;AAChD,IAAA,IAAA,CAAK,IAAA,GAAO,wBAAA;AAAA,EAChB;AACJ;AAKO,IAAM,mBAAA,GAAN,cAAkC,QAAA,CAAS;AAAA,EAC9C,WAAA,CAAY,SAAiB,KAAA,EAAe;AACxC,IAAA,KAAA,CAAM,YAAA,EAAc,SAAS,KAAK,CAAA;AAClC,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AAAA,EAChB;AACJ;AAKO,IAAM,iBAAA,GAAN,cAAgC,QAAA,CAAS;AAAA,EAC5C,WAAA,CAAY,OAAA,GAAkB,qBAAA,EAAuB,KAAA,EAAe;AAChE,IAAA,KAAA,CAAM,eAAA,EAAiB,SAAS,KAAK,CAAA;AACrC,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AAAA,EAChB;AACJ;AAKO,IAAM,iBAAA,GAAN,cAAgC,QAAA,CAAS;AAAA,EAC5C,WAAA,CAAY,OAAA,GAAkB,yBAAA,EAA2B,KAAA,EAAe;AACpE,IAAA,KAAA,CAAM,eAAA,EAAiB,SAAS,KAAK,CAAA;AACrC,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AAAA,EAChB;AACJ;AAKO,IAAM,kBAAA,GAAN,cAAiC,QAAA,CAAS;AAAA,EAC7C,WAAA,CAAY,SAAiB,KAAA,EAAe;AACxC,IAAA,KAAA,CAAM,qBAAA,EAAuB,SAAS,KAAK,CAAA;AAC3C,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AAAA,EAChB;AACJ;AAKO,IAAM,kBAAA,GAAN,cAAiC,QAAA,CAAS;AAAA,EAC7C,WAAA,CAAY,QAAA,EAAkB,OAAA,EAAiB,KAAA,EAAe;AAC1D,IAAA,KAAA,CAAM,wBAAwB,CAAA,MAAA,EAAS,QAAQ,CAAA,UAAA,EAAa,OAAO,IAAI,KAAK,CAAA;AAC5E,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AAAA,EAChB;AACJ;AAKO,IAAM,aAAA,GAAgB;AAAA,EACzB,eAAA,EAAiB,iBAAA;AAAA,EACjB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,YAAA,EAAc,cAAA;AAAA,EACd,aAAA,EAAe,eAAA;AAAA,EACf,cAAA,EAAgB,gBAAA;AAAA,EAChB,cAAA,EAAgB;AACpB;;;AC9BO,SAAS,iBACd,QAAA,EACoC;AACpC,EAAA,OAAO,SAAA,IAAa,QAAA,IAAY,QAAA,CAAS,OAAA,KAAY,IAAA;AACvD;AAEO,SAAS,sBACd,QAAA,EACyC;AACzC,EAAA,OAAO,cAAA,IAAkB,QAAA,IAAY,QAAA,CAAS,YAAA,KAAiB,IAAA;AACjE;AAEO,SAAS,eACd,QAAA,EACkC;AAClC,EAAA,OAAO,OAAA,IAAW,QAAA;AACpB;AAEO,SAAS,mBACd,QAAA,EACsC;AACtC,EAAA,OAAO,OAAA,IAAW,QAAA;AACpB;AAEO,SAAS,kBACd,QAAA,EACqC;AACrC,EAAA,OAAO,SAAA,IAAa,QAAA;AACtB;;;AC5HO,SAAS,oBAAoB,IAAA,EAAsB;AACxD,EAAA,IAAI,SAAA,GAAY,IAAA,CACb,OAAA,CAAQ,iBAAA,EAAmB,GAAG,EAC9B,OAAA,CAAQ,QAAA,EAAU,GAAG,CAAA,CACrB,WAAA,EAAY;AAEf,EAAA,IAAI,CAAC,WAAA,CAAY,IAAA,CAAK,SAAS,CAAA,EAAG;AAChC,IAAA,SAAA,GAAY,IAAA,GAAO,SAAA;AAAA,EACrB;AAEA,EAAA,OAAO,SAAA;AACT","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 * 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 } 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\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 +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 * 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 } 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;\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\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"],"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 * 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 } 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\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"]}
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @example
|
|
9
9
|
* ```typescript
|
|
10
10
|
* import { MultiSessionClient } from '@mcp-ts/sdk/server';
|
|
11
|
-
* import { AguiAdapter } from '@mcp-ts/sdk/adapters/
|
|
11
|
+
* import { AguiAdapter } from '@mcp-ts/sdk/adapters/agui-adapter';
|
|
12
12
|
* import { createMcpMiddleware } from '@mcp-ts/sdk/adapters/agui-middleware';
|
|
13
13
|
* import { HttpAgent } from '@ag-ui/client';
|
|
14
14
|
*
|
|
@@ -22,13 +22,62 @@
|
|
|
22
22
|
*
|
|
23
23
|
* // Use with AG-UI middleware
|
|
24
24
|
* const agent = new HttpAgent({ url: 'http://localhost:8000/agent' });
|
|
25
|
-
* agent.use(createMcpMiddleware(
|
|
25
|
+
* agent.use(createMcpMiddleware({ tools }));
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
29
|
import { MCPClient } from '../server/mcp/oauth-client.js';
|
|
30
30
|
import { MultiSessionClient } from '../server/mcp/multi-session-client.js';
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Cleans a JSON Schema by removing meta-properties that cause issues with
|
|
34
|
+
* strict Pydantic validation (e.g., Google ADK).
|
|
35
|
+
*
|
|
36
|
+
* Removes: $schema, $id, $comment, $defs, definitions
|
|
37
|
+
*
|
|
38
|
+
* @param schema - The JSON Schema to clean
|
|
39
|
+
* @returns Cleaned schema without meta-properties
|
|
40
|
+
*/
|
|
41
|
+
export function cleanSchema(schema: Record<string, any> | undefined): Record<string, any> {
|
|
42
|
+
if (!schema) {
|
|
43
|
+
return { type: 'object', properties: {} };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const cleaned = { ...schema };
|
|
47
|
+
|
|
48
|
+
// Remove JSON Schema meta-properties that cause Pydantic validation errors
|
|
49
|
+
delete cleaned.$schema;
|
|
50
|
+
delete cleaned.$id;
|
|
51
|
+
delete cleaned.$comment;
|
|
52
|
+
delete cleaned.$defs;
|
|
53
|
+
delete cleaned.definitions;
|
|
54
|
+
|
|
55
|
+
// Recursively clean nested properties
|
|
56
|
+
if (cleaned.properties && typeof cleaned.properties === 'object') {
|
|
57
|
+
const cleanedProps: Record<string, any> = {};
|
|
58
|
+
for (const [key, value] of Object.entries(cleaned.properties)) {
|
|
59
|
+
if (typeof value === 'object' && value !== null) {
|
|
60
|
+
cleanedProps[key] = cleanSchema(value as Record<string, any>);
|
|
61
|
+
} else {
|
|
62
|
+
cleanedProps[key] = value;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
cleaned.properties = cleanedProps;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Clean items if it's an array schema
|
|
69
|
+
if (cleaned.items && typeof cleaned.items === 'object') {
|
|
70
|
+
cleaned.items = cleanSchema(cleaned.items);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Clean additionalProperties if it's an object schema
|
|
74
|
+
if (cleaned.additionalProperties && typeof cleaned.additionalProperties === 'object') {
|
|
75
|
+
cleaned.additionalProperties = cleanSchema(cleaned.additionalProperties);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return cleaned;
|
|
79
|
+
}
|
|
80
|
+
|
|
32
81
|
/**
|
|
33
82
|
* Configuration options for AguiAdapter
|
|
34
83
|
*/
|
|
@@ -42,43 +91,25 @@ export interface AguiAdapterOptions {
|
|
|
42
91
|
|
|
43
92
|
/**
|
|
44
93
|
* AG-UI Tool with handler for server-side execution.
|
|
45
|
-
*
|
|
46
|
-
* Tools contain:
|
|
47
|
-
* - `name`: Unique identifier (prefixed with server ID)
|
|
48
|
-
* - `description`: Human-readable description for the LLM
|
|
49
|
-
* - `parameters`: JSON Schema defining the input format
|
|
50
|
-
* - `handler`: Function that executes the tool via MCP client
|
|
51
94
|
*/
|
|
52
95
|
export interface AguiTool {
|
|
53
|
-
/** Unique tool name (e.g., "server-abc_get_weather") */
|
|
54
96
|
name: string;
|
|
55
|
-
/** Human-readable description for the LLM */
|
|
56
97
|
description: string;
|
|
57
|
-
/** JSON Schema format parameters */
|
|
58
98
|
parameters?: Record<string, any>;
|
|
59
|
-
/** Handler function that executes the MCP tool */
|
|
60
99
|
handler?: (args: any) => any | Promise<any>;
|
|
61
100
|
}
|
|
62
101
|
|
|
63
102
|
/**
|
|
64
103
|
* Tool definition format for passing to remote agents (without handler).
|
|
65
|
-
* Compatible with OpenAI's function calling API.
|
|
66
104
|
*/
|
|
67
105
|
export interface AguiToolDefinition {
|
|
68
|
-
/** Tool name (e.g., "server-abc_get_weather") */
|
|
69
106
|
name: string;
|
|
70
|
-
/** Human-readable description */
|
|
71
107
|
description: string;
|
|
72
|
-
/** JSON Schema format parameters */
|
|
73
108
|
parameters: Record<string, any>;
|
|
74
109
|
}
|
|
75
110
|
|
|
76
111
|
/**
|
|
77
112
|
* Adapter that transforms MCP tools into AG-UI compatible formats.
|
|
78
|
-
*
|
|
79
|
-
* This adapter provides two main outputs:
|
|
80
|
-
* - `getTools()`: Returns tools with handlers for server-side execution
|
|
81
|
-
* - `getToolDefinitions()`: Returns tool definitions in JSON Schema format for remote agents
|
|
82
113
|
*/
|
|
83
114
|
export class AguiAdapter {
|
|
84
115
|
constructor(
|
|
@@ -88,123 +119,81 @@ export class AguiAdapter {
|
|
|
88
119
|
|
|
89
120
|
/**
|
|
90
121
|
* Get tools with handlers for MCP tool execution.
|
|
91
|
-
*
|
|
92
|
-
* Each tool includes a handler function that:
|
|
93
|
-
* 1. Calls the MCP tool via the client
|
|
94
|
-
* 2. Extracts text content from the result
|
|
95
|
-
* 3. Returns the result as a string or JSON
|
|
96
|
-
*
|
|
97
|
-
* @returns Array of AguiTool objects
|
|
98
122
|
*/
|
|
99
123
|
async getTools(): Promise<AguiTool[]> {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (isMultiSession) {
|
|
124
|
+
if (this.isMultiSession()) {
|
|
103
125
|
const clients = (this.client as MultiSessionClient).getClients();
|
|
104
126
|
const allTools: AguiTool[] = [];
|
|
105
|
-
|
|
106
127
|
for (const client of clients) {
|
|
107
|
-
|
|
108
|
-
allTools.push(...tools);
|
|
128
|
+
allTools.push(...await this.transformTools(client));
|
|
109
129
|
}
|
|
110
|
-
|
|
111
130
|
return allTools;
|
|
112
131
|
}
|
|
113
|
-
|
|
114
132
|
return this.transformTools(this.client as MCPClient);
|
|
115
133
|
}
|
|
116
134
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
tools.push({
|
|
130
|
-
name: toolName,
|
|
131
|
-
description: tool.description || `Execute ${tool.name}`,
|
|
132
|
-
parameters: tool.inputSchema || { type: 'object', properties: {} },
|
|
133
|
-
handler: async (args: any) => {
|
|
134
|
-
console.log(`[AguiAdapter] Executing MCP tool: ${tool.name}`, args);
|
|
135
|
-
const result = await client.callTool(tool.name, args);
|
|
136
|
-
|
|
137
|
-
// Extract text content from result
|
|
138
|
-
if (result.content && Array.isArray(result.content)) {
|
|
139
|
-
const textContent = result.content
|
|
140
|
-
.filter((c: any) => c.type === 'text')
|
|
141
|
-
.map((c: any) => c.text)
|
|
142
|
-
.join('\n');
|
|
143
|
-
return textContent || result;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return result;
|
|
147
|
-
}
|
|
148
|
-
});
|
|
135
|
+
/**
|
|
136
|
+
* Get tool definitions in JSON Schema format for passing to remote agents.
|
|
137
|
+
*/
|
|
138
|
+
async getToolDefinitions(): Promise<AguiToolDefinition[]> {
|
|
139
|
+
if (this.isMultiSession()) {
|
|
140
|
+
const clients = (this.client as MultiSessionClient).getClients();
|
|
141
|
+
const allTools: AguiToolDefinition[] = [];
|
|
142
|
+
for (const client of clients) {
|
|
143
|
+
allTools.push(...await this.transformToolDefinitions(client));
|
|
144
|
+
}
|
|
145
|
+
return allTools;
|
|
149
146
|
}
|
|
150
|
-
|
|
151
|
-
return tools;
|
|
147
|
+
return this.transformToolDefinitions(this.client as MCPClient);
|
|
152
148
|
}
|
|
153
149
|
|
|
154
150
|
/**
|
|
155
151
|
* Get tools as a function (for dynamic loading).
|
|
156
|
-
*
|
|
157
|
-
* @returns Function that returns a Promise of tools
|
|
158
152
|
*/
|
|
159
153
|
getToolsFunction(): () => Promise<AguiTool[]> {
|
|
160
|
-
return
|
|
154
|
+
return () => this.getTools();
|
|
161
155
|
}
|
|
162
156
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
* This format is compatible with:
|
|
167
|
-
* - OpenAI's function calling API
|
|
168
|
-
* - AG-UI input.tools format
|
|
169
|
-
* - Most LLM tool/function calling implementations
|
|
170
|
-
*
|
|
171
|
-
* @returns Array of AguiToolDefinition objects
|
|
172
|
-
*/
|
|
173
|
-
async getToolDefinitions(): Promise<AguiToolDefinition[]> {
|
|
174
|
-
const isMultiSession = typeof (this.client as any).getClients === 'function';
|
|
157
|
+
private isMultiSession(): boolean {
|
|
158
|
+
return typeof (this.client as any).getClients === 'function';
|
|
159
|
+
}
|
|
175
160
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const allTools: AguiToolDefinition[] = [];
|
|
161
|
+
private async transformTools(client: MCPClient): Promise<AguiTool[]> {
|
|
162
|
+
if (!client.isConnected()) return [];
|
|
179
163
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
164
|
+
const result = await client.listTools();
|
|
165
|
+
const prefix = this.options.prefix ?? `tool_${client.getServerId() ?? 'mcp'}`;
|
|
166
|
+
|
|
167
|
+
return result.tools.map(tool => ({
|
|
168
|
+
name: `${prefix}_${tool.name}`,
|
|
169
|
+
description: tool.description || `Execute ${tool.name}`,
|
|
170
|
+
parameters: cleanSchema(tool.inputSchema),
|
|
171
|
+
handler: async (args: any) => {
|
|
172
|
+
console.log(`[AguiAdapter] Executing MCP tool: ${tool.name}`, args);
|
|
173
|
+
const result = await client.callTool(tool.name, args);
|
|
174
|
+
|
|
175
|
+
if (result.content && Array.isArray(result.content)) {
|
|
176
|
+
const textContent = result.content
|
|
177
|
+
.filter((c: any) => c.type === 'text')
|
|
178
|
+
.map((c: any) => c.text)
|
|
179
|
+
.join('\n');
|
|
180
|
+
return textContent || result;
|
|
181
|
+
}
|
|
182
|
+
return result;
|
|
183
183
|
}
|
|
184
|
-
|
|
185
|
-
return allTools;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return this.transformToolDefinitions(this.client as MCPClient);
|
|
184
|
+
}));
|
|
189
185
|
}
|
|
190
186
|
|
|
191
187
|
private async transformToolDefinitions(client: MCPClient): Promise<AguiToolDefinition[]> {
|
|
192
|
-
if (!client.isConnected())
|
|
193
|
-
return [];
|
|
194
|
-
}
|
|
188
|
+
if (!client.isConnected()) return [];
|
|
195
189
|
|
|
196
190
|
const result = await client.listTools();
|
|
197
|
-
const prefix = this.options.prefix ?? client.getServerId() ?? 'mcp'
|
|
198
|
-
const tools: AguiToolDefinition[] = [];
|
|
199
|
-
|
|
200
|
-
for (const tool of result.tools) {
|
|
201
|
-
tools.push({
|
|
202
|
-
name: `${prefix}_${tool.name}`,
|
|
203
|
-
description: tool.description || `Execute ${tool.name}`,
|
|
204
|
-
parameters: tool.inputSchema || { type: 'object', properties: {} },
|
|
205
|
-
});
|
|
206
|
-
}
|
|
191
|
+
const prefix = this.options.prefix ?? `tool_${client.getServerId() ?? 'mcp'}`;
|
|
207
192
|
|
|
208
|
-
return tools
|
|
193
|
+
return result.tools.map(tool => ({
|
|
194
|
+
name: `${prefix}_${tool.name}`,
|
|
195
|
+
description: tool.description || `Execute ${tool.name}`,
|
|
196
|
+
parameters: cleanSchema(tool.inputSchema),
|
|
197
|
+
}));
|
|
209
198
|
}
|
|
210
199
|
}
|