@frontmcp/testing 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/fixtures/index.mjs +2377 -0
- package/esm/index.mjs +4768 -0
- package/esm/matchers/index.mjs +646 -0
- package/esm/package.json +122 -0
- package/esm/playwright/index.mjs +19 -0
- package/esm/setup.mjs +680 -0
- package/fixtures/index.js +2418 -0
- package/index.js +4866 -0
- package/jest-preset.js +3 -3
- package/matchers/index.js +673 -0
- package/package.json +51 -23
- package/playwright/index.js +46 -0
- package/setup.js +651 -0
- package/src/assertions/index.js +0 -18
- package/src/assertions/index.js.map +0 -1
- package/src/assertions/mcp-assertions.js +0 -220
- package/src/assertions/mcp-assertions.js.map +0 -1
- package/src/auth/auth-headers.js +0 -62
- package/src/auth/auth-headers.js.map +0 -1
- package/src/auth/index.js +0 -15
- package/src/auth/index.js.map +0 -1
- package/src/auth/mock-api-server.js +0 -200
- package/src/auth/mock-api-server.js.map +0 -1
- package/src/auth/mock-oauth-server.js +0 -253
- package/src/auth/mock-oauth-server.js.map +0 -1
- package/src/auth/token-factory.js +0 -181
- package/src/auth/token-factory.js.map +0 -1
- package/src/auth/user-fixtures.js +0 -92
- package/src/auth/user-fixtures.js.map +0 -1
- package/src/client/index.js +0 -12
- package/src/client/index.js.map +0 -1
- package/src/client/mcp-test-client.builder.js +0 -163
- package/src/client/mcp-test-client.builder.js.map +0 -1
- package/src/client/mcp-test-client.js +0 -937
- package/src/client/mcp-test-client.js.map +0 -1
- package/src/client/mcp-test-client.types.js +0 -16
- package/src/client/mcp-test-client.types.js.map +0 -1
- package/src/errors/index.js +0 -85
- package/src/errors/index.js.map +0 -1
- package/src/example-tools/index.js +0 -40
- package/src/example-tools/index.js.map +0 -1
- package/src/example-tools/tool-configs.js +0 -222
- package/src/example-tools/tool-configs.js.map +0 -1
- package/src/expect.js +0 -31
- package/src/expect.js.map +0 -1
- package/src/fixtures/fixture-types.js +0 -7
- package/src/fixtures/fixture-types.js.map +0 -1
- package/src/fixtures/index.js +0 -16
- package/src/fixtures/index.js.map +0 -1
- package/src/fixtures/test-fixture.js +0 -311
- package/src/fixtures/test-fixture.js.map +0 -1
- package/src/http-mock/http-mock.js +0 -544
- package/src/http-mock/http-mock.js.map +0 -1
- package/src/http-mock/http-mock.types.js +0 -10
- package/src/http-mock/http-mock.types.js.map +0 -1
- package/src/http-mock/index.js +0 -11
- package/src/http-mock/index.js.map +0 -1
- package/src/index.js +0 -167
- package/src/index.js.map +0 -1
- package/src/interceptor/index.js +0 -15
- package/src/interceptor/index.js.map +0 -1
- package/src/interceptor/interceptor-chain.js +0 -207
- package/src/interceptor/interceptor-chain.js.map +0 -1
- package/src/interceptor/interceptor.types.js +0 -7
- package/src/interceptor/interceptor.types.js.map +0 -1
- package/src/interceptor/mock-registry.js +0 -189
- package/src/interceptor/mock-registry.js.map +0 -1
- package/src/matchers/index.js +0 -12
- package/src/matchers/index.js.map +0 -1
- package/src/matchers/matcher-types.js +0 -10
- package/src/matchers/matcher-types.js.map +0 -1
- package/src/matchers/mcp-matchers.js +0 -395
- package/src/matchers/mcp-matchers.js.map +0 -1
- package/src/platform/index.js +0 -47
- package/src/platform/index.js.map +0 -1
- package/src/platform/platform-client-info.js +0 -155
- package/src/platform/platform-client-info.js.map +0 -1
- package/src/platform/platform-types.js +0 -110
- package/src/platform/platform-types.js.map +0 -1
- package/src/playwright/index.js +0 -49
- package/src/playwright/index.js.map +0 -1
- package/src/server/index.js +0 -10
- package/src/server/index.js.map +0 -1
- package/src/server/test-server.js +0 -341
- package/src/server/test-server.js.map +0 -1
- package/src/setup.js +0 -30
- package/src/setup.js.map +0 -1
- package/src/transport/index.js +0 -10
- package/src/transport/index.js.map +0 -1
- package/src/transport/streamable-http.transport.js +0 -438
- package/src/transport/streamable-http.transport.js.map +0 -1
- package/src/transport/transport.interface.js +0 -7
- package/src/transport/transport.interface.js.map +0 -1
- package/src/ui/index.js +0 -23
- package/src/ui/index.js.map +0 -1
- package/src/ui/ui-assertions.js +0 -367
- package/src/ui/ui-assertions.js.map +0 -1
- package/src/ui/ui-matchers.js +0 -493
- package/src/ui/ui-matchers.js.map +0 -1
- /package/{src/assertions → assertions}/index.d.ts +0 -0
- /package/{src/assertions → assertions}/mcp-assertions.d.ts +0 -0
- /package/{src/auth → auth}/auth-headers.d.ts +0 -0
- /package/{src/auth → auth}/index.d.ts +0 -0
- /package/{src/auth → auth}/mock-api-server.d.ts +0 -0
- /package/{src/auth → auth}/mock-oauth-server.d.ts +0 -0
- /package/{src/auth → auth}/token-factory.d.ts +0 -0
- /package/{src/auth → auth}/user-fixtures.d.ts +0 -0
- /package/{src/client → client}/index.d.ts +0 -0
- /package/{src/client → client}/mcp-test-client.builder.d.ts +0 -0
- /package/{src/client → client}/mcp-test-client.d.ts +0 -0
- /package/{src/client → client}/mcp-test-client.types.d.ts +0 -0
- /package/{src/errors → errors}/index.d.ts +0 -0
- /package/{src/example-tools → example-tools}/index.d.ts +0 -0
- /package/{src/example-tools → example-tools}/tool-configs.d.ts +0 -0
- /package/{src/expect.d.ts → expect.d.ts} +0 -0
- /package/{src/fixtures → fixtures}/fixture-types.d.ts +0 -0
- /package/{src/fixtures → fixtures}/index.d.ts +0 -0
- /package/{src/fixtures → fixtures}/test-fixture.d.ts +0 -0
- /package/{src/http-mock → http-mock}/http-mock.d.ts +0 -0
- /package/{src/http-mock → http-mock}/http-mock.types.d.ts +0 -0
- /package/{src/http-mock → http-mock}/index.d.ts +0 -0
- /package/{src/index.d.ts → index.d.ts} +0 -0
- /package/{src/interceptor → interceptor}/index.d.ts +0 -0
- /package/{src/interceptor → interceptor}/interceptor-chain.d.ts +0 -0
- /package/{src/interceptor → interceptor}/interceptor.types.d.ts +0 -0
- /package/{src/interceptor → interceptor}/mock-registry.d.ts +0 -0
- /package/{src/matchers → matchers}/index.d.ts +0 -0
- /package/{src/matchers → matchers}/matcher-types.d.ts +0 -0
- /package/{src/matchers → matchers}/mcp-matchers.d.ts +0 -0
- /package/{src/platform → platform}/index.d.ts +0 -0
- /package/{src/platform → platform}/platform-client-info.d.ts +0 -0
- /package/{src/platform → platform}/platform-types.d.ts +0 -0
- /package/{src/playwright → playwright}/index.d.ts +0 -0
- /package/{src/server → server}/index.d.ts +0 -0
- /package/{src/server → server}/test-server.d.ts +0 -0
- /package/{src/setup.d.ts → setup.d.ts} +0 -0
- /package/{src/transport → transport}/index.d.ts +0 -0
- /package/{src/transport → transport}/streamable-http.transport.d.ts +0 -0
- /package/{src/transport → transport}/transport.interface.d.ts +0 -0
- /package/{src/ui → ui}/index.d.ts +0 -0
- /package/{src/ui → ui}/ui-assertions.d.ts +0 -0
- /package/{src/ui → ui}/ui-matchers.d.ts +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-test-client.js","sourceRoot":"","sources":["../../../src/client/mcp-test-client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @file mcp-test-client.ts\n * @description Main MCP Test Client implementation for E2E testing\n */\n\nimport type {\n McpTestClientConfig,\n McpResponse,\n TestTransportType,\n TestAuthConfig,\n TestClientCapabilities,\n ToolResultWrapper,\n ResourceContentWrapper,\n PromptResultWrapper,\n LogEntry,\n RequestTrace,\n NotificationEntry,\n ProgressUpdate,\n SessionInfo,\n AuthState,\n McpErrorInfo,\n InitializeResult,\n ListToolsResult,\n CallToolResult,\n ListResourcesResult,\n ReadResourceResult,\n ListResourceTemplatesResult,\n ListPromptsResult,\n GetPromptResult,\n Tool,\n Resource,\n ResourceTemplate,\n Prompt,\n JSONRPCResponse,\n} from './mcp-test-client.types';\nimport { McpTestClientBuilder } from './mcp-test-client.builder';\nimport type { McpTransport } from '../transport/transport.interface';\nimport { StreamableHttpTransport } from '../transport/streamable-http.transport';\nimport type {\n InterceptorChain,\n MockDefinition,\n MockHandle,\n RequestInterceptor,\n ResponseInterceptor,\n} from '../interceptor';\nimport { DefaultInterceptorChain, mockResponse } from '../interceptor';\n\n// ═══════════════════════════════════════════════════════════════════\n// CONSTANTS\n// ═══════════════════════════════════════════════════════════════════\n\nconst DEFAULT_TIMEOUT = 30000;\nconst DEFAULT_PROTOCOL_VERSION = '2025-06-18';\nconst DEFAULT_CLIENT_INFO = {\n name: '@frontmcp/testing',\n version: '0.4.0',\n};\n\n// ═══════════════════════════════════════════════════════════════════\n// MAIN CLIENT CLASS\n// ═══════════════════════════════════════════════════════════════════\n\nexport class McpTestClient {\n // Platform and capabilities are optional - only set when testing platform-specific behavior\n private readonly config: Required<Omit<McpTestClientConfig, 'platform' | 'capabilities'>> &\n Pick<McpTestClientConfig, 'platform' | 'capabilities'>;\n private transport: McpTransport | null = null;\n private initResult: InitializeResult | null = null;\n private requestIdCounter = 0;\n private _lastRequestId: string | number = 0;\n private _sessionId: string | undefined;\n private _sessionInfo: SessionInfo | null = null;\n private _authState: AuthState = { isAnonymous: true, scopes: [] };\n\n // Logging and tracing\n private _logs: LogEntry[] = [];\n private _traces: RequestTrace[] = [];\n private _notifications: NotificationEntry[] = [];\n private _progressUpdates: ProgressUpdate[] = [];\n\n // Interceptor chain\n private _interceptors: InterceptorChain;\n\n // ═══════════════════════════════════════════════════════════════════\n // CONSTRUCTOR & FACTORY\n // ═══════════════════════════════════════════════════════════════════\n\n constructor(config: McpTestClientConfig) {\n this.config = {\n baseUrl: config.baseUrl,\n transport: config.transport ?? 'streamable-http',\n auth: config.auth ?? {},\n publicMode: config.publicMode ?? false,\n timeout: config.timeout ?? DEFAULT_TIMEOUT,\n debug: config.debug ?? false,\n protocolVersion: config.protocolVersion ?? DEFAULT_PROTOCOL_VERSION,\n clientInfo: config.clientInfo ?? DEFAULT_CLIENT_INFO,\n platform: config.platform,\n capabilities: config.capabilities,\n };\n\n // If a token is provided, user is authenticated (even in public mode)\n // Public mode just means anonymous access is allowed, not that tokens are ignored\n if (config.auth?.token) {\n this._authState = {\n isAnonymous: false,\n token: config.auth.token,\n scopes: this.parseScopesFromToken(config.auth.token),\n user: this.parseUserFromToken(config.auth.token),\n };\n }\n // Otherwise, user is anonymous (default _authState is already { isAnonymous: true, scopes: [] })\n\n // Initialize interceptor chain\n this._interceptors = new DefaultInterceptorChain();\n }\n\n /**\n * Create a new McpTestClientBuilder for fluent configuration\n */\n static create(config: McpTestClientConfig): McpTestClientBuilder {\n return new McpTestClientBuilder(config);\n }\n\n // ═══════════════════════════════════════════════════════════════════\n // CONNECTION & LIFECYCLE\n // ═══════════════════════════════════════════════════════════════════\n\n /**\n * Connect to the MCP server and perform initialization\n */\n async connect(): Promise<InitializeResult> {\n this.log('debug', `Connecting to ${this.config.baseUrl}...`);\n\n // Create transport based on config\n this.transport = this.createTransport();\n\n // Connect transport\n await this.transport.connect();\n\n // Perform MCP initialization\n const initResponse = await this.initialize();\n\n if (!initResponse.success || !initResponse.data) {\n throw new Error(`Failed to initialize MCP connection: ${initResponse.error?.message ?? 'Unknown error'}`);\n }\n\n this.initResult = initResponse.data;\n this._sessionId = this.transport.getSessionId();\n this._sessionInfo = {\n id: this._sessionId ?? `session-${Date.now()}`,\n createdAt: new Date(),\n lastActivityAt: new Date(),\n requestCount: 1,\n };\n\n // Send initialized notification per MCP protocol\n // This notification MUST be sent after receiving initialize response\n // before the client can make any other requests\n await this.transport.notify({\n jsonrpc: '2.0',\n method: 'notifications/initialized',\n });\n\n this.log('info', `Connected to ${this.initResult.serverInfo?.name ?? 'MCP Server'}`);\n\n return this.initResult;\n }\n\n /**\n * Disconnect from the MCP server\n */\n async disconnect(): Promise<void> {\n if (this.transport) {\n await this.transport.close();\n this.transport = null;\n }\n this.initResult = null;\n this.log('info', 'Disconnected from MCP server');\n }\n\n /**\n * Reconnect to the server, optionally with an existing session ID\n */\n async reconnect(options?: { sessionId?: string }): Promise<void> {\n await this.disconnect();\n\n if (options?.sessionId && this.transport) {\n // Set session ID before reconnecting\n this._sessionId = options.sessionId;\n }\n\n await this.connect();\n }\n\n /**\n * Check if the client is currently connected\n */\n isConnected(): boolean {\n return this.transport?.isConnected() ?? false;\n }\n\n // ═══════════════════════════════════════════════════════════════════\n // SESSION & AUTH PROPERTIES\n // ═══════════════════════════════════════════════════════════════════\n\n get sessionId(): string {\n return this._sessionId ?? '';\n }\n\n get session(): SessionInfo & { expire: () => Promise<void> } {\n const info = this._sessionInfo ?? {\n id: '',\n createdAt: new Date(),\n lastActivityAt: new Date(),\n requestCount: 0,\n };\n\n return {\n ...info,\n expire: async () => {\n // Force session expiration for testing\n this._sessionId = undefined;\n this._sessionInfo = null;\n },\n };\n }\n\n get auth(): AuthState {\n return this._authState;\n }\n\n /**\n * Authenticate with a token\n */\n async authenticate(token: string): Promise<void> {\n this._authState = {\n isAnonymous: false,\n token,\n scopes: this.parseScopesFromToken(token),\n user: this.parseUserFromToken(token),\n };\n\n // Update transport headers\n if (this.transport) {\n this.transport.setAuthToken(token);\n }\n\n this.log('debug', 'Authentication updated');\n }\n\n // ═══════════════════════════════════════════════════════════════════\n // SERVER INFO & CAPABILITIES\n // ═══════════════════════════════════════════════════════════════════\n\n get serverInfo(): { name: string; version: string; title?: string } {\n return {\n name: this.initResult?.serverInfo?.name ?? '',\n version: this.initResult?.serverInfo?.version ?? '',\n };\n }\n\n get protocolVersion(): string {\n return this.initResult?.protocolVersion ?? '';\n }\n\n get instructions(): string {\n return this.initResult?.instructions ?? '';\n }\n\n get capabilities(): InitializeResult['capabilities'] {\n return this.initResult?.capabilities ?? {};\n }\n\n /**\n * Check if server has a specific capability\n */\n hasCapability(name: 'tools' | 'resources' | 'prompts' | 'logging' | 'sampling'): boolean {\n return !!this.capabilities[name];\n }\n\n // ═══════════════════════════════════════════════════════════════════\n // TOOLS API\n // ═══════════════════════════════════════════════════════════════════\n\n readonly tools = {\n /**\n * List all available tools\n */\n list: async (): Promise<Tool[]> => {\n const response = await this.listTools();\n if (!response.success || !response.data) {\n throw new Error(`Failed to list tools: ${response.error?.message}`);\n }\n return response.data.tools;\n },\n\n /**\n * Call a tool by name with arguments\n */\n call: async (name: string, args?: Record<string, unknown>): Promise<ToolResultWrapper> => {\n const response = await this.callTool(name, args);\n return this.wrapToolResult(response);\n },\n };\n\n // ═══════════════════════════════════════════════════════════════════\n // RESOURCES API\n // ═══════════════════════════════════════════════════════════════════\n\n readonly resources = {\n /**\n * List all static resources\n */\n list: async (): Promise<Resource[]> => {\n const response = await this.listResources();\n if (!response.success || !response.data) {\n throw new Error(`Failed to list resources: ${response.error?.message}`);\n }\n return response.data.resources;\n },\n\n /**\n * List all resource templates\n */\n listTemplates: async (): Promise<ResourceTemplate[]> => {\n const response = await this.listResourceTemplates();\n if (!response.success || !response.data) {\n throw new Error(`Failed to list resource templates: ${response.error?.message}`);\n }\n return response.data.resourceTemplates;\n },\n\n /**\n * Read a resource by URI\n */\n read: async (uri: string): Promise<ResourceContentWrapper> => {\n const response = await this.readResource(uri);\n return this.wrapResourceContent(response);\n },\n\n /**\n * Subscribe to resource changes (placeholder for future implementation)\n */\n subscribe: async (_uri: string): Promise<void> => {\n // TODO: Implement resource subscription\n this.log('warn', 'Resource subscription not yet implemented');\n },\n\n /**\n * Unsubscribe from resource changes (placeholder for future implementation)\n */\n unsubscribe: async (_uri: string): Promise<void> => {\n // TODO: Implement resource unsubscription\n this.log('warn', 'Resource unsubscription not yet implemented');\n },\n };\n\n // ═══════════════════════════════════════════════════════════════════\n // PROMPTS API\n // ═══════════════════════════════════════════════════════════════════\n\n readonly prompts = {\n /**\n * List all available prompts\n */\n list: async (): Promise<Prompt[]> => {\n const response = await this.listPrompts();\n if (!response.success || !response.data) {\n throw new Error(`Failed to list prompts: ${response.error?.message}`);\n }\n return response.data.prompts;\n },\n\n /**\n * Get a prompt with arguments\n */\n get: async (name: string, args?: Record<string, string>): Promise<PromptResultWrapper> => {\n const response = await this.getPrompt(name, args);\n return this.wrapPromptResult(response);\n },\n };\n\n // ═══════════════════════════════════════════════════════════════════\n // RAW PROTOCOL ACCESS\n // ═══════════════════════════════════════════════════════════════════\n\n readonly raw = {\n /**\n * Send any JSON-RPC request\n */\n request: async (message: {\n jsonrpc: '2.0';\n id: string | number;\n method: string;\n params?: Record<string, unknown>;\n }): Promise<JSONRPCResponse> => {\n this.ensureConnected();\n const start = Date.now();\n const response = await this.transport!.request(message);\n this.traceRequest(message.method, message.params, message.id, response, Date.now() - start);\n return response;\n },\n\n /**\n * Send a notification (no response expected)\n */\n notify: async (message: { jsonrpc: '2.0'; method: string; params?: Record<string, unknown> }): Promise<void> => {\n this.ensureConnected();\n await this.transport!.notify(message);\n },\n\n /**\n * Send raw string data (for error testing)\n */\n sendRaw: async (data: string): Promise<JSONRPCResponse> => {\n this.ensureConnected();\n return this.transport!.sendRaw(data);\n },\n };\n\n get lastRequestId(): string | number {\n return this._lastRequestId;\n }\n\n // ═══════════════════════════════════════════════════════════════════\n // TRANSPORT INFO\n // ═══════════════════════════════════════════════════════════════════\n\n /**\n * Get transport information and utilities\n */\n get transport_info(): {\n type: TestTransportType;\n isConnected: () => boolean;\n messageEndpoint: string | undefined;\n connectionCount: number;\n reconnectCount: number;\n lastRequestHeaders: Record<string, string>;\n simulateDisconnect: () => Promise<void>;\n waitForReconnect: (timeoutMs: number) => Promise<void>;\n } {\n return {\n type: this.config.transport,\n isConnected: () => this.transport?.isConnected() ?? false,\n messageEndpoint: this.transport?.getMessageEndpoint?.(),\n connectionCount: this.transport?.getConnectionCount?.() ?? 0,\n reconnectCount: this.transport?.getReconnectCount?.() ?? 0,\n lastRequestHeaders: this.transport?.getLastRequestHeaders?.() ?? {},\n simulateDisconnect: async () => {\n await this.transport?.simulateDisconnect?.();\n },\n waitForReconnect: async (timeoutMs: number) => {\n await this.transport?.waitForReconnect?.(timeoutMs);\n },\n };\n }\n\n // Alias for transport info\n get transport_() {\n return this.transport_info;\n }\n\n // ═══════════════════════════════════════════════════════════════════\n // NOTIFICATIONS\n // ═══════════════════════════════════════════════════════════════════\n\n readonly notifications = {\n /**\n * Start collecting server notifications\n */\n collect: (): NotificationCollector => {\n return new NotificationCollector(this._notifications);\n },\n\n /**\n * Collect progress notifications specifically\n */\n collectProgress: (): ProgressCollector => {\n return new ProgressCollector(this._progressUpdates);\n },\n\n /**\n * Send a notification to the server\n */\n send: async (method: string, params?: Record<string, unknown>): Promise<void> => {\n await this.raw.notify({ jsonrpc: '2.0', method, params });\n },\n };\n\n // ═══════════════════════════════════════════════════════════════════\n // LOGGING & DEBUGGING\n // ═══════════════════════════════════════════════════════════════════\n\n readonly logs = {\n all: (): LogEntry[] => [...this._logs],\n\n filter: (level: 'debug' | 'info' | 'warn' | 'error'): LogEntry[] => this._logs.filter((l) => l.level === level),\n\n search: (text: string): LogEntry[] => this._logs.filter((l) => l.message.includes(text)),\n\n last: (): LogEntry | undefined => this._logs[this._logs.length - 1],\n\n clear: (): void => {\n this._logs = [];\n },\n };\n\n readonly trace = {\n all: (): RequestTrace[] => [...this._traces],\n\n last: (): RequestTrace | undefined => this._traces[this._traces.length - 1],\n\n clear: (): void => {\n this._traces = [];\n },\n };\n\n // ═══════════════════════════════════════════════════════════════════\n // MOCKING & INTERCEPTION\n // ═══════════════════════════════════════════════════════════════════\n\n /**\n * API for mocking MCP requests\n *\n * @example\n * ```typescript\n * // Mock a specific tool call\n * const handle = mcp.mock.tool('my-tool', { result: 'mocked!' });\n *\n * // Mock with params matching\n * mcp.mock.add({\n * method: 'tools/call',\n * params: { name: 'my-tool' },\n * response: mockResponse.toolResult([{ type: 'text', text: 'mocked' }]),\n * });\n *\n * // Clear all mocks after test\n * mcp.mock.clear();\n * ```\n */\n readonly mock = {\n /**\n * Add a mock definition\n */\n add: (mock: MockDefinition): MockHandle => {\n return this._interceptors.mocks.add(mock);\n },\n\n /**\n * Mock a tools/call request for a specific tool\n */\n tool: (name: string, result: unknown, options?: { times?: number; delay?: number }): MockHandle => {\n return this._interceptors.mocks.add({\n method: 'tools/call',\n params: { name },\n response: mockResponse.toolResult([\n { type: 'text', text: typeof result === 'string' ? result : JSON.stringify(result) },\n ]),\n times: options?.times,\n delay: options?.delay,\n });\n },\n\n /**\n * Mock a tools/call request to return an error\n */\n toolError: (name: string, code: number, message: string, options?: { times?: number }): MockHandle => {\n return this._interceptors.mocks.add({\n method: 'tools/call',\n params: { name },\n response: mockResponse.error(code, message),\n times: options?.times,\n });\n },\n\n /**\n * Mock a resources/read request\n */\n resource: (\n uri: string,\n content: string | { text?: string; blob?: string; mimeType?: string },\n options?: { times?: number; delay?: number },\n ): MockHandle => {\n const contentObj = typeof content === 'string' ? { uri, text: content } : { uri, ...content };\n return this._interceptors.mocks.add({\n method: 'resources/read',\n params: { uri },\n response: mockResponse.resourceRead([contentObj]),\n times: options?.times,\n delay: options?.delay,\n });\n },\n\n /**\n * Mock a resources/read request to return an error\n */\n resourceError: (uri: string, options?: { times?: number }): MockHandle => {\n return this._interceptors.mocks.add({\n method: 'resources/read',\n params: { uri },\n response: mockResponse.errors.resourceNotFound(uri),\n times: options?.times,\n });\n },\n\n /**\n * Mock the tools/list response\n */\n toolsList: (\n tools: Array<{ name: string; description?: string; inputSchema?: Record<string, unknown> }>,\n options?: { times?: number },\n ): MockHandle => {\n return this._interceptors.mocks.add({\n method: 'tools/list',\n response: mockResponse.toolsList(tools),\n times: options?.times,\n });\n },\n\n /**\n * Mock the resources/list response\n */\n resourcesList: (\n resources: Array<{ uri: string; name?: string; description?: string; mimeType?: string }>,\n options?: { times?: number },\n ): MockHandle => {\n return this._interceptors.mocks.add({\n method: 'resources/list',\n response: mockResponse.resourcesList(resources),\n times: options?.times,\n });\n },\n\n /**\n * Clear all mocks\n */\n clear: (): void => {\n this._interceptors.mocks.clear();\n },\n\n /**\n * Get all active mocks\n */\n all: (): MockDefinition[] => {\n return this._interceptors.mocks.getAll();\n },\n };\n\n /**\n * API for intercepting requests and responses\n *\n * @example\n * ```typescript\n * // Log all requests\n * const remove = mcp.intercept.request((ctx) => {\n * console.log('Request:', ctx.request.method);\n * return { action: 'passthrough' };\n * });\n *\n * // Modify requests\n * mcp.intercept.request((ctx) => {\n * if (ctx.request.method === 'tools/call') {\n * return {\n * action: 'modify',\n * request: { ...ctx.request, params: { ...ctx.request.params, extra: true } },\n * };\n * }\n * return { action: 'passthrough' };\n * });\n *\n * // Add latency to all requests\n * mcp.intercept.delay(100);\n *\n * // Clean up\n * remove();\n * mcp.intercept.clear();\n * ```\n */\n readonly intercept = {\n /**\n * Add a request interceptor\n * @returns Function to remove the interceptor\n */\n request: (interceptor: RequestInterceptor): (() => void) => {\n return (this._interceptors as DefaultInterceptorChain).addRequestInterceptor(interceptor);\n },\n\n /**\n * Add a response interceptor\n * @returns Function to remove the interceptor\n */\n response: (interceptor: ResponseInterceptor): (() => void) => {\n return (this._interceptors as DefaultInterceptorChain).addResponseInterceptor(interceptor);\n },\n\n /**\n * Add latency to all requests\n * @returns Function to remove the interceptor\n */\n delay: (ms: number): (() => void) => {\n return (this._interceptors as DefaultInterceptorChain).addRequestInterceptor(async () => {\n await new Promise((r) => setTimeout(r, ms));\n return { action: 'passthrough' };\n });\n },\n\n /**\n * Fail requests matching a method\n * @returns Function to remove the interceptor\n */\n failMethod: (method: string, error?: string): (() => void) => {\n return (this._interceptors as DefaultInterceptorChain).addRequestInterceptor((ctx) => {\n if (ctx.request.method === method) {\n return { action: 'error', error: new Error(error ?? `Intercepted: ${method}`) };\n }\n return { action: 'passthrough' };\n });\n },\n\n /**\n * Clear all interceptors (but not mocks)\n */\n clear: (): void => {\n (this._interceptors as DefaultInterceptorChain).request = [];\n (this._interceptors as DefaultInterceptorChain).response = [];\n },\n\n /**\n * Clear everything (interceptors and mocks)\n */\n clearAll: (): void => {\n (this._interceptors as DefaultInterceptorChain).clear();\n },\n };\n\n // ═══════════════════════════════════════════════════════════════════\n // TIMEOUT\n // ═══════════════════════════════════════════════════════════════════\n\n setTimeout(ms: number): void {\n this.config.timeout = ms;\n if (this.transport) {\n this.transport.setTimeout(ms);\n }\n }\n\n // ═══════════════════════════════════════════════════════════════════\n // PRIVATE: MCP OPERATIONS\n // ═══════════════════════════════════════════════════════════════════\n\n private async initialize(): Promise<McpResponse<InitializeResult>> {\n // Use configured capabilities or default to base capabilities\n const capabilities: TestClientCapabilities = this.config.capabilities ?? {\n sampling: {},\n };\n\n return this.request<InitializeResult>('initialize', {\n protocolVersion: this.config.protocolVersion,\n capabilities,\n clientInfo: this.config.clientInfo,\n });\n }\n\n private async listTools(): Promise<McpResponse<ListToolsResult>> {\n return this.request<ListToolsResult>('tools/list', {});\n }\n\n private async callTool(name: string, args?: Record<string, unknown>): Promise<McpResponse<CallToolResult>> {\n return this.request<CallToolResult>('tools/call', {\n name,\n arguments: args ?? {},\n });\n }\n\n private async listResources(): Promise<McpResponse<ListResourcesResult>> {\n return this.request<ListResourcesResult>('resources/list', {});\n }\n\n private async listResourceTemplates(): Promise<McpResponse<ListResourceTemplatesResult>> {\n return this.request<ListResourceTemplatesResult>('resources/templates/list', {});\n }\n\n private async readResource(uri: string): Promise<McpResponse<ReadResourceResult>> {\n return this.request<ReadResourceResult>('resources/read', { uri });\n }\n\n private async listPrompts(): Promise<McpResponse<ListPromptsResult>> {\n return this.request<ListPromptsResult>('prompts/list', {});\n }\n\n private async getPrompt(name: string, args?: Record<string, string>): Promise<McpResponse<GetPromptResult>> {\n return this.request<GetPromptResult>('prompts/get', {\n name,\n arguments: args ?? {},\n });\n }\n\n // ═══════════════════════════════════════════════════════════════════\n // PRIVATE: TRANSPORT & REQUEST HELPERS\n // ═══════════════════════════════════════════════════════════════════\n\n private createTransport(): McpTransport {\n switch (this.config.transport) {\n case 'streamable-http':\n return new StreamableHttpTransport({\n baseUrl: this.config.baseUrl,\n timeout: this.config.timeout,\n auth: this.config.auth,\n publicMode: this.config.publicMode,\n debug: this.config.debug,\n interceptors: this._interceptors,\n clientInfo: this.config.clientInfo,\n });\n case 'sse':\n // TODO: Implement SSE transport\n throw new Error('SSE transport not yet implemented');\n default:\n throw new Error(`Unknown transport type: ${this.config.transport}`);\n }\n }\n\n private async request<T>(method: string, params: Record<string, unknown>): Promise<McpResponse<T>> {\n this.ensureConnected();\n\n const id = ++this.requestIdCounter;\n this._lastRequestId = id;\n const start = Date.now();\n\n try {\n const response = await this.transport!.request<T>({\n jsonrpc: '2.0',\n id,\n method,\n params,\n });\n\n const durationMs = Date.now() - start;\n this.updateSessionActivity();\n\n if ('error' in response && response.error) {\n const error = response.error as McpErrorInfo;\n this.traceRequest(method, params, id, response, durationMs);\n return {\n success: false,\n error,\n durationMs,\n requestId: id,\n };\n }\n\n this.traceRequest(method, params, id, response, durationMs);\n return {\n success: true,\n data: response.result as T,\n durationMs,\n requestId: id,\n };\n } catch (err) {\n const durationMs = Date.now() - start;\n const error: McpErrorInfo = {\n code: -32603,\n message: err instanceof Error ? err.message : 'Unknown error',\n };\n return {\n success: false,\n error,\n durationMs,\n requestId: id,\n };\n }\n }\n\n private ensureConnected(): void {\n if (!this.transport?.isConnected()) {\n throw new Error('Not connected to MCP server. Call connect() first.');\n }\n }\n\n private updateSessionActivity(): void {\n if (this._sessionInfo) {\n this._sessionInfo.lastActivityAt = new Date();\n this._sessionInfo.requestCount++;\n }\n }\n\n // ═══════════════════════════════════════════════════════════════════\n // PRIVATE: RESULT WRAPPERS\n // ═══════════════════════════════════════════════════════════════════\n\n private wrapToolResult(response: McpResponse<CallToolResult>): ToolResultWrapper {\n const raw = response.data ?? { content: [] };\n const isError = !response.success || raw.isError === true;\n\n // Check for Tool UI response - has UI metadata in _meta\n // Platform-specific HTML keys:\n // - OpenAI: openai/html\n // - ext-apps: ui/html\n // - Others: frontmcp/html (+ ui/html for compatibility)\n const meta = raw._meta as Record<string, unknown> | undefined;\n const hasUI =\n meta?.['ui/html'] !== undefined ||\n meta?.['ui/component'] !== undefined ||\n meta?.['openai/html'] !== undefined ||\n meta?.['frontmcp/html'] !== undefined;\n const structuredContent = (raw as Record<string, unknown>)['structuredContent'];\n\n return {\n raw,\n isSuccess: !isError,\n isError,\n error: response.error,\n durationMs: response.durationMs,\n json<T>(): T {\n // For Tool UI responses, return structuredContent (the typed output)\n if (hasUI && structuredContent !== undefined) {\n return structuredContent as T;\n }\n // For regular responses, parse text content as JSON\n const textContent = raw.content?.find((c) => c.type === 'text');\n if (textContent && 'text' in textContent) {\n return JSON.parse(textContent.text) as T;\n }\n throw new Error('No text content to parse as JSON');\n },\n text(): string | undefined {\n const textContent = raw.content?.find((c) => c.type === 'text');\n if (textContent && 'text' in textContent) {\n return textContent.text;\n }\n return undefined;\n },\n hasTextContent(): boolean {\n return raw.content?.some((c) => c.type === 'text') ?? false;\n },\n hasImageContent(): boolean {\n return raw.content?.some((c) => c.type === 'image') ?? false;\n },\n hasResourceContent(): boolean {\n return raw.content?.some((c) => c.type === 'resource') ?? false;\n },\n hasToolUI(): boolean {\n return hasUI;\n },\n };\n }\n\n private wrapResourceContent(response: McpResponse<ReadResourceResult>): ResourceContentWrapper {\n const raw = response.data ?? { contents: [] };\n const isError = !response.success;\n const firstContent = raw.contents?.[0];\n\n return {\n raw,\n isSuccess: !isError,\n isError,\n error: response.error,\n durationMs: response.durationMs,\n json<T>(): T {\n if (firstContent && 'text' in firstContent) {\n return JSON.parse(firstContent.text) as T;\n }\n throw new Error('No text content to parse as JSON');\n },\n text(): string | undefined {\n if (firstContent && 'text' in firstContent) {\n return firstContent.text;\n }\n return undefined;\n },\n mimeType(): string | undefined {\n return firstContent?.mimeType;\n },\n hasMimeType(type: string): boolean {\n return firstContent?.mimeType === type;\n },\n };\n }\n\n private wrapPromptResult(response: McpResponse<GetPromptResult>): PromptResultWrapper {\n const raw = response.data ?? { messages: [] };\n const isError = !response.success;\n\n return {\n raw,\n isSuccess: !isError,\n isError,\n error: response.error,\n durationMs: response.durationMs,\n messages: raw.messages ?? [],\n description: raw.description,\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════\n // PRIVATE: LOGGING & TRACING\n // ═══════════════════════════════════════════════════════════════════\n\n private log(level: 'debug' | 'info' | 'warn' | 'error', message: string, data?: unknown): void {\n const entry: LogEntry = {\n level,\n message,\n timestamp: new Date(),\n data,\n };\n this._logs.push(entry);\n\n if (this.config.debug) {\n console.log(`[${level.toUpperCase()}] ${message}`, data ?? '');\n }\n }\n\n private traceRequest(\n method: string,\n params: unknown,\n id: string | number,\n response: JSONRPCResponse,\n durationMs: number,\n ): void {\n this._traces.push({\n request: { method, params, id },\n response: {\n result: 'result' in response ? response.result : undefined,\n error: 'error' in response ? (response.error as McpErrorInfo) : undefined,\n },\n durationMs,\n timestamp: new Date(),\n });\n }\n\n // ═══════════════════════════════════════════════════════════════════\n // PRIVATE: TOKEN PARSING\n // ═══════════════════════════════════════════════════════════════════\n\n private parseScopesFromToken(token: string): string[] {\n try {\n const payload = this.decodeJwtPayload(token);\n if (!payload) return [];\n const scope = payload['scope'];\n const scopes = payload['scopes'];\n if (typeof scope === 'string') {\n return scope.split(' ');\n }\n if (Array.isArray(scopes)) {\n return scopes as string[];\n }\n return [];\n } catch {\n return [];\n }\n }\n\n private parseUserFromToken(token: string): { sub: string; email?: string; name?: string } | undefined {\n try {\n const payload = this.decodeJwtPayload(token);\n const sub = payload?.['sub'];\n if (!sub || typeof sub !== 'string') return undefined;\n return {\n sub,\n email: payload['email'] as string | undefined,\n name: payload['name'] as string | undefined,\n };\n } catch {\n return undefined;\n }\n }\n\n private decodeJwtPayload(token: string): Record<string, unknown> | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n const payload = Buffer.from(parts[1], 'base64url').toString('utf-8');\n return JSON.parse(payload);\n } catch {\n return null;\n }\n }\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// NOTIFICATION COLLECTORS\n// ═══════════════════════════════════════════════════════════════════\n\nclass NotificationCollector {\n constructor(private readonly notifications: NotificationEntry[]) {}\n\n get received(): NotificationEntry[] {\n return [...this.notifications];\n }\n\n has(method: string): boolean {\n return this.notifications.some((n) => n.method === method);\n }\n\n async waitFor(method: string, timeoutMs: number): Promise<NotificationEntry> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n const found = this.notifications.find((n) => n.method === method);\n if (found) return found;\n await new Promise((r) => setTimeout(r, 50));\n }\n throw new Error(`Timeout waiting for notification: ${method}`);\n }\n}\n\nclass ProgressCollector {\n constructor(private readonly updates: ProgressUpdate[]) {}\n\n get all(): ProgressUpdate[] {\n return [...this.updates];\n }\n\n async waitForComplete(timeoutMs: number): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n const last = this.updates[this.updates.length - 1];\n if (last && last.total !== undefined && last.progress >= last.total) {\n return;\n }\n await new Promise((r) => setTimeout(r, 50));\n }\n throw new Error('Timeout waiting for progress to complete');\n }\n}\n"]}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file mcp-test-client.types.ts
|
|
4
|
-
* @description Type definitions for the MCP Test Client
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.MCP_APPS_EXTENSION_KEY = void 0;
|
|
8
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
9
|
-
// CLIENT CAPABILITIES
|
|
10
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
11
|
-
/**
|
|
12
|
-
* MCP Apps extension key used for ext-apps platform detection.
|
|
13
|
-
* When a client sends this capability, the server detects it as an ext-apps client.
|
|
14
|
-
*/
|
|
15
|
-
exports.MCP_APPS_EXTENSION_KEY = 'io.modelcontextprotocol/ui';
|
|
16
|
-
//# sourceMappingURL=mcp-test-client.types.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-test-client.types.js","sourceRoot":"","sources":["../../../src/client/mcp-test-client.types.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA2EH,sEAAsE;AACtE,sBAAsB;AACtB,sEAAsE;AAEtE;;;GAGG;AACU,QAAA,sBAAsB,GAAG,4BAAqC,CAAC","sourcesContent":["/**\n * @file mcp-test-client.types.ts\n * @description Type definitions for the MCP Test Client\n */\n\nimport type {\n InitializeResult,\n ListToolsResult,\n CallToolResult,\n ListResourcesResult,\n ReadResourceResult,\n ListResourceTemplatesResult,\n ListPromptsResult,\n GetPromptResult,\n Tool,\n Resource,\n ResourceTemplate,\n Prompt,\n Implementation,\n} from '@modelcontextprotocol/sdk/types.js';\nimport type { TestPlatformType } from '../platform/platform-types';\n\n// ═══════════════════════════════════════════════════════════════════\n// JSON-RPC TYPES (simplified for testing)\n// ═══════════════════════════════════════════════════════════════════\n\n/**\n * Simplified JSON-RPC request type for testing\n */\nexport interface JSONRPCRequest {\n jsonrpc: '2.0';\n id?: string | number;\n method: string;\n params?: Record<string, unknown>;\n}\n\n/**\n * Simplified JSON-RPC response type for testing\n */\nexport interface JSONRPCResponse {\n jsonrpc: '2.0';\n id: string | number | null;\n result?: unknown;\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// TRANSPORT TYPES\n// ═══════════════════════════════════════════════════════════════════\n\nexport type TestTransportType = 'sse' | 'streamable-http';\n\nexport type TransportState = 'disconnected' | 'connecting' | 'connected' | 'error';\n\n// ═══════════════════════════════════════════════════════════════════\n// AUTH TYPES\n// ═══════════════════════════════════════════════════════════════════\n\nexport interface TestAuthConfig {\n /** Bearer token for authentication */\n token?: string;\n /** Additional headers to include in requests */\n headers?: Record<string, string>;\n}\n\n/**\n * Client information sent during MCP initialization.\n * Re-exported from MCP SDK's Implementation type.\n * Also used for User-Agent header to enable platform detection.\n *\n * Includes: name, version, title?, description?, icons?\n */\nexport type ClientInfo = Implementation;\n\n// ═══════════════════════════════════════════════════════════════════\n// CLIENT CAPABILITIES\n// ═══════════════════════════════════════════════════════════════════\n\n/**\n * MCP Apps extension key used for ext-apps platform detection.\n * When a client sends this capability, the server detects it as an ext-apps client.\n */\nexport const MCP_APPS_EXTENSION_KEY = 'io.modelcontextprotocol/ui' as const;\n\n/**\n * MCP Apps extension capability configuration.\n */\nexport interface McpAppsExtension {\n /** Supported MIME types (e.g., ['text/html+mcp']) */\n mimeTypes?: string[];\n}\n\n/**\n * Experimental capabilities for MCP clients.\n */\nexport interface ExperimentalCapabilities {\n /** MCP Apps (ext-apps) extension capability */\n [MCP_APPS_EXTENSION_KEY]?: McpAppsExtension;\n /** Other experimental capabilities */\n [key: string]: unknown;\n}\n\n/**\n * Client capabilities sent during MCP initialization.\n * These capabilities enable platform-specific detection and features.\n */\nexport interface TestClientCapabilities {\n /** Sampling capabilities */\n sampling?: Record<string, unknown>;\n /** Experimental capabilities including MCP Apps extension */\n experimental?: ExperimentalCapabilities;\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// CLIENT CONFIG\n// ═══════════════════════════════════════════════════════════════════\n\nexport interface McpTestClientConfig {\n /** Base URL of the MCP server */\n baseUrl: string;\n /** Transport type to use (default: 'streamable-http') */\n transport?: TestTransportType;\n /** Authentication configuration */\n auth?: TestAuthConfig;\n /**\n * Enable public mode - skip authentication entirely.\n * When true, no Authorization header is sent and anonymous token is not requested.\n * Use this for testing public/unauthenticated endpoints in CI/CD pipelines.\n */\n publicMode?: boolean;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n /** Enable debug logging (default: false) */\n debug?: boolean;\n /** MCP protocol version to request (default: '2024-11-05') */\n protocolVersion?: string;\n /** Client info to send during initialization and for platform detection */\n clientInfo?: ClientInfo;\n /**\n * Client capabilities sent during MCP initialization.\n * Use this to enable platform-specific detection via capability extensions.\n *\n * Example for ext-apps:\n * ```typescript\n * capabilities: {\n * experimental: {\n * 'io.modelcontextprotocol/ui': { mimeTypes: ['text/html+mcp'] }\n * }\n * }\n * ```\n */\n capabilities?: TestClientCapabilities;\n /**\n * Platform type for testing platform-specific meta keys.\n * When set, automatically configures clientInfo and capabilities for platform detection.\n *\n * Platform-specific behavior:\n * - `openai`: Uses openai/* meta keys\n * - `ext-apps`: Uses ui/* meta keys per SEP-1865, sets io.modelcontextprotocol/ui capability\n * - Others: Uses frontmcp/* + ui/* keys for compatibility\n */\n platform?: TestPlatformType;\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// RESPONSE TYPES\n// ═══════════════════════════════════════════════════════════════════\n\nexport interface McpResponse<T> {\n /** Whether the request succeeded */\n success: boolean;\n /** Response data (if successful) */\n data?: T;\n /** Error information (if failed) */\n error?: McpErrorInfo;\n /** Request duration in milliseconds */\n durationMs: number;\n /** Request ID used for this request */\n requestId: string | number;\n}\n\nexport interface McpErrorInfo {\n /** JSON-RPC error code */\n code: number;\n /** Error message */\n message: string;\n /** Additional error data */\n data?: unknown;\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// TOOL RESULT WRAPPER\n// ═══════════════════════════════════════════════════════════════════\n\nexport interface ToolResultWrapper {\n /** Raw CallToolResult from MCP */\n raw: CallToolResult;\n /** Whether the tool call was successful (no isError flag) */\n isSuccess: boolean;\n /** Whether the tool call failed */\n isError: boolean;\n /** Error information if failed */\n error?: McpErrorInfo;\n /** Duration of the tool call in ms */\n durationMs: number;\n /**\n * Parse tool output as JSON\n *\n * For Tool UI responses: returns structuredContent (the typed output)\n * For regular responses: parses text content as JSON\n */\n json<T = unknown>(): T;\n /** Get first text content */\n text(): string | undefined;\n /** Check if response has text content */\n hasTextContent(): boolean;\n /** Check if response has image content */\n hasImageContent(): boolean;\n /** Check if response has resource content */\n hasResourceContent(): boolean;\n /** Check if response has Tool UI metadata (ui/html in _meta) */\n hasToolUI(): boolean;\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// RESOURCE CONTENT WRAPPER\n// ═══════════════════════════════════════════════════════════════════\n\nexport interface ResourceContentWrapper {\n /** Raw ReadResourceResult from MCP */\n raw: ReadResourceResult;\n /** Whether the read was successful */\n isSuccess: boolean;\n /** Whether the read failed */\n isError: boolean;\n /** Error information if failed */\n error?: McpErrorInfo;\n /** Duration in ms */\n durationMs: number;\n /** Parse text content as JSON */\n json<T = unknown>(): T;\n /** Get text content */\n text(): string | undefined;\n /** Get MIME type */\n mimeType(): string | undefined;\n /** Check if has specific MIME type */\n hasMimeType(type: string): boolean;\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// PROMPT RESULT WRAPPER\n// ═══════════════════════════════════════════════════════════════════\n\nexport interface PromptResultWrapper {\n /** Raw GetPromptResult from MCP */\n raw: GetPromptResult;\n /** Whether the get was successful */\n isSuccess: boolean;\n /** Whether the get failed */\n isError: boolean;\n /** Error information if failed */\n error?: McpErrorInfo;\n /** Duration in ms */\n durationMs: number;\n /** Messages in the prompt */\n messages: GetPromptResult['messages'];\n /** Description from prompt result */\n description?: string;\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// LOGGING TYPES\n// ═══════════════════════════════════════════════════════════════════\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface LogEntry {\n /** Log level */\n level: LogLevel;\n /** Log message */\n message: string;\n /** Timestamp */\n timestamp: Date;\n /** Additional data */\n data?: unknown;\n}\n\nexport interface RequestTrace {\n /** Request that was sent */\n request: {\n method: string;\n params?: unknown;\n id: string | number;\n };\n /** Response that was received */\n response: {\n result?: unknown;\n error?: McpErrorInfo;\n };\n /** Duration in milliseconds */\n durationMs: number;\n /** Timestamp of the request */\n timestamp: Date;\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// NOTIFICATION TYPES\n// ═══════════════════════════════════════════════════════════════════\n\nexport interface NotificationEntry {\n /** Notification method */\n method: string;\n /** Notification params */\n params?: unknown;\n /** Timestamp received */\n timestamp: Date;\n}\n\nexport interface ProgressUpdate {\n /** Progress value (0-100 or custom) */\n progress: number;\n /** Total value */\n total?: number;\n /** Progress token */\n progressToken?: string | number;\n /** Timestamp */\n timestamp: Date;\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// SESSION TYPES\n// ═══════════════════════════════════════════════════════════════════\n\nexport interface SessionInfo {\n /** Session ID */\n id: string;\n /** When the session was created */\n createdAt: Date;\n /** When the last request was made */\n lastActivityAt: Date;\n /** Number of requests made in this session */\n requestCount: number;\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// AUTH STATE\n// ═══════════════════════════════════════════════════════════════════\n\nexport interface AuthState {\n /** Whether the user is anonymous (no token) */\n isAnonymous: boolean;\n /** Current token (if any) */\n token?: string;\n /** Scopes from the token */\n scopes: string[];\n /** User information from token */\n user?: {\n sub: string;\n email?: string;\n name?: string;\n };\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// RE-EXPORTS FROM MCP SDK\n// ═══════════════════════════════════════════════════════════════════\n\nexport type {\n InitializeResult,\n ListToolsResult,\n CallToolResult,\n ListResourcesResult,\n ReadResourceResult,\n ListResourceTemplatesResult,\n ListPromptsResult,\n GetPromptResult,\n Tool,\n Resource,\n ResourceTemplate,\n Prompt,\n};\n"]}
|
package/src/errors/index.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file errors/index.ts
|
|
4
|
-
* @description Error classes for @frontmcp/testing
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.AssertionError = exports.ServerStartError = exports.McpProtocolError = exports.TimeoutError = exports.ConnectionError = exports.TestClientError = void 0;
|
|
8
|
-
/**
|
|
9
|
-
* Base error class for test client errors
|
|
10
|
-
*/
|
|
11
|
-
class TestClientError extends Error {
|
|
12
|
-
constructor(message) {
|
|
13
|
-
super(message);
|
|
14
|
-
this.name = 'TestClientError';
|
|
15
|
-
// Fix prototype chain for proper instanceof checks in transpiled code
|
|
16
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
exports.TestClientError = TestClientError;
|
|
20
|
-
/**
|
|
21
|
-
* Error thrown when connection fails
|
|
22
|
-
*/
|
|
23
|
-
class ConnectionError extends TestClientError {
|
|
24
|
-
cause;
|
|
25
|
-
constructor(message, cause) {
|
|
26
|
-
super(message);
|
|
27
|
-
this.cause = cause;
|
|
28
|
-
this.name = 'ConnectionError';
|
|
29
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
exports.ConnectionError = ConnectionError;
|
|
33
|
-
/**
|
|
34
|
-
* Error thrown when request times out
|
|
35
|
-
*/
|
|
36
|
-
class TimeoutError extends TestClientError {
|
|
37
|
-
timeoutMs;
|
|
38
|
-
constructor(message, timeoutMs) {
|
|
39
|
-
super(message);
|
|
40
|
-
this.timeoutMs = timeoutMs;
|
|
41
|
-
this.name = 'TimeoutError';
|
|
42
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
exports.TimeoutError = TimeoutError;
|
|
46
|
-
/**
|
|
47
|
-
* Error thrown when MCP returns an error response
|
|
48
|
-
*/
|
|
49
|
-
class McpProtocolError extends TestClientError {
|
|
50
|
-
code;
|
|
51
|
-
data;
|
|
52
|
-
constructor(message, code, data) {
|
|
53
|
-
super(message);
|
|
54
|
-
this.code = code;
|
|
55
|
-
this.data = data;
|
|
56
|
-
this.name = 'McpProtocolError';
|
|
57
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
exports.McpProtocolError = McpProtocolError;
|
|
61
|
-
/**
|
|
62
|
-
* Error thrown when server fails to start
|
|
63
|
-
*/
|
|
64
|
-
class ServerStartError extends TestClientError {
|
|
65
|
-
cause;
|
|
66
|
-
constructor(message, cause) {
|
|
67
|
-
super(message);
|
|
68
|
-
this.cause = cause;
|
|
69
|
-
this.name = 'ServerStartError';
|
|
70
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
exports.ServerStartError = ServerStartError;
|
|
74
|
-
/**
|
|
75
|
-
* Error thrown when assertion fails
|
|
76
|
-
*/
|
|
77
|
-
class AssertionError extends TestClientError {
|
|
78
|
-
constructor(message) {
|
|
79
|
-
super(message);
|
|
80
|
-
this.name = 'AssertionError';
|
|
81
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
exports.AssertionError = AssertionError;
|
|
85
|
-
//# sourceMappingURL=index.js.map
|
package/src/errors/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/errors/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;GAEG;AACH,MAAa,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,sEAAsE;QACtE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAPD,0CAOC;AAED;;GAEG;AACH,MAAa,eAAgB,SAAQ,eAAe;IACI;IAAtD,YAAY,OAAe,EAA2B,KAAa;QACjE,KAAK,CAAC,OAAO,CAAC,CAAC;QADqC,UAAK,GAAL,KAAK,CAAQ;QAEjE,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAND,0CAMC;AAED;;GAEG;AACH,MAAa,YAAa,SAAQ,eAAe;IACF;IAA7C,YAAY,OAAe,EAAkB,SAAiB;QAC5D,KAAK,CAAC,OAAO,CAAC,CAAC;QAD4B,cAAS,GAAT,SAAS,CAAQ;QAE5D,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAND,oCAMC;AAED;;GAEG;AACH,MAAa,gBAAiB,SAAQ,eAAe;IACN;IAA8B;IAA3E,YAAY,OAAe,EAAkB,IAAY,EAAkB,IAAc;QACvF,KAAK,CAAC,OAAO,CAAC,CAAC;QAD4B,SAAI,GAAJ,IAAI,CAAQ;QAAkB,SAAI,GAAJ,IAAI,CAAU;QAEvF,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAND,4CAMC;AAED;;GAEG;AACH,MAAa,gBAAiB,SAAQ,eAAe;IACG;IAAtD,YAAY,OAAe,EAA2B,KAAa;QACjE,KAAK,CAAC,OAAO,CAAC,CAAC;QADqC,UAAK,GAAL,KAAK,CAAQ;QAEjE,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAND,4CAMC;AAED;;GAEG;AACH,MAAa,cAAe,SAAQ,eAAe;IACjD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAND,wCAMC","sourcesContent":["/**\n * @file errors/index.ts\n * @description Error classes for @frontmcp/testing\n */\n\n/**\n * Base error class for test client errors\n */\nexport class TestClientError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'TestClientError';\n // Fix prototype chain for proper instanceof checks in transpiled code\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Error thrown when connection fails\n */\nexport class ConnectionError extends TestClientError {\n constructor(message: string, public override readonly cause?: Error) {\n super(message);\n this.name = 'ConnectionError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Error thrown when request times out\n */\nexport class TimeoutError extends TestClientError {\n constructor(message: string, public readonly timeoutMs: number) {\n super(message);\n this.name = 'TimeoutError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Error thrown when MCP returns an error response\n */\nexport class McpProtocolError extends TestClientError {\n constructor(message: string, public readonly code: number, public readonly data?: unknown) {\n super(message);\n this.name = 'McpProtocolError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Error thrown when server fails to start\n */\nexport class ServerStartError extends TestClientError {\n constructor(message: string, public override readonly cause?: Error) {\n super(message);\n this.name = 'ServerStartError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Error thrown when assertion fails\n */\nexport class AssertionError extends TestClientError {\n constructor(message: string) {\n super(message);\n this.name = 'AssertionError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n"]}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file example-tools/index.ts
|
|
4
|
-
* @description Barrel export for example tool configurations.
|
|
5
|
-
*
|
|
6
|
-
* These configurations provide consistent test fixtures for platform E2E testing.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```typescript
|
|
10
|
-
* import {
|
|
11
|
-
* BASIC_UI_TOOL_CONFIG,
|
|
12
|
-
* FULL_UI_TOOL_CONFIG,
|
|
13
|
-
* generateBasicUIToolOutput,
|
|
14
|
-
* EXPECTED_OPENAI_TOOL_CALL_META_KEYS,
|
|
15
|
-
* } from '@frontmcp/testing';
|
|
16
|
-
* ```
|
|
17
|
-
*/
|
|
18
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.EXPECTED_FRONTMCP_TOOL_CALL_META_KEYS = exports.EXPECTED_FRONTMCP_TOOLS_LIST_META_KEYS = exports.EXPECTED_EXTAPPS_TOOL_CALL_META_KEYS = exports.EXPECTED_EXTAPPS_TOOLS_LIST_META_KEYS = exports.EXPECTED_OPENAI_TOOL_CALL_META_KEYS = exports.EXPECTED_OPENAI_TOOLS_LIST_META_KEYS = exports.generateFullUIToolOutput = exports.generateBasicUIToolOutput = exports.fullUIToolOutputSchema = exports.fullUIToolInputSchema = exports.basicUIToolOutputSchema = exports.basicUIToolInputSchema = exports.FULL_UI_TOOL_CONFIG = exports.BASIC_UI_TOOL_CONFIG = void 0;
|
|
20
|
-
// Tool configurations
|
|
21
|
-
var tool_configs_1 = require("./tool-configs");
|
|
22
|
-
Object.defineProperty(exports, "BASIC_UI_TOOL_CONFIG", { enumerable: true, get: function () { return tool_configs_1.BASIC_UI_TOOL_CONFIG; } });
|
|
23
|
-
Object.defineProperty(exports, "FULL_UI_TOOL_CONFIG", { enumerable: true, get: function () { return tool_configs_1.FULL_UI_TOOL_CONFIG; } });
|
|
24
|
-
Object.defineProperty(exports, "basicUIToolInputSchema", { enumerable: true, get: function () { return tool_configs_1.basicUIToolInputSchema; } });
|
|
25
|
-
Object.defineProperty(exports, "basicUIToolOutputSchema", { enumerable: true, get: function () { return tool_configs_1.basicUIToolOutputSchema; } });
|
|
26
|
-
Object.defineProperty(exports, "fullUIToolInputSchema", { enumerable: true, get: function () { return tool_configs_1.fullUIToolInputSchema; } });
|
|
27
|
-
Object.defineProperty(exports, "fullUIToolOutputSchema", { enumerable: true, get: function () { return tool_configs_1.fullUIToolOutputSchema; } });
|
|
28
|
-
// Execution helpers
|
|
29
|
-
var tool_configs_2 = require("./tool-configs");
|
|
30
|
-
Object.defineProperty(exports, "generateBasicUIToolOutput", { enumerable: true, get: function () { return tool_configs_2.generateBasicUIToolOutput; } });
|
|
31
|
-
Object.defineProperty(exports, "generateFullUIToolOutput", { enumerable: true, get: function () { return tool_configs_2.generateFullUIToolOutput; } });
|
|
32
|
-
// Expected meta keys
|
|
33
|
-
var tool_configs_3 = require("./tool-configs");
|
|
34
|
-
Object.defineProperty(exports, "EXPECTED_OPENAI_TOOLS_LIST_META_KEYS", { enumerable: true, get: function () { return tool_configs_3.EXPECTED_OPENAI_TOOLS_LIST_META_KEYS; } });
|
|
35
|
-
Object.defineProperty(exports, "EXPECTED_OPENAI_TOOL_CALL_META_KEYS", { enumerable: true, get: function () { return tool_configs_3.EXPECTED_OPENAI_TOOL_CALL_META_KEYS; } });
|
|
36
|
-
Object.defineProperty(exports, "EXPECTED_EXTAPPS_TOOLS_LIST_META_KEYS", { enumerable: true, get: function () { return tool_configs_3.EXPECTED_EXTAPPS_TOOLS_LIST_META_KEYS; } });
|
|
37
|
-
Object.defineProperty(exports, "EXPECTED_EXTAPPS_TOOL_CALL_META_KEYS", { enumerable: true, get: function () { return tool_configs_3.EXPECTED_EXTAPPS_TOOL_CALL_META_KEYS; } });
|
|
38
|
-
Object.defineProperty(exports, "EXPECTED_FRONTMCP_TOOLS_LIST_META_KEYS", { enumerable: true, get: function () { return tool_configs_3.EXPECTED_FRONTMCP_TOOLS_LIST_META_KEYS; } });
|
|
39
|
-
Object.defineProperty(exports, "EXPECTED_FRONTMCP_TOOL_CALL_META_KEYS", { enumerable: true, get: function () { return tool_configs_3.EXPECTED_FRONTMCP_TOOL_CALL_META_KEYS; } });
|
|
40
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/example-tools/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,sBAAsB;AACtB,+CAOwB;AANtB,oHAAA,oBAAoB,OAAA;AACpB,mHAAA,mBAAmB,OAAA;AACnB,sHAAA,sBAAsB,OAAA;AACtB,uHAAA,uBAAuB,OAAA;AACvB,qHAAA,qBAAqB,OAAA;AACrB,sHAAA,sBAAsB,OAAA;AAGxB,oBAAoB;AACpB,+CAAqF;AAA5E,yHAAA,yBAAyB,OAAA;AAAE,wHAAA,wBAAwB,OAAA;AAE5D,qBAAqB;AACrB,+CAOwB;AANtB,oIAAA,oCAAoC,OAAA;AACpC,mIAAA,mCAAmC,OAAA;AACnC,qIAAA,qCAAqC,OAAA;AACrC,oIAAA,oCAAoC,OAAA;AACpC,sIAAA,sCAAsC,OAAA;AACtC,qIAAA,qCAAqC,OAAA","sourcesContent":["/**\n * @file example-tools/index.ts\n * @description Barrel export for example tool configurations.\n *\n * These configurations provide consistent test fixtures for platform E2E testing.\n *\n * @example\n * ```typescript\n * import {\n * BASIC_UI_TOOL_CONFIG,\n * FULL_UI_TOOL_CONFIG,\n * generateBasicUIToolOutput,\n * EXPECTED_OPENAI_TOOL_CALL_META_KEYS,\n * } from '@frontmcp/testing';\n * ```\n */\n\n// Tool configurations\nexport {\n BASIC_UI_TOOL_CONFIG,\n FULL_UI_TOOL_CONFIG,\n basicUIToolInputSchema,\n basicUIToolOutputSchema,\n fullUIToolInputSchema,\n fullUIToolOutputSchema,\n} from './tool-configs';\n\n// Execution helpers\nexport { generateBasicUIToolOutput, generateFullUIToolOutput } from './tool-configs';\n\n// Expected meta keys\nexport {\n EXPECTED_OPENAI_TOOLS_LIST_META_KEYS,\n EXPECTED_OPENAI_TOOL_CALL_META_KEYS,\n EXPECTED_EXTAPPS_TOOLS_LIST_META_KEYS,\n EXPECTED_EXTAPPS_TOOL_CALL_META_KEYS,\n EXPECTED_FRONTMCP_TOOLS_LIST_META_KEYS,\n EXPECTED_FRONTMCP_TOOL_CALL_META_KEYS,\n} from './tool-configs';\n"]}
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @file tool-configs.ts
|
|
4
|
-
* @description Shared tool configurations for platform E2E testing.
|
|
5
|
-
*
|
|
6
|
-
* These configurations provide consistent test fixtures for validating
|
|
7
|
-
* platform-specific meta key behavior across E2E test projects.
|
|
8
|
-
*
|
|
9
|
-
* @example Usage in E2E tool implementation
|
|
10
|
-
* ```typescript
|
|
11
|
-
* import { Tool, ToolContext } from '@frontmcp/sdk';
|
|
12
|
-
* import { BASIC_UI_TOOL_CONFIG, FULL_UI_TOOL_CONFIG } from '@frontmcp/testing';
|
|
13
|
-
*
|
|
14
|
-
* @Tool({
|
|
15
|
-
* name: BASIC_UI_TOOL_CONFIG.name,
|
|
16
|
-
* description: BASIC_UI_TOOL_CONFIG.description,
|
|
17
|
-
* ui: BASIC_UI_TOOL_CONFIG.ui,
|
|
18
|
-
* })
|
|
19
|
-
* export class BasicUITool extends ToolContext<typeof inputSchema, typeof outputSchema> {
|
|
20
|
-
* async execute(input) {
|
|
21
|
-
* return { message: `Hello, ${input.name}!`, timestamp: Date.now() };
|
|
22
|
-
* }
|
|
23
|
-
* }
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
-
exports.EXPECTED_FRONTMCP_TOOL_CALL_META_KEYS = exports.EXPECTED_FRONTMCP_TOOLS_LIST_META_KEYS = exports.EXPECTED_EXTAPPS_TOOL_CALL_META_KEYS = exports.EXPECTED_EXTAPPS_TOOLS_LIST_META_KEYS = exports.EXPECTED_OPENAI_TOOL_CALL_META_KEYS = exports.EXPECTED_OPENAI_TOOLS_LIST_META_KEYS = exports.FULL_UI_TOOL_CONFIG = exports.fullUIToolOutputSchema = exports.fullUIToolInputSchema = exports.BASIC_UI_TOOL_CONFIG = exports.basicUIToolOutputSchema = exports.basicUIToolInputSchema = void 0;
|
|
28
|
-
exports.generateBasicUIToolOutput = generateBasicUIToolOutput;
|
|
29
|
-
exports.generateFullUIToolOutput = generateFullUIToolOutput;
|
|
30
|
-
const zod_1 = require("zod");
|
|
31
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
32
|
-
// BASIC UI TOOL CONFIG
|
|
33
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
34
|
-
/**
|
|
35
|
-
* Input schema for the basic UI tool.
|
|
36
|
-
*/
|
|
37
|
-
exports.basicUIToolInputSchema = zod_1.z.object({
|
|
38
|
-
name: zod_1.z.string().optional().default('World'),
|
|
39
|
-
});
|
|
40
|
-
/**
|
|
41
|
-
* Output schema for the basic UI tool.
|
|
42
|
-
*/
|
|
43
|
-
exports.basicUIToolOutputSchema = zod_1.z.object({
|
|
44
|
-
message: zod_1.z.string(),
|
|
45
|
-
timestamp: zod_1.z.number(),
|
|
46
|
-
});
|
|
47
|
-
/**
|
|
48
|
-
* Basic UI tool configuration with minimal UI config.
|
|
49
|
-
* Use this for testing that platform-specific meta keys are correctly applied.
|
|
50
|
-
*/
|
|
51
|
-
exports.BASIC_UI_TOOL_CONFIG = {
|
|
52
|
-
name: 'platform-test-basic',
|
|
53
|
-
description: 'Basic UI tool for platform testing',
|
|
54
|
-
inputSchema: exports.basicUIToolInputSchema,
|
|
55
|
-
outputSchema: exports.basicUIToolOutputSchema,
|
|
56
|
-
ui: {
|
|
57
|
-
/**
|
|
58
|
-
* Simple template that displays the output.
|
|
59
|
-
* Works with all platforms.
|
|
60
|
-
*/
|
|
61
|
-
template: `
|
|
62
|
-
<div class="platform-test-basic">
|
|
63
|
-
<h1>Platform Test - Basic</h1>
|
|
64
|
-
<p>Message: {output.message}</p>
|
|
65
|
-
<p>Timestamp: {output.timestamp}</p>
|
|
66
|
-
</div>
|
|
67
|
-
`.trim(),
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
71
|
-
// FULL UI TOOL CONFIG
|
|
72
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
73
|
-
/**
|
|
74
|
-
* Input schema for the full UI tool.
|
|
75
|
-
*/
|
|
76
|
-
exports.fullUIToolInputSchema = zod_1.z.object({
|
|
77
|
-
name: zod_1.z.string().optional().default('World'),
|
|
78
|
-
count: zod_1.z.number().optional().default(1),
|
|
79
|
-
});
|
|
80
|
-
/**
|
|
81
|
-
* Output schema for the full UI tool.
|
|
82
|
-
*/
|
|
83
|
-
exports.fullUIToolOutputSchema = zod_1.z.object({
|
|
84
|
-
message: zod_1.z.string(),
|
|
85
|
-
count: zod_1.z.number(),
|
|
86
|
-
items: zod_1.z.array(zod_1.z.string()),
|
|
87
|
-
timestamp: zod_1.z.number(),
|
|
88
|
-
});
|
|
89
|
-
/**
|
|
90
|
-
* Full UI tool configuration with all UI options.
|
|
91
|
-
* Use this for testing comprehensive platform-specific meta key behavior.
|
|
92
|
-
*/
|
|
93
|
-
exports.FULL_UI_TOOL_CONFIG = {
|
|
94
|
-
name: 'platform-test-full',
|
|
95
|
-
description: 'Full UI tool with all options for comprehensive platform testing',
|
|
96
|
-
inputSchema: exports.fullUIToolInputSchema,
|
|
97
|
-
outputSchema: exports.fullUIToolOutputSchema,
|
|
98
|
-
ui: {
|
|
99
|
-
/**
|
|
100
|
-
* Template with more complex UI elements.
|
|
101
|
-
*/
|
|
102
|
-
template: `
|
|
103
|
-
<div class="platform-test-full">
|
|
104
|
-
<h1>Platform Test - Full</h1>
|
|
105
|
-
<div class="message-box">
|
|
106
|
-
<strong>Message:</strong> {output.message}
|
|
107
|
-
</div>
|
|
108
|
-
<div class="count-box">
|
|
109
|
-
<strong>Count:</strong> {output.count}
|
|
110
|
-
</div>
|
|
111
|
-
<div class="items-list">
|
|
112
|
-
<strong>Items:</strong>
|
|
113
|
-
<ul>
|
|
114
|
-
{output.items.map(item => <li key={item}>{item}</li>)}
|
|
115
|
-
</ul>
|
|
116
|
-
</div>
|
|
117
|
-
<footer>
|
|
118
|
-
<small>Generated at: {new Date(output.timestamp).toISOString()}</small>
|
|
119
|
-
</footer>
|
|
120
|
-
</div>
|
|
121
|
-
`.trim(),
|
|
122
|
-
/**
|
|
123
|
-
* Widget is accessible for callback invocations.
|
|
124
|
-
*/
|
|
125
|
-
widgetAccessible: true,
|
|
126
|
-
/**
|
|
127
|
-
* Invocation status messages for OpenAI.
|
|
128
|
-
*/
|
|
129
|
-
invocationStatus: {
|
|
130
|
-
invoking: 'Processing request...',
|
|
131
|
-
invoked: 'Request completed',
|
|
132
|
-
},
|
|
133
|
-
/**
|
|
134
|
-
* Content Security Policy configuration.
|
|
135
|
-
*/
|
|
136
|
-
csp: {
|
|
137
|
-
connectDomains: ['https://api.example.com'],
|
|
138
|
-
resourceDomains: ['https://cdn.example.com'],
|
|
139
|
-
},
|
|
140
|
-
/**
|
|
141
|
-
* Display mode for the widget.
|
|
142
|
-
*/
|
|
143
|
-
displayMode: 'inline',
|
|
144
|
-
/**
|
|
145
|
-
* Prefers border around the widget.
|
|
146
|
-
*/
|
|
147
|
-
prefersBorder: true,
|
|
148
|
-
/**
|
|
149
|
-
* Custom sandbox domain.
|
|
150
|
-
*/
|
|
151
|
-
sandboxDomain: 'sandbox.example.com',
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
155
|
-
// TOOL EXECUTION HELPERS
|
|
156
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
157
|
-
/**
|
|
158
|
-
* Generate output for the basic UI tool.
|
|
159
|
-
*/
|
|
160
|
-
function generateBasicUIToolOutput(input) {
|
|
161
|
-
return {
|
|
162
|
-
message: `Hello, ${input.name}!`,
|
|
163
|
-
timestamp: Date.now(),
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Generate output for the full UI tool.
|
|
168
|
-
*/
|
|
169
|
-
function generateFullUIToolOutput(input) {
|
|
170
|
-
const items = [];
|
|
171
|
-
for (let i = 1; i <= input.count; i++) {
|
|
172
|
-
items.push(`Item ${i}`);
|
|
173
|
-
}
|
|
174
|
-
return {
|
|
175
|
-
message: `Hello, ${input.name}! You requested ${input.count} item(s).`,
|
|
176
|
-
count: input.count,
|
|
177
|
-
items,
|
|
178
|
-
timestamp: Date.now(),
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
182
|
-
// EXPECTED META KEYS
|
|
183
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
184
|
-
/**
|
|
185
|
-
* Expected meta keys for OpenAI platform in tools/list response.
|
|
186
|
-
*/
|
|
187
|
-
exports.EXPECTED_OPENAI_TOOLS_LIST_META_KEYS = [
|
|
188
|
-
'openai/outputTemplate',
|
|
189
|
-
'openai/resultCanProduceWidget',
|
|
190
|
-
'openai/widgetAccessible',
|
|
191
|
-
];
|
|
192
|
-
/**
|
|
193
|
-
* Expected meta keys for OpenAI platform in tools/call response.
|
|
194
|
-
*/
|
|
195
|
-
exports.EXPECTED_OPENAI_TOOL_CALL_META_KEYS = ['openai/html', 'openai/mimeType', 'openai/type'];
|
|
196
|
-
/**
|
|
197
|
-
* Expected meta keys for ext-apps platform in tools/list response (SEP-1865).
|
|
198
|
-
*/
|
|
199
|
-
exports.EXPECTED_EXTAPPS_TOOLS_LIST_META_KEYS = ['ui/resourceUri', 'ui/mimeType', 'ui/cdn', 'ui/type'];
|
|
200
|
-
/**
|
|
201
|
-
* Expected meta keys for ext-apps platform in tools/call response (SEP-1865).
|
|
202
|
-
*/
|
|
203
|
-
exports.EXPECTED_EXTAPPS_TOOL_CALL_META_KEYS = ['ui/html', 'ui/mimeType', 'ui/type'];
|
|
204
|
-
/**
|
|
205
|
-
* Expected meta keys for FrontMCP platforms in tools/list response (Claude, Cursor, etc.).
|
|
206
|
-
*/
|
|
207
|
-
exports.EXPECTED_FRONTMCP_TOOLS_LIST_META_KEYS = [
|
|
208
|
-
'frontmcp/outputTemplate',
|
|
209
|
-
'frontmcp/resultCanProduceWidget',
|
|
210
|
-
'ui/cdn',
|
|
211
|
-
'ui/type',
|
|
212
|
-
];
|
|
213
|
-
/**
|
|
214
|
-
* Expected meta keys for FrontMCP platforms in tools/call response (Claude, Cursor, etc.).
|
|
215
|
-
*/
|
|
216
|
-
exports.EXPECTED_FRONTMCP_TOOL_CALL_META_KEYS = [
|
|
217
|
-
'frontmcp/html',
|
|
218
|
-
'frontmcp/mimeType',
|
|
219
|
-
'ui/html',
|
|
220
|
-
'ui/mimeType',
|
|
221
|
-
];
|
|
222
|
-
//# sourceMappingURL=tool-configs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-configs.js","sourceRoot":"","sources":["../../../src/example-tools/tool-configs.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @file tool-configs.ts\n * @description Shared tool configurations for platform E2E testing.\n *\n * These configurations provide consistent test fixtures for validating\n * platform-specific meta key behavior across E2E test projects.\n *\n * @example Usage in E2E tool implementation\n * ```typescript\n * import { Tool, ToolContext } from '@frontmcp/sdk';\n * import { BASIC_UI_TOOL_CONFIG, FULL_UI_TOOL_CONFIG } from '@frontmcp/testing';\n *\n * @Tool({\n * name: BASIC_UI_TOOL_CONFIG.name,\n * description: BASIC_UI_TOOL_CONFIG.description,\n * ui: BASIC_UI_TOOL_CONFIG.ui,\n * })\n * export class BasicUITool extends ToolContext<typeof inputSchema, typeof outputSchema> {\n * async execute(input) {\n * return { message: `Hello, ${input.name}!`, timestamp: Date.now() };\n * }\n * }\n * ```\n */\n\nimport { z } from 'zod';\n\n// ═══════════════════════════════════════════════════════════════════\n// BASIC UI TOOL CONFIG\n// ═══════════════════════════════════════════════════════════════════\n\n/**\n * Input schema for the basic UI tool.\n */\nexport const basicUIToolInputSchema = z.object({\n name: z.string().optional().default('World'),\n});\n\n/**\n * Output schema for the basic UI tool.\n */\nexport const basicUIToolOutputSchema = z.object({\n message: z.string(),\n timestamp: z.number(),\n});\n\n/**\n * Basic UI tool configuration with minimal UI config.\n * Use this for testing that platform-specific meta keys are correctly applied.\n */\nexport const BASIC_UI_TOOL_CONFIG = {\n name: 'platform-test-basic',\n description: 'Basic UI tool for platform testing',\n inputSchema: basicUIToolInputSchema,\n outputSchema: basicUIToolOutputSchema,\n ui: {\n /**\n * Simple template that displays the output.\n * Works with all platforms.\n */\n template: `\n<div class=\"platform-test-basic\">\n <h1>Platform Test - Basic</h1>\n <p>Message: {output.message}</p>\n <p>Timestamp: {output.timestamp}</p>\n</div>\n `.trim(),\n },\n} as const;\n\n// ═══════════════════════════════════════════════════════════════════\n// FULL UI TOOL CONFIG\n// ═══════════════════════════════════════════════════════════════════\n\n/**\n * Input schema for the full UI tool.\n */\nexport const fullUIToolInputSchema = z.object({\n name: z.string().optional().default('World'),\n count: z.number().optional().default(1),\n});\n\n/**\n * Output schema for the full UI tool.\n */\nexport const fullUIToolOutputSchema = z.object({\n message: z.string(),\n count: z.number(),\n items: z.array(z.string()),\n timestamp: z.number(),\n});\n\n/**\n * Full UI tool configuration with all UI options.\n * Use this for testing comprehensive platform-specific meta key behavior.\n */\nexport const FULL_UI_TOOL_CONFIG = {\n name: 'platform-test-full',\n description: 'Full UI tool with all options for comprehensive platform testing',\n inputSchema: fullUIToolInputSchema,\n outputSchema: fullUIToolOutputSchema,\n ui: {\n /**\n * Template with more complex UI elements.\n */\n template: `\n<div class=\"platform-test-full\">\n <h1>Platform Test - Full</h1>\n <div class=\"message-box\">\n <strong>Message:</strong> {output.message}\n </div>\n <div class=\"count-box\">\n <strong>Count:</strong> {output.count}\n </div>\n <div class=\"items-list\">\n <strong>Items:</strong>\n <ul>\n {output.items.map(item => <li key={item}>{item}</li>)}\n </ul>\n </div>\n <footer>\n <small>Generated at: {new Date(output.timestamp).toISOString()}</small>\n </footer>\n</div>\n `.trim(),\n /**\n * Widget is accessible for callback invocations.\n */\n widgetAccessible: true,\n /**\n * Invocation status messages for OpenAI.\n */\n invocationStatus: {\n invoking: 'Processing request...',\n invoked: 'Request completed',\n },\n /**\n * Content Security Policy configuration.\n */\n csp: {\n connectDomains: ['https://api.example.com'],\n resourceDomains: ['https://cdn.example.com'],\n },\n /**\n * Display mode for the widget.\n */\n displayMode: 'inline' as const,\n /**\n * Prefers border around the widget.\n */\n prefersBorder: true,\n /**\n * Custom sandbox domain.\n */\n sandboxDomain: 'sandbox.example.com',\n },\n} as const;\n\n// ═══════════════════════════════════════════════════════════════════\n// TOOL EXECUTION HELPERS\n// ═══════════════════════════════════════════════════════════════════\n\n/**\n * Generate output for the basic UI tool.\n */\nexport function generateBasicUIToolOutput(input: z.infer<typeof basicUIToolInputSchema>) {\n return {\n message: `Hello, ${input.name}!`,\n timestamp: Date.now(),\n };\n}\n\n/**\n * Generate output for the full UI tool.\n */\nexport function generateFullUIToolOutput(input: z.infer<typeof fullUIToolInputSchema>) {\n const items: string[] = [];\n for (let i = 1; i <= input.count; i++) {\n items.push(`Item ${i}`);\n }\n return {\n message: `Hello, ${input.name}! You requested ${input.count} item(s).`,\n count: input.count,\n items,\n timestamp: Date.now(),\n };\n}\n\n// ═══════════════════════════════════════════════════════════════════\n// EXPECTED META KEYS\n// ═══════════════════════════════════════════════════════════════════\n\n/**\n * Expected meta keys for OpenAI platform in tools/list response.\n */\nexport const EXPECTED_OPENAI_TOOLS_LIST_META_KEYS = [\n 'openai/outputTemplate',\n 'openai/resultCanProduceWidget',\n 'openai/widgetAccessible',\n] as const;\n\n/**\n * Expected meta keys for OpenAI platform in tools/call response.\n */\nexport const EXPECTED_OPENAI_TOOL_CALL_META_KEYS = ['openai/html', 'openai/mimeType', 'openai/type'] as const;\n\n/**\n * Expected meta keys for ext-apps platform in tools/list response (SEP-1865).\n */\nexport const EXPECTED_EXTAPPS_TOOLS_LIST_META_KEYS = ['ui/resourceUri', 'ui/mimeType', 'ui/cdn', 'ui/type'] as const;\n\n/**\n * Expected meta keys for ext-apps platform in tools/call response (SEP-1865).\n */\nexport const EXPECTED_EXTAPPS_TOOL_CALL_META_KEYS = ['ui/html', 'ui/mimeType', 'ui/type'] as const;\n\n/**\n * Expected meta keys for FrontMCP platforms in tools/list response (Claude, Cursor, etc.).\n */\nexport const EXPECTED_FRONTMCP_TOOLS_LIST_META_KEYS = [\n 'frontmcp/outputTemplate',\n 'frontmcp/resultCanProduceWidget',\n 'ui/cdn',\n 'ui/type',\n] as const;\n\n/**\n * Expected meta keys for FrontMCP platforms in tools/call response (Claude, Cursor, etc.).\n */\nexport const EXPECTED_FRONTMCP_TOOL_CALL_META_KEYS = [\n 'frontmcp/html',\n 'frontmcp/mimeType',\n 'ui/html',\n 'ui/mimeType',\n] as const;\n"]}
|