Initial commit: Complete Hive distributed AI orchestration platform
This comprehensive implementation includes: - FastAPI backend with MCP server integration - React/TypeScript frontend with Vite - PostgreSQL database with Redis caching - Grafana/Prometheus monitoring stack - Docker Compose orchestration - Full MCP protocol support for Claude Code integration Features: - Agent discovery and management across network - Visual workflow editor and execution engine - Real-time task coordination and monitoring - Multi-model support with specialized agents - Distributed development task allocation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
		
							
								
								
									
										2
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/multipleClientsParallel.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/multipleClientsParallel.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| export {}; | ||||
| //# sourceMappingURL=multipleClientsParallel.d.ts.map | ||||
							
								
								
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/multipleClientsParallel.d.ts.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/multipleClientsParallel.d.ts.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| {"version":3,"file":"multipleClientsParallel.d.ts","sourceRoot":"","sources":["../../../../src/examples/client/multipleClientsParallel.ts"],"names":[],"mappings":""} | ||||
							
								
								
									
										132
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/multipleClientsParallel.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/multipleClientsParallel.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,132 @@ | ||||
| import { Client } from '../../client/index.js'; | ||||
| import { StreamableHTTPClientTransport } from '../../client/streamableHttp.js'; | ||||
| import { CallToolResultSchema, LoggingMessageNotificationSchema, } from '../../types.js'; | ||||
| /** | ||||
|  * Multiple Clients MCP Example | ||||
|  * | ||||
|  * This client demonstrates how to: | ||||
|  * 1. Create multiple MCP clients in parallel | ||||
|  * 2. Each client calls a single tool | ||||
|  * 3. Track notifications from each client independently | ||||
|  */ | ||||
| // Command line args processing | ||||
| const args = process.argv.slice(2); | ||||
| const serverUrl = args[0] || 'http://localhost:3000/mcp'; | ||||
| async function createAndRunClient(config) { | ||||
|     console.log(`[${config.id}] Creating client: ${config.name}`); | ||||
|     const client = new Client({ | ||||
|         name: config.name, | ||||
|         version: '1.0.0' | ||||
|     }); | ||||
|     const transport = new StreamableHTTPClientTransport(new URL(serverUrl)); | ||||
|     // Set up client-specific error handler | ||||
|     client.onerror = (error) => { | ||||
|         console.error(`[${config.id}] Client error:`, error); | ||||
|     }; | ||||
|     // Set up client-specific notification handler | ||||
|     client.setNotificationHandler(LoggingMessageNotificationSchema, (notification) => { | ||||
|         console.log(`[${config.id}] Notification: ${notification.params.data}`); | ||||
|     }); | ||||
|     try { | ||||
|         // Connect to the server | ||||
|         await client.connect(transport); | ||||
|         console.log(`[${config.id}] Connected to MCP server`); | ||||
|         // Call the specified tool | ||||
|         console.log(`[${config.id}] Calling tool: ${config.toolName}`); | ||||
|         const toolRequest = { | ||||
|             method: 'tools/call', | ||||
|             params: { | ||||
|                 name: config.toolName, | ||||
|                 arguments: { | ||||
|                     ...config.toolArguments, | ||||
|                     // Add client ID to arguments for identification in notifications | ||||
|                     caller: config.id | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|         const result = await client.request(toolRequest, CallToolResultSchema); | ||||
|         console.log(`[${config.id}] Tool call completed`); | ||||
|         // Keep the connection open for a bit to receive notifications | ||||
|         await new Promise(resolve => setTimeout(resolve, 5000)); | ||||
|         // Disconnect | ||||
|         await transport.close(); | ||||
|         console.log(`[${config.id}] Disconnected from MCP server`); | ||||
|         return { id: config.id, result }; | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.error(`[${config.id}] Error:`, error); | ||||
|         throw error; | ||||
|     } | ||||
| } | ||||
| async function main() { | ||||
|     console.log('MCP Multiple Clients Example'); | ||||
|     console.log('============================'); | ||||
|     console.log(`Server URL: ${serverUrl}`); | ||||
|     console.log(''); | ||||
|     try { | ||||
|         // Define client configurations | ||||
|         const clientConfigs = [ | ||||
|             { | ||||
|                 id: 'client1', | ||||
|                 name: 'basic-client-1', | ||||
|                 toolName: 'start-notification-stream', | ||||
|                 toolArguments: { | ||||
|                     interval: 3, // 1 second between notifications | ||||
|                     count: 5 // Send 5 notifications | ||||
|                 } | ||||
|             }, | ||||
|             { | ||||
|                 id: 'client2', | ||||
|                 name: 'basic-client-2', | ||||
|                 toolName: 'start-notification-stream', | ||||
|                 toolArguments: { | ||||
|                     interval: 2, // 2 seconds between notifications | ||||
|                     count: 3 // Send 3 notifications | ||||
|                 } | ||||
|             }, | ||||
|             { | ||||
|                 id: 'client3', | ||||
|                 name: 'basic-client-3', | ||||
|                 toolName: 'start-notification-stream', | ||||
|                 toolArguments: { | ||||
|                     interval: 1, // 0.5 second between notifications | ||||
|                     count: 8 // Send 8 notifications | ||||
|                 } | ||||
|             } | ||||
|         ]; | ||||
|         // Start all clients in parallel | ||||
|         console.log(`Starting ${clientConfigs.length} clients in parallel...`); | ||||
|         console.log(''); | ||||
|         const clientPromises = clientConfigs.map(config => createAndRunClient(config)); | ||||
|         const results = await Promise.all(clientPromises); | ||||
|         // Display results from all clients | ||||
|         console.log('\n=== Final Results ==='); | ||||
|         results.forEach(({ id, result }) => { | ||||
|             console.log(`\n[${id}] Tool result:`); | ||||
|             if (Array.isArray(result.content)) { | ||||
|                 result.content.forEach((item) => { | ||||
|                     if (item.type === 'text' && item.text) { | ||||
|                         console.log(`  ${item.text}`); | ||||
|                     } | ||||
|                     else { | ||||
|                         console.log(`  ${item.type} content:`, item); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|             else { | ||||
|                 console.log(`  Unexpected result format:`, result); | ||||
|             } | ||||
|         }); | ||||
|         console.log('\n=== All clients completed successfully ==='); | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.error('Error running multiple clients:', error); | ||||
|         process.exit(1); | ||||
|     } | ||||
| } | ||||
| // Start the example | ||||
| main().catch((error) => { | ||||
|     console.error('Error running MCP multiple clients example:', error); | ||||
|     process.exit(1); | ||||
| }); | ||||
| //# sourceMappingURL=multipleClientsParallel.js.map | ||||
							
								
								
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/multipleClientsParallel.js.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/multipleClientsParallel.js.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| {"version":3,"file":"multipleClientsParallel.js","sourceRoot":"","sources":["../../../../src/examples/client/multipleClientsParallel.ts"],"names":[],"mappings":"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"} | ||||
							
								
								
									
										2
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/parallelToolCallsClient.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/parallelToolCallsClient.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| export {}; | ||||
| //# sourceMappingURL=parallelToolCallsClient.d.ts.map | ||||
							
								
								
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/parallelToolCallsClient.d.ts.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/parallelToolCallsClient.d.ts.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| {"version":3,"file":"parallelToolCallsClient.d.ts","sourceRoot":"","sources":["../../../../src/examples/client/parallelToolCallsClient.ts"],"names":[],"mappings":""} | ||||
							
								
								
									
										173
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/parallelToolCallsClient.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/parallelToolCallsClient.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| import { Client } from '../../client/index.js'; | ||||
| import { StreamableHTTPClientTransport } from '../../client/streamableHttp.js'; | ||||
| import { ListToolsResultSchema, CallToolResultSchema, LoggingMessageNotificationSchema, } from '../../types.js'; | ||||
| /** | ||||
|  * Parallel Tool Calls MCP Client | ||||
|  * | ||||
|  * This client demonstrates how to: | ||||
|  * 1. Start multiple tool calls in parallel | ||||
|  * 2. Track notifications from each tool call using a caller parameter | ||||
|  */ | ||||
| // Command line args processing | ||||
| const args = process.argv.slice(2); | ||||
| const serverUrl = args[0] || 'http://localhost:3000/mcp'; | ||||
| async function main() { | ||||
|     console.log('MCP Parallel Tool Calls Client'); | ||||
|     console.log('=============================='); | ||||
|     console.log(`Connecting to server at: ${serverUrl}`); | ||||
|     let client; | ||||
|     let transport; | ||||
|     try { | ||||
|         // Create client with streamable HTTP transport | ||||
|         client = new Client({ | ||||
|             name: 'parallel-tool-calls-client', | ||||
|             version: '1.0.0' | ||||
|         }); | ||||
|         client.onerror = (error) => { | ||||
|             console.error('Client error:', error); | ||||
|         }; | ||||
|         // Connect to the server | ||||
|         transport = new StreamableHTTPClientTransport(new URL(serverUrl)); | ||||
|         await client.connect(transport); | ||||
|         console.log('Successfully connected to MCP server'); | ||||
|         // Set up notification handler with caller identification | ||||
|         client.setNotificationHandler(LoggingMessageNotificationSchema, (notification) => { | ||||
|             console.log(`Notification: ${notification.params.data}`); | ||||
|         }); | ||||
|         console.log("List tools"); | ||||
|         const toolsRequest = await listTools(client); | ||||
|         console.log("Tools: ", toolsRequest); | ||||
|         // 2. Start multiple notification tools in parallel | ||||
|         console.log('\n=== Starting Multiple Notification Streams in Parallel ==='); | ||||
|         const toolResults = await startParallelNotificationTools(client); | ||||
|         // Log the results from each tool call | ||||
|         for (const [caller, result] of Object.entries(toolResults)) { | ||||
|             console.log(`\n=== Tool result for ${caller} ===`); | ||||
|             result.content.forEach((item) => { | ||||
|                 if (item.type === 'text') { | ||||
|                     console.log(`  ${item.text}`); | ||||
|                 } | ||||
|                 else { | ||||
|                     console.log(`  ${item.type} content:`, item); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|         // 3. Wait for all notifications (10 seconds) | ||||
|         console.log('\n=== Waiting for all notifications ==='); | ||||
|         await new Promise(resolve => setTimeout(resolve, 10000)); | ||||
|         // 4. Disconnect | ||||
|         console.log('\n=== Disconnecting ==='); | ||||
|         await transport.close(); | ||||
|         console.log('Disconnected from MCP server'); | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.error('Error running client:', error); | ||||
|         process.exit(1); | ||||
|     } | ||||
| } | ||||
| /** | ||||
|  * List available tools on the server | ||||
|  */ | ||||
| async function listTools(client) { | ||||
|     try { | ||||
|         const toolsRequest = { | ||||
|             method: 'tools/list', | ||||
|             params: {} | ||||
|         }; | ||||
|         const toolsResult = await client.request(toolsRequest, ListToolsResultSchema); | ||||
|         console.log('Available tools:'); | ||||
|         if (toolsResult.tools.length === 0) { | ||||
|             console.log('  No tools available'); | ||||
|         } | ||||
|         else { | ||||
|             for (const tool of toolsResult.tools) { | ||||
|                 console.log(`  - ${tool.name}: ${tool.description}`); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.log(`Tools not supported by this server: ${error}`); | ||||
|     } | ||||
| } | ||||
| /** | ||||
|  * Start multiple notification tools in parallel with different configurations | ||||
|  * Each tool call includes a caller parameter to identify its notifications | ||||
|  */ | ||||
| async function startParallelNotificationTools(client) { | ||||
|     try { | ||||
|         // Define multiple tool calls with different configurations | ||||
|         const toolCalls = [ | ||||
|             { | ||||
|                 caller: 'fast-notifier', | ||||
|                 request: { | ||||
|                     method: 'tools/call', | ||||
|                     params: { | ||||
|                         name: 'start-notification-stream', | ||||
|                         arguments: { | ||||
|                             interval: 2, // 0.5 second between notifications | ||||
|                             count: 10, // Send 10 notifications | ||||
|                             caller: 'fast-notifier' // Identify this tool call | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             { | ||||
|                 caller: 'slow-notifier', | ||||
|                 request: { | ||||
|                     method: 'tools/call', | ||||
|                     params: { | ||||
|                         name: 'start-notification-stream', | ||||
|                         arguments: { | ||||
|                             interval: 5, // 2 seconds between notifications | ||||
|                             count: 5, // Send 5 notifications | ||||
|                             caller: 'slow-notifier' // Identify this tool call | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             { | ||||
|                 caller: 'burst-notifier', | ||||
|                 request: { | ||||
|                     method: 'tools/call', | ||||
|                     params: { | ||||
|                         name: 'start-notification-stream', | ||||
|                         arguments: { | ||||
|                             interval: 1, // 0.1 second between notifications | ||||
|                             count: 3, // Send just 3 notifications | ||||
|                             caller: 'burst-notifier' // Identify this tool call | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         ]; | ||||
|         console.log(`Starting ${toolCalls.length} notification tools in parallel...`); | ||||
|         // Start all tool calls in parallel | ||||
|         const toolPromises = toolCalls.map(({ caller, request }) => { | ||||
|             console.log(`Starting tool call for ${caller}...`); | ||||
|             return client.request(request, CallToolResultSchema) | ||||
|                 .then(result => ({ caller, result })) | ||||
|                 .catch(error => { | ||||
|                 console.error(`Error in tool call for ${caller}:`, error); | ||||
|                 throw error; | ||||
|             }); | ||||
|         }); | ||||
|         // Wait for all tool calls to complete | ||||
|         const results = await Promise.all(toolPromises); | ||||
|         // Organize results by caller | ||||
|         const resultsByTool = {}; | ||||
|         results.forEach(({ caller, result }) => { | ||||
|             resultsByTool[caller] = result; | ||||
|         }); | ||||
|         return resultsByTool; | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.error(`Error starting parallel notification tools:`, error); | ||||
|         throw error; | ||||
|     } | ||||
| } | ||||
| // Start the client | ||||
| main().catch((error) => { | ||||
|     console.error('Error running MCP client:', error); | ||||
|     process.exit(1); | ||||
| }); | ||||
| //# sourceMappingURL=parallelToolCallsClient.js.map | ||||
							
								
								
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/parallelToolCallsClient.js.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/parallelToolCallsClient.js.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| {"version":3,"file":"parallelToolCallsClient.js","sourceRoot":"","sources":["../../../../src/examples/client/parallelToolCallsClient.ts"],"names":[],"mappings":"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"} | ||||
							
								
								
									
										3
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleOAuthClient.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleOAuthClient.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| #!/usr/bin/env node | ||||
| export {}; | ||||
| //# sourceMappingURL=simpleOAuthClient.d.ts.map | ||||
							
								
								
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleOAuthClient.d.ts.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleOAuthClient.d.ts.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| {"version":3,"file":"simpleOAuthClient.d.ts","sourceRoot":"","sources":["../../../../src/examples/client/simpleOAuthClient.ts"],"names":[],"mappings":""} | ||||
							
								
								
									
										370
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleOAuthClient.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										370
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleOAuthClient.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,370 @@ | ||||
| #!/usr/bin/env node | ||||
| import { createServer } from 'node:http'; | ||||
| import { createInterface } from 'node:readline'; | ||||
| import { URL } from 'node:url'; | ||||
| import { exec } from 'node:child_process'; | ||||
| import { Client } from '../../client/index.js'; | ||||
| import { StreamableHTTPClientTransport } from '../../client/streamableHttp.js'; | ||||
| import { CallToolResultSchema, ListToolsResultSchema } from '../../types.js'; | ||||
| import { UnauthorizedError } from '../../client/auth.js'; | ||||
| // Configuration | ||||
| const DEFAULT_SERVER_URL = 'http://localhost:3000/mcp'; | ||||
| const CALLBACK_PORT = 8090; // Use different port than auth server (3001) | ||||
| const CALLBACK_URL = `http://localhost:${CALLBACK_PORT}/callback`; | ||||
| /** | ||||
|  * In-memory OAuth client provider for demonstration purposes | ||||
|  * In production, you should persist tokens securely | ||||
|  */ | ||||
| class InMemoryOAuthClientProvider { | ||||
|     constructor(_redirectUrl, _clientMetadata, onRedirect) { | ||||
|         this._redirectUrl = _redirectUrl; | ||||
|         this._clientMetadata = _clientMetadata; | ||||
|         this._onRedirect = onRedirect || ((url) => { | ||||
|             console.log(`Redirect to: ${url.toString()}`); | ||||
|         }); | ||||
|     } | ||||
|     get redirectUrl() { | ||||
|         return this._redirectUrl; | ||||
|     } | ||||
|     get clientMetadata() { | ||||
|         return this._clientMetadata; | ||||
|     } | ||||
|     clientInformation() { | ||||
|         return this._clientInformation; | ||||
|     } | ||||
|     saveClientInformation(clientInformation) { | ||||
|         this._clientInformation = clientInformation; | ||||
|     } | ||||
|     tokens() { | ||||
|         return this._tokens; | ||||
|     } | ||||
|     saveTokens(tokens) { | ||||
|         this._tokens = tokens; | ||||
|     } | ||||
|     redirectToAuthorization(authorizationUrl) { | ||||
|         this._onRedirect(authorizationUrl); | ||||
|     } | ||||
|     saveCodeVerifier(codeVerifier) { | ||||
|         this._codeVerifier = codeVerifier; | ||||
|     } | ||||
|     codeVerifier() { | ||||
|         if (!this._codeVerifier) { | ||||
|             throw new Error('No code verifier saved'); | ||||
|         } | ||||
|         return this._codeVerifier; | ||||
|     } | ||||
| } | ||||
| /** | ||||
|  * Interactive MCP client with OAuth authentication | ||||
|  * Demonstrates the complete OAuth flow with browser-based authorization | ||||
|  */ | ||||
| class InteractiveOAuthClient { | ||||
|     constructor(serverUrl) { | ||||
|         this.serverUrl = serverUrl; | ||||
|         this.client = null; | ||||
|         this.rl = createInterface({ | ||||
|             input: process.stdin, | ||||
|             output: process.stdout, | ||||
|         }); | ||||
|     } | ||||
|     /** | ||||
|      * Prompts user for input via readline | ||||
|      */ | ||||
|     async question(query) { | ||||
|         return new Promise((resolve) => { | ||||
|             this.rl.question(query, resolve); | ||||
|         }); | ||||
|     } | ||||
|     /** | ||||
|      * Opens the authorization URL in the user's default browser | ||||
|      */ | ||||
|     async openBrowser(url) { | ||||
|         console.log(`🌐 Opening browser for authorization: ${url}`); | ||||
|         const command = `open "${url}"`; | ||||
|         exec(command, (error) => { | ||||
|             if (error) { | ||||
|                 console.error(`Failed to open browser: ${error.message}`); | ||||
|                 console.log(`Please manually open: ${url}`); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|     /** | ||||
|      * Example OAuth callback handler - in production, use a more robust approach | ||||
|      * for handling callbacks and storing tokens | ||||
|      */ | ||||
|     /** | ||||
|      * Starts a temporary HTTP server to receive the OAuth callback | ||||
|      */ | ||||
|     async waitForOAuthCallback() { | ||||
|         return new Promise((resolve, reject) => { | ||||
|             const server = createServer((req, res) => { | ||||
|                 // Ignore favicon requests | ||||
|                 if (req.url === '/favicon.ico') { | ||||
|                     res.writeHead(404); | ||||
|                     res.end(); | ||||
|                     return; | ||||
|                 } | ||||
|                 console.log(`📥 Received callback: ${req.url}`); | ||||
|                 const parsedUrl = new URL(req.url || '', 'http://localhost'); | ||||
|                 const code = parsedUrl.searchParams.get('code'); | ||||
|                 const error = parsedUrl.searchParams.get('error'); | ||||
|                 if (code) { | ||||
|                     console.log(`✅ Authorization code received: ${code === null || code === void 0 ? void 0 : code.substring(0, 10)}...`); | ||||
|                     res.writeHead(200, { 'Content-Type': 'text/html' }); | ||||
|                     res.end(` | ||||
|             <html> | ||||
|               <body> | ||||
|                 <h1>Authorization Successful!</h1> | ||||
|                 <p>You can close this window and return to the terminal.</p> | ||||
|                 <script>setTimeout(() => window.close(), 2000);</script> | ||||
|               </body> | ||||
|             </html> | ||||
|           `); | ||||
|                     resolve(code); | ||||
|                     setTimeout(() => server.close(), 3000); | ||||
|                 } | ||||
|                 else if (error) { | ||||
|                     console.log(`❌ Authorization error: ${error}`); | ||||
|                     res.writeHead(400, { 'Content-Type': 'text/html' }); | ||||
|                     res.end(` | ||||
|             <html> | ||||
|               <body> | ||||
|                 <h1>Authorization Failed</h1> | ||||
|                 <p>Error: ${error}</p> | ||||
|               </body> | ||||
|             </html> | ||||
|           `); | ||||
|                     reject(new Error(`OAuth authorization failed: ${error}`)); | ||||
|                 } | ||||
|                 else { | ||||
|                     console.log(`❌ No authorization code or error in callback`); | ||||
|                     res.writeHead(400); | ||||
|                     res.end('Bad request'); | ||||
|                     reject(new Error('No authorization code provided')); | ||||
|                 } | ||||
|             }); | ||||
|             server.listen(CALLBACK_PORT, () => { | ||||
|                 console.log(`OAuth callback server started on http://localhost:${CALLBACK_PORT}`); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
|     async attemptConnection(oauthProvider) { | ||||
|         console.log('🚢 Creating transport with OAuth provider...'); | ||||
|         const baseUrl = new URL(this.serverUrl); | ||||
|         const transport = new StreamableHTTPClientTransport(baseUrl, { | ||||
|             authProvider: oauthProvider | ||||
|         }); | ||||
|         console.log('🚢 Transport created'); | ||||
|         try { | ||||
|             console.log('🔌 Attempting connection (this will trigger OAuth redirect)...'); | ||||
|             await this.client.connect(transport); | ||||
|             console.log('✅ Connected successfully'); | ||||
|         } | ||||
|         catch (error) { | ||||
|             if (error instanceof UnauthorizedError) { | ||||
|                 console.log('🔐 OAuth required - waiting for authorization...'); | ||||
|                 const callbackPromise = this.waitForOAuthCallback(); | ||||
|                 const authCode = await callbackPromise; | ||||
|                 await transport.finishAuth(authCode); | ||||
|                 console.log('🔐 Authorization code received:', authCode); | ||||
|                 console.log('🔌 Reconnecting with authenticated transport...'); | ||||
|                 await this.attemptConnection(oauthProvider); | ||||
|             } | ||||
|             else { | ||||
|                 console.error('❌ Connection failed with non-auth error:', error); | ||||
|                 throw error; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
|      * Establishes connection to the MCP server with OAuth authentication | ||||
|      */ | ||||
|     async connect() { | ||||
|         console.log(`🔗 Attempting to connect to ${this.serverUrl}...`); | ||||
|         const clientMetadata = { | ||||
|             client_name: 'Simple OAuth MCP Client', | ||||
|             redirect_uris: [CALLBACK_URL], | ||||
|             grant_types: ['authorization_code', 'refresh_token'], | ||||
|             response_types: ['code'], | ||||
|             token_endpoint_auth_method: 'client_secret_post', | ||||
|             scope: 'mcp:tools' | ||||
|         }; | ||||
|         console.log('🔐 Creating OAuth provider...'); | ||||
|         const oauthProvider = new InMemoryOAuthClientProvider(CALLBACK_URL, clientMetadata, (redirectUrl) => { | ||||
|             console.log(`📌 OAuth redirect handler called - opening browser`); | ||||
|             console.log(`Opening browser to: ${redirectUrl.toString()}`); | ||||
|             this.openBrowser(redirectUrl.toString()); | ||||
|         }); | ||||
|         console.log('🔐 OAuth provider created'); | ||||
|         console.log('👤 Creating MCP client...'); | ||||
|         this.client = new Client({ | ||||
|             name: 'simple-oauth-client', | ||||
|             version: '1.0.0', | ||||
|         }, { capabilities: {} }); | ||||
|         console.log('👤 Client created'); | ||||
|         console.log('🔐 Starting OAuth flow...'); | ||||
|         await this.attemptConnection(oauthProvider); | ||||
|         // Start interactive loop | ||||
|         await this.interactiveLoop(); | ||||
|     } | ||||
|     /** | ||||
|      * Main interactive loop for user commands | ||||
|      */ | ||||
|     async interactiveLoop() { | ||||
|         console.log('\n🎯 Interactive MCP Client with OAuth'); | ||||
|         console.log('Commands:'); | ||||
|         console.log('  list - List available tools'); | ||||
|         console.log('  call <tool_name> [args] - Call a tool'); | ||||
|         console.log('  quit - Exit the client'); | ||||
|         console.log(); | ||||
|         while (true) { | ||||
|             try { | ||||
|                 const command = await this.question('mcp> '); | ||||
|                 if (!command.trim()) { | ||||
|                     continue; | ||||
|                 } | ||||
|                 if (command === 'quit') { | ||||
|                     break; | ||||
|                 } | ||||
|                 else if (command === 'list') { | ||||
|                     await this.listTools(); | ||||
|                 } | ||||
|                 else if (command.startsWith('call ')) { | ||||
|                     await this.handleCallTool(command); | ||||
|                 } | ||||
|                 else { | ||||
|                     console.log('❌ Unknown command. Try \'list\', \'call <tool_name>\', or \'quit\''); | ||||
|                 } | ||||
|             } | ||||
|             catch (error) { | ||||
|                 if (error instanceof Error && error.message === 'SIGINT') { | ||||
|                     console.log('\n\n👋 Goodbye!'); | ||||
|                     break; | ||||
|                 } | ||||
|                 console.error('❌ Error:', error); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     async listTools() { | ||||
|         if (!this.client) { | ||||
|             console.log('❌ Not connected to server'); | ||||
|             return; | ||||
|         } | ||||
|         try { | ||||
|             const request = { | ||||
|                 method: 'tools/list', | ||||
|                 params: {}, | ||||
|             }; | ||||
|             const result = await this.client.request(request, ListToolsResultSchema); | ||||
|             if (result.tools && result.tools.length > 0) { | ||||
|                 console.log('\n📋 Available tools:'); | ||||
|                 result.tools.forEach((tool, index) => { | ||||
|                     console.log(`${index + 1}. ${tool.name}`); | ||||
|                     if (tool.description) { | ||||
|                         console.log(`   Description: ${tool.description}`); | ||||
|                     } | ||||
|                     console.log(); | ||||
|                 }); | ||||
|             } | ||||
|             else { | ||||
|                 console.log('No tools available'); | ||||
|             } | ||||
|         } | ||||
|         catch (error) { | ||||
|             console.error('❌ Failed to list tools:', error); | ||||
|         } | ||||
|     } | ||||
|     async handleCallTool(command) { | ||||
|         const parts = command.split(/\s+/); | ||||
|         const toolName = parts[1]; | ||||
|         if (!toolName) { | ||||
|             console.log('❌ Please specify a tool name'); | ||||
|             return; | ||||
|         } | ||||
|         // Parse arguments (simple JSON-like format) | ||||
|         let toolArgs = {}; | ||||
|         if (parts.length > 2) { | ||||
|             const argsString = parts.slice(2).join(' '); | ||||
|             try { | ||||
|                 toolArgs = JSON.parse(argsString); | ||||
|             } | ||||
|             catch (_a) { | ||||
|                 console.log('❌ Invalid arguments format (expected JSON)'); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         await this.callTool(toolName, toolArgs); | ||||
|     } | ||||
|     async callTool(toolName, toolArgs) { | ||||
|         if (!this.client) { | ||||
|             console.log('❌ Not connected to server'); | ||||
|             return; | ||||
|         } | ||||
|         try { | ||||
|             const request = { | ||||
|                 method: 'tools/call', | ||||
|                 params: { | ||||
|                     name: toolName, | ||||
|                     arguments: toolArgs, | ||||
|                 }, | ||||
|             }; | ||||
|             const result = await this.client.request(request, CallToolResultSchema); | ||||
|             console.log(`\n🔧 Tool '${toolName}' result:`); | ||||
|             if (result.content) { | ||||
|                 result.content.forEach((content) => { | ||||
|                     if (content.type === 'text') { | ||||
|                         console.log(content.text); | ||||
|                     } | ||||
|                     else { | ||||
|                         console.log(content); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|             else { | ||||
|                 console.log(result); | ||||
|             } | ||||
|         } | ||||
|         catch (error) { | ||||
|             console.error(`❌ Failed to call tool '${toolName}':`, error); | ||||
|         } | ||||
|     } | ||||
|     close() { | ||||
|         this.rl.close(); | ||||
|         if (this.client) { | ||||
|             // Note: Client doesn't have a close method in the current implementation | ||||
|             // This would typically close the transport connection | ||||
|         } | ||||
|     } | ||||
| } | ||||
| /** | ||||
|  * Main entry point | ||||
|  */ | ||||
| async function main() { | ||||
|     const serverUrl = process.env.MCP_SERVER_URL || DEFAULT_SERVER_URL; | ||||
|     console.log('🚀 Simple MCP OAuth Client'); | ||||
|     console.log(`Connecting to: ${serverUrl}`); | ||||
|     console.log(); | ||||
|     const client = new InteractiveOAuthClient(serverUrl); | ||||
|     // Handle graceful shutdown | ||||
|     process.on('SIGINT', () => { | ||||
|         console.log('\n\n👋 Goodbye!'); | ||||
|         client.close(); | ||||
|         process.exit(0); | ||||
|     }); | ||||
|     try { | ||||
|         await client.connect(); | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.error('Failed to start client:', error); | ||||
|         process.exit(1); | ||||
|     } | ||||
|     finally { | ||||
|         client.close(); | ||||
|     } | ||||
| } | ||||
| // Run if this file is executed directly | ||||
| main().catch((error) => { | ||||
|     console.error('Unhandled error:', error); | ||||
|     process.exit(1); | ||||
| }); | ||||
| //# sourceMappingURL=simpleOAuthClient.js.map | ||||
							
								
								
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleOAuthClient.js.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleOAuthClient.js.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleStreamableHttp.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleStreamableHttp.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| export {}; | ||||
| //# sourceMappingURL=simpleStreamableHttp.d.ts.map | ||||
							
								
								
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleStreamableHttp.d.ts.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleStreamableHttp.d.ts.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| {"version":3,"file":"simpleStreamableHttp.d.ts","sourceRoot":"","sources":["../../../../src/examples/client/simpleStreamableHttp.ts"],"names":[],"mappings":""} | ||||
							
								
								
									
										738
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleStreamableHttp.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										738
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleStreamableHttp.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,738 @@ | ||||
| import { Client } from '../../client/index.js'; | ||||
| import { StreamableHTTPClientTransport } from '../../client/streamableHttp.js'; | ||||
| import { createInterface } from 'node:readline'; | ||||
| import { ListToolsResultSchema, CallToolResultSchema, ListPromptsResultSchema, GetPromptResultSchema, ListResourcesResultSchema, LoggingMessageNotificationSchema, ResourceListChangedNotificationSchema, ElicitRequestSchema, ReadResourceResultSchema, } from '../../types.js'; | ||||
| import { getDisplayName } from '../../shared/metadataUtils.js'; | ||||
| import Ajv from "ajv"; | ||||
| // Create readline interface for user input | ||||
| const readline = createInterface({ | ||||
|     input: process.stdin, | ||||
|     output: process.stdout | ||||
| }); | ||||
| // Track received notifications for debugging resumability | ||||
| let notificationCount = 0; | ||||
| // Global client and transport for interactive commands | ||||
| let client = null; | ||||
| let transport = null; | ||||
| let serverUrl = 'http://localhost:3000/mcp'; | ||||
| let notificationsToolLastEventId = undefined; | ||||
| let sessionId = undefined; | ||||
| async function main() { | ||||
|     console.log('MCP Interactive Client'); | ||||
|     console.log('====================='); | ||||
|     // Connect to server immediately with default settings | ||||
|     await connect(); | ||||
|     // Print help and start the command loop | ||||
|     printHelp(); | ||||
|     commandLoop(); | ||||
| } | ||||
| function printHelp() { | ||||
|     console.log('\nAvailable commands:'); | ||||
|     console.log('  connect [url]              - Connect to MCP server (default: http://localhost:3000/mcp)'); | ||||
|     console.log('  disconnect                 - Disconnect from server'); | ||||
|     console.log('  terminate-session          - Terminate the current session'); | ||||
|     console.log('  reconnect                  - Reconnect to the server'); | ||||
|     console.log('  list-tools                 - List available tools'); | ||||
|     console.log('  call-tool <name> [args]    - Call a tool with optional JSON arguments'); | ||||
|     console.log('  greet [name]               - Call the greet tool'); | ||||
|     console.log('  multi-greet [name]         - Call the multi-greet tool with notifications'); | ||||
|     console.log('  collect-info [type]        - Test elicitation with collect-user-info tool (contact/preferences/feedback)'); | ||||
|     console.log('  start-notifications [interval] [count] - Start periodic notifications'); | ||||
|     console.log('  run-notifications-tool-with-resumability [interval] [count] - Run notification tool with resumability'); | ||||
|     console.log('  list-prompts               - List available prompts'); | ||||
|     console.log('  get-prompt [name] [args]   - Get a prompt with optional JSON arguments'); | ||||
|     console.log('  list-resources             - List available resources'); | ||||
|     console.log('  read-resource <uri>        - Read a specific resource by URI'); | ||||
|     console.log('  help                       - Show this help'); | ||||
|     console.log('  quit                       - Exit the program'); | ||||
| } | ||||
| function commandLoop() { | ||||
|     readline.question('\n> ', async (input) => { | ||||
|         var _a; | ||||
|         const args = input.trim().split(/\s+/); | ||||
|         const command = (_a = args[0]) === null || _a === void 0 ? void 0 : _a.toLowerCase(); | ||||
|         try { | ||||
|             switch (command) { | ||||
|                 case 'connect': | ||||
|                     await connect(args[1]); | ||||
|                     break; | ||||
|                 case 'disconnect': | ||||
|                     await disconnect(); | ||||
|                     break; | ||||
|                 case 'terminate-session': | ||||
|                     await terminateSession(); | ||||
|                     break; | ||||
|                 case 'reconnect': | ||||
|                     await reconnect(); | ||||
|                     break; | ||||
|                 case 'list-tools': | ||||
|                     await listTools(); | ||||
|                     break; | ||||
|                 case 'call-tool': | ||||
|                     if (args.length < 2) { | ||||
|                         console.log('Usage: call-tool <name> [args]'); | ||||
|                     } | ||||
|                     else { | ||||
|                         const toolName = args[1]; | ||||
|                         let toolArgs = {}; | ||||
|                         if (args.length > 2) { | ||||
|                             try { | ||||
|                                 toolArgs = JSON.parse(args.slice(2).join(' ')); | ||||
|                             } | ||||
|                             catch (_b) { | ||||
|                                 console.log('Invalid JSON arguments. Using empty args.'); | ||||
|                             } | ||||
|                         } | ||||
|                         await callTool(toolName, toolArgs); | ||||
|                     } | ||||
|                     break; | ||||
|                 case 'greet': | ||||
|                     await callGreetTool(args[1] || 'MCP User'); | ||||
|                     break; | ||||
|                 case 'multi-greet': | ||||
|                     await callMultiGreetTool(args[1] || 'MCP User'); | ||||
|                     break; | ||||
|                 case 'collect-info': | ||||
|                     await callCollectInfoTool(args[1] || 'contact'); | ||||
|                     break; | ||||
|                 case 'start-notifications': { | ||||
|                     const interval = args[1] ? parseInt(args[1], 10) : 2000; | ||||
|                     const count = args[2] ? parseInt(args[2], 10) : 10; | ||||
|                     await startNotifications(interval, count); | ||||
|                     break; | ||||
|                 } | ||||
|                 case 'run-notifications-tool-with-resumability': { | ||||
|                     const interval = args[1] ? parseInt(args[1], 10) : 2000; | ||||
|                     const count = args[2] ? parseInt(args[2], 10) : 10; | ||||
|                     await runNotificationsToolWithResumability(interval, count); | ||||
|                     break; | ||||
|                 } | ||||
|                 case 'list-prompts': | ||||
|                     await listPrompts(); | ||||
|                     break; | ||||
|                 case 'get-prompt': | ||||
|                     if (args.length < 2) { | ||||
|                         console.log('Usage: get-prompt <name> [args]'); | ||||
|                     } | ||||
|                     else { | ||||
|                         const promptName = args[1]; | ||||
|                         let promptArgs = {}; | ||||
|                         if (args.length > 2) { | ||||
|                             try { | ||||
|                                 promptArgs = JSON.parse(args.slice(2).join(' ')); | ||||
|                             } | ||||
|                             catch (_c) { | ||||
|                                 console.log('Invalid JSON arguments. Using empty args.'); | ||||
|                             } | ||||
|                         } | ||||
|                         await getPrompt(promptName, promptArgs); | ||||
|                     } | ||||
|                     break; | ||||
|                 case 'list-resources': | ||||
|                     await listResources(); | ||||
|                     break; | ||||
|                 case 'read-resource': | ||||
|                     if (args.length < 2) { | ||||
|                         console.log('Usage: read-resource <uri>'); | ||||
|                     } | ||||
|                     else { | ||||
|                         await readResource(args[1]); | ||||
|                     } | ||||
|                     break; | ||||
|                 case 'help': | ||||
|                     printHelp(); | ||||
|                     break; | ||||
|                 case 'quit': | ||||
|                 case 'exit': | ||||
|                     await cleanup(); | ||||
|                     return; | ||||
|                 default: | ||||
|                     if (command) { | ||||
|                         console.log(`Unknown command: ${command}`); | ||||
|                     } | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|         catch (error) { | ||||
|             console.error(`Error executing command: ${error}`); | ||||
|         } | ||||
|         // Continue the command loop | ||||
|         commandLoop(); | ||||
|     }); | ||||
| } | ||||
| async function connect(url) { | ||||
|     if (client) { | ||||
|         console.log('Already connected. Disconnect first.'); | ||||
|         return; | ||||
|     } | ||||
|     if (url) { | ||||
|         serverUrl = url; | ||||
|     } | ||||
|     console.log(`Connecting to ${serverUrl}...`); | ||||
|     try { | ||||
|         // Create a new client with elicitation capability | ||||
|         client = new Client({ | ||||
|             name: 'example-client', | ||||
|             version: '1.0.0' | ||||
|         }, { | ||||
|             capabilities: { | ||||
|                 elicitation: {}, | ||||
|             }, | ||||
|         }); | ||||
|         client.onerror = (error) => { | ||||
|             console.error('\x1b[31mClient error:', error, '\x1b[0m'); | ||||
|         }; | ||||
|         // Set up elicitation request handler with proper validation | ||||
|         client.setRequestHandler(ElicitRequestSchema, async (request) => { | ||||
|             var _a; | ||||
|             console.log('\n🔔 Elicitation Request Received:'); | ||||
|             console.log(`Message: ${request.params.message}`); | ||||
|             console.log('Requested Schema:'); | ||||
|             console.log(JSON.stringify(request.params.requestedSchema, null, 2)); | ||||
|             const schema = request.params.requestedSchema; | ||||
|             const properties = schema.properties; | ||||
|             const required = schema.required || []; | ||||
|             // Set up AJV validator for the requested schema | ||||
|             const ajv = new Ajv(); | ||||
|             const validate = ajv.compile(schema); | ||||
|             let attempts = 0; | ||||
|             const maxAttempts = 3; | ||||
|             while (attempts < maxAttempts) { | ||||
|                 attempts++; | ||||
|                 console.log(`\nPlease provide the following information (attempt ${attempts}/${maxAttempts}):`); | ||||
|                 const content = {}; | ||||
|                 let inputCancelled = false; | ||||
|                 // Collect input for each field | ||||
|                 for (const [fieldName, fieldSchema] of Object.entries(properties)) { | ||||
|                     const field = fieldSchema; | ||||
|                     const isRequired = required.includes(fieldName); | ||||
|                     let prompt = `${field.title || fieldName}`; | ||||
|                     // Add helpful information to the prompt | ||||
|                     if (field.description) { | ||||
|                         prompt += ` (${field.description})`; | ||||
|                     } | ||||
|                     if (field.enum) { | ||||
|                         prompt += ` [options: ${field.enum.join(', ')}]`; | ||||
|                     } | ||||
|                     if (field.type === 'number' || field.type === 'integer') { | ||||
|                         if (field.minimum !== undefined && field.maximum !== undefined) { | ||||
|                             prompt += ` [${field.minimum}-${field.maximum}]`; | ||||
|                         } | ||||
|                         else if (field.minimum !== undefined) { | ||||
|                             prompt += ` [min: ${field.minimum}]`; | ||||
|                         } | ||||
|                         else if (field.maximum !== undefined) { | ||||
|                             prompt += ` [max: ${field.maximum}]`; | ||||
|                         } | ||||
|                     } | ||||
|                     if (field.type === 'string' && field.format) { | ||||
|                         prompt += ` [format: ${field.format}]`; | ||||
|                     } | ||||
|                     if (isRequired) { | ||||
|                         prompt += ' *required*'; | ||||
|                     } | ||||
|                     if (field.default !== undefined) { | ||||
|                         prompt += ` [default: ${field.default}]`; | ||||
|                     } | ||||
|                     prompt += ': '; | ||||
|                     const answer = await new Promise((resolve) => { | ||||
|                         readline.question(prompt, (input) => { | ||||
|                             resolve(input.trim()); | ||||
|                         }); | ||||
|                     }); | ||||
|                     // Check for cancellation | ||||
|                     if (answer.toLowerCase() === 'cancel' || answer.toLowerCase() === 'c') { | ||||
|                         inputCancelled = true; | ||||
|                         break; | ||||
|                     } | ||||
|                     // Parse and validate the input | ||||
|                     try { | ||||
|                         if (answer === '' && field.default !== undefined) { | ||||
|                             content[fieldName] = field.default; | ||||
|                         } | ||||
|                         else if (answer === '' && !isRequired) { | ||||
|                             // Skip optional empty fields | ||||
|                             continue; | ||||
|                         } | ||||
|                         else if (answer === '') { | ||||
|                             throw new Error(`${fieldName} is required`); | ||||
|                         } | ||||
|                         else { | ||||
|                             // Parse the value based on type | ||||
|                             let parsedValue; | ||||
|                             if (field.type === 'boolean') { | ||||
|                                 parsedValue = answer.toLowerCase() === 'true' || answer.toLowerCase() === 'yes' || answer === '1'; | ||||
|                             } | ||||
|                             else if (field.type === 'number') { | ||||
|                                 parsedValue = parseFloat(answer); | ||||
|                                 if (isNaN(parsedValue)) { | ||||
|                                     throw new Error(`${fieldName} must be a valid number`); | ||||
|                                 } | ||||
|                             } | ||||
|                             else if (field.type === 'integer') { | ||||
|                                 parsedValue = parseInt(answer, 10); | ||||
|                                 if (isNaN(parsedValue)) { | ||||
|                                     throw new Error(`${fieldName} must be a valid integer`); | ||||
|                                 } | ||||
|                             } | ||||
|                             else if (field.enum) { | ||||
|                                 if (!field.enum.includes(answer)) { | ||||
|                                     throw new Error(`${fieldName} must be one of: ${field.enum.join(', ')}`); | ||||
|                                 } | ||||
|                                 parsedValue = answer; | ||||
|                             } | ||||
|                             else { | ||||
|                                 parsedValue = answer; | ||||
|                             } | ||||
|                             content[fieldName] = parsedValue; | ||||
|                         } | ||||
|                     } | ||||
|                     catch (error) { | ||||
|                         console.log(`❌ Error: ${error}`); | ||||
|                         // Continue to next attempt | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|                 if (inputCancelled) { | ||||
|                     return { action: 'cancel' }; | ||||
|                 } | ||||
|                 // If we didn't complete all fields due to an error, try again | ||||
|                 if (Object.keys(content).length !== Object.keys(properties).filter(name => required.includes(name) || content[name] !== undefined).length) { | ||||
|                     if (attempts < maxAttempts) { | ||||
|                         console.log('Please try again...'); | ||||
|                         continue; | ||||
|                     } | ||||
|                     else { | ||||
|                         console.log('Maximum attempts reached. Declining request.'); | ||||
|                         return { action: 'decline' }; | ||||
|                     } | ||||
|                 } | ||||
|                 // Validate the complete object against the schema | ||||
|                 const isValid = validate(content); | ||||
|                 if (!isValid) { | ||||
|                     console.log('❌ Validation errors:'); | ||||
|                     (_a = validate.errors) === null || _a === void 0 ? void 0 : _a.forEach(error => { | ||||
|                         console.log(`  - ${error.dataPath || 'root'}: ${error.message}`); | ||||
|                     }); | ||||
|                     if (attempts < maxAttempts) { | ||||
|                         console.log('Please correct the errors and try again...'); | ||||
|                         continue; | ||||
|                     } | ||||
|                     else { | ||||
|                         console.log('Maximum attempts reached. Declining request.'); | ||||
|                         return { action: 'decline' }; | ||||
|                     } | ||||
|                 } | ||||
|                 // Show the collected data and ask for confirmation | ||||
|                 console.log('\n✅ Collected data:'); | ||||
|                 console.log(JSON.stringify(content, null, 2)); | ||||
|                 const confirmAnswer = await new Promise((resolve) => { | ||||
|                     readline.question('\nSubmit this information? (yes/no/cancel): ', (input) => { | ||||
|                         resolve(input.trim().toLowerCase()); | ||||
|                     }); | ||||
|                 }); | ||||
|                 if (confirmAnswer === 'yes' || confirmAnswer === 'y') { | ||||
|                     return { | ||||
|                         action: 'accept', | ||||
|                         content, | ||||
|                     }; | ||||
|                 } | ||||
|                 else if (confirmAnswer === 'cancel' || confirmAnswer === 'c') { | ||||
|                     return { action: 'cancel' }; | ||||
|                 } | ||||
|                 else if (confirmAnswer === 'no' || confirmAnswer === 'n') { | ||||
|                     if (attempts < maxAttempts) { | ||||
|                         console.log('Please re-enter the information...'); | ||||
|                         continue; | ||||
|                     } | ||||
|                     else { | ||||
|                         return { action: 'decline' }; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             console.log('Maximum attempts reached. Declining request.'); | ||||
|             return { action: 'decline' }; | ||||
|         }); | ||||
|         transport = new StreamableHTTPClientTransport(new URL(serverUrl), { | ||||
|             sessionId: sessionId | ||||
|         }); | ||||
|         // Set up notification handlers | ||||
|         client.setNotificationHandler(LoggingMessageNotificationSchema, (notification) => { | ||||
|             notificationCount++; | ||||
|             console.log(`\nNotification #${notificationCount}: ${notification.params.level} - ${notification.params.data}`); | ||||
|             // Re-display the prompt | ||||
|             process.stdout.write('> '); | ||||
|         }); | ||||
|         client.setNotificationHandler(ResourceListChangedNotificationSchema, async (_) => { | ||||
|             console.log(`\nResource list changed notification received!`); | ||||
|             try { | ||||
|                 if (!client) { | ||||
|                     console.log('Client disconnected, cannot fetch resources'); | ||||
|                     return; | ||||
|                 } | ||||
|                 const resourcesResult = await client.request({ | ||||
|                     method: 'resources/list', | ||||
|                     params: {} | ||||
|                 }, ListResourcesResultSchema); | ||||
|                 console.log('Available resources count:', resourcesResult.resources.length); | ||||
|             } | ||||
|             catch (_a) { | ||||
|                 console.log('Failed to list resources after change notification'); | ||||
|             } | ||||
|             // Re-display the prompt | ||||
|             process.stdout.write('> '); | ||||
|         }); | ||||
|         // Connect the client | ||||
|         await client.connect(transport); | ||||
|         sessionId = transport.sessionId; | ||||
|         console.log('Transport created with session ID:', sessionId); | ||||
|         console.log('Connected to MCP server'); | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.error('Failed to connect:', error); | ||||
|         client = null; | ||||
|         transport = null; | ||||
|     } | ||||
| } | ||||
| async function disconnect() { | ||||
|     if (!client || !transport) { | ||||
|         console.log('Not connected.'); | ||||
|         return; | ||||
|     } | ||||
|     try { | ||||
|         await transport.close(); | ||||
|         console.log('Disconnected from MCP server'); | ||||
|         client = null; | ||||
|         transport = null; | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.error('Error disconnecting:', error); | ||||
|     } | ||||
| } | ||||
| async function terminateSession() { | ||||
|     if (!client || !transport) { | ||||
|         console.log('Not connected.'); | ||||
|         return; | ||||
|     } | ||||
|     try { | ||||
|         console.log('Terminating session with ID:', transport.sessionId); | ||||
|         await transport.terminateSession(); | ||||
|         console.log('Session terminated successfully'); | ||||
|         // Check if sessionId was cleared after termination | ||||
|         if (!transport.sessionId) { | ||||
|             console.log('Session ID has been cleared'); | ||||
|             sessionId = undefined; | ||||
|             // Also close the transport and clear client objects | ||||
|             await transport.close(); | ||||
|             console.log('Transport closed after session termination'); | ||||
|             client = null; | ||||
|             transport = null; | ||||
|         } | ||||
|         else { | ||||
|             console.log('Server responded with 405 Method Not Allowed (session termination not supported)'); | ||||
|             console.log('Session ID is still active:', transport.sessionId); | ||||
|         } | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.error('Error terminating session:', error); | ||||
|     } | ||||
| } | ||||
| async function reconnect() { | ||||
|     if (client) { | ||||
|         await disconnect(); | ||||
|     } | ||||
|     await connect(); | ||||
| } | ||||
| async function listTools() { | ||||
|     if (!client) { | ||||
|         console.log('Not connected to server.'); | ||||
|         return; | ||||
|     } | ||||
|     try { | ||||
|         const toolsRequest = { | ||||
|             method: 'tools/list', | ||||
|             params: {} | ||||
|         }; | ||||
|         const toolsResult = await client.request(toolsRequest, ListToolsResultSchema); | ||||
|         console.log('Available tools:'); | ||||
|         if (toolsResult.tools.length === 0) { | ||||
|             console.log('  No tools available'); | ||||
|         } | ||||
|         else { | ||||
|             for (const tool of toolsResult.tools) { | ||||
|                 console.log(`  - id: ${tool.name}, name: ${getDisplayName(tool)}, description: ${tool.description}`); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.log(`Tools not supported by this server (${error})`); | ||||
|     } | ||||
| } | ||||
| async function callTool(name, args) { | ||||
|     if (!client) { | ||||
|         console.log('Not connected to server.'); | ||||
|         return; | ||||
|     } | ||||
|     try { | ||||
|         const request = { | ||||
|             method: 'tools/call', | ||||
|             params: { | ||||
|                 name, | ||||
|                 arguments: args | ||||
|             } | ||||
|         }; | ||||
|         console.log(`Calling tool '${name}' with args:`, args); | ||||
|         const result = await client.request(request, CallToolResultSchema); | ||||
|         console.log('Tool result:'); | ||||
|         const resourceLinks = []; | ||||
|         result.content.forEach(item => { | ||||
|             if (item.type === 'text') { | ||||
|                 console.log(`  ${item.text}`); | ||||
|             } | ||||
|             else if (item.type === 'resource_link') { | ||||
|                 const resourceLink = item; | ||||
|                 resourceLinks.push(resourceLink); | ||||
|                 console.log(`  📁 Resource Link: ${resourceLink.name}`); | ||||
|                 console.log(`     URI: ${resourceLink.uri}`); | ||||
|                 if (resourceLink.mimeType) { | ||||
|                     console.log(`     Type: ${resourceLink.mimeType}`); | ||||
|                 } | ||||
|                 if (resourceLink.description) { | ||||
|                     console.log(`     Description: ${resourceLink.description}`); | ||||
|                 } | ||||
|             } | ||||
|             else if (item.type === 'resource') { | ||||
|                 console.log(`  [Embedded Resource: ${item.resource.uri}]`); | ||||
|             } | ||||
|             else if (item.type === 'image') { | ||||
|                 console.log(`  [Image: ${item.mimeType}]`); | ||||
|             } | ||||
|             else if (item.type === 'audio') { | ||||
|                 console.log(`  [Audio: ${item.mimeType}]`); | ||||
|             } | ||||
|             else { | ||||
|                 console.log(`  [Unknown content type]:`, item); | ||||
|             } | ||||
|         }); | ||||
|         // Offer to read resource links | ||||
|         if (resourceLinks.length > 0) { | ||||
|             console.log(`\nFound ${resourceLinks.length} resource link(s). Use 'read-resource <uri>' to read their content.`); | ||||
|         } | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.log(`Error calling tool ${name}: ${error}`); | ||||
|     } | ||||
| } | ||||
| async function callGreetTool(name) { | ||||
|     await callTool('greet', { name }); | ||||
| } | ||||
| async function callMultiGreetTool(name) { | ||||
|     console.log('Calling multi-greet tool with notifications...'); | ||||
|     await callTool('multi-greet', { name }); | ||||
| } | ||||
| async function callCollectInfoTool(infoType) { | ||||
|     console.log(`Testing elicitation with collect-user-info tool (${infoType})...`); | ||||
|     await callTool('collect-user-info', { infoType }); | ||||
| } | ||||
| async function startNotifications(interval, count) { | ||||
|     console.log(`Starting notification stream: interval=${interval}ms, count=${count || 'unlimited'}`); | ||||
|     await callTool('start-notification-stream', { interval, count }); | ||||
| } | ||||
| async function runNotificationsToolWithResumability(interval, count) { | ||||
|     if (!client) { | ||||
|         console.log('Not connected to server.'); | ||||
|         return; | ||||
|     } | ||||
|     try { | ||||
|         console.log(`Starting notification stream with resumability: interval=${interval}ms, count=${count || 'unlimited'}`); | ||||
|         console.log(`Using resumption token: ${notificationsToolLastEventId || 'none'}`); | ||||
|         const request = { | ||||
|             method: 'tools/call', | ||||
|             params: { | ||||
|                 name: 'start-notification-stream', | ||||
|                 arguments: { interval, count } | ||||
|             } | ||||
|         }; | ||||
|         const onLastEventIdUpdate = (event) => { | ||||
|             notificationsToolLastEventId = event; | ||||
|             console.log(`Updated resumption token: ${event}`); | ||||
|         }; | ||||
|         const result = await client.request(request, CallToolResultSchema, { | ||||
|             resumptionToken: notificationsToolLastEventId, | ||||
|             onresumptiontoken: onLastEventIdUpdate | ||||
|         }); | ||||
|         console.log('Tool result:'); | ||||
|         result.content.forEach(item => { | ||||
|             if (item.type === 'text') { | ||||
|                 console.log(`  ${item.text}`); | ||||
|             } | ||||
|             else { | ||||
|                 console.log(`  ${item.type} content:`, item); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.log(`Error starting notification stream: ${error}`); | ||||
|     } | ||||
| } | ||||
| async function listPrompts() { | ||||
|     if (!client) { | ||||
|         console.log('Not connected to server.'); | ||||
|         return; | ||||
|     } | ||||
|     try { | ||||
|         const promptsRequest = { | ||||
|             method: 'prompts/list', | ||||
|             params: {} | ||||
|         }; | ||||
|         const promptsResult = await client.request(promptsRequest, ListPromptsResultSchema); | ||||
|         console.log('Available prompts:'); | ||||
|         if (promptsResult.prompts.length === 0) { | ||||
|             console.log('  No prompts available'); | ||||
|         } | ||||
|         else { | ||||
|             for (const prompt of promptsResult.prompts) { | ||||
|                 console.log(`  - id: ${prompt.name}, name: ${getDisplayName(prompt)}, description: ${prompt.description}`); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.log(`Prompts not supported by this server (${error})`); | ||||
|     } | ||||
| } | ||||
| async function getPrompt(name, args) { | ||||
|     if (!client) { | ||||
|         console.log('Not connected to server.'); | ||||
|         return; | ||||
|     } | ||||
|     try { | ||||
|         const promptRequest = { | ||||
|             method: 'prompts/get', | ||||
|             params: { | ||||
|                 name, | ||||
|                 arguments: args | ||||
|             } | ||||
|         }; | ||||
|         const promptResult = await client.request(promptRequest, GetPromptResultSchema); | ||||
|         console.log('Prompt template:'); | ||||
|         promptResult.messages.forEach((msg, index) => { | ||||
|             console.log(`  [${index + 1}] ${msg.role}: ${msg.content.text}`); | ||||
|         }); | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.log(`Error getting prompt ${name}: ${error}`); | ||||
|     } | ||||
| } | ||||
| async function listResources() { | ||||
|     if (!client) { | ||||
|         console.log('Not connected to server.'); | ||||
|         return; | ||||
|     } | ||||
|     try { | ||||
|         const resourcesRequest = { | ||||
|             method: 'resources/list', | ||||
|             params: {} | ||||
|         }; | ||||
|         const resourcesResult = await client.request(resourcesRequest, ListResourcesResultSchema); | ||||
|         console.log('Available resources:'); | ||||
|         if (resourcesResult.resources.length === 0) { | ||||
|             console.log('  No resources available'); | ||||
|         } | ||||
|         else { | ||||
|             for (const resource of resourcesResult.resources) { | ||||
|                 console.log(`  - id: ${resource.name}, name: ${getDisplayName(resource)}, description: ${resource.uri}`); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.log(`Resources not supported by this server (${error})`); | ||||
|     } | ||||
| } | ||||
| async function readResource(uri) { | ||||
|     if (!client) { | ||||
|         console.log('Not connected to server.'); | ||||
|         return; | ||||
|     } | ||||
|     try { | ||||
|         const request = { | ||||
|             method: 'resources/read', | ||||
|             params: { uri } | ||||
|         }; | ||||
|         console.log(`Reading resource: ${uri}`); | ||||
|         const result = await client.request(request, ReadResourceResultSchema); | ||||
|         console.log('Resource contents:'); | ||||
|         for (const content of result.contents) { | ||||
|             console.log(`  URI: ${content.uri}`); | ||||
|             if (content.mimeType) { | ||||
|                 console.log(`  Type: ${content.mimeType}`); | ||||
|             } | ||||
|             if ('text' in content && typeof content.text === 'string') { | ||||
|                 console.log('  Content:'); | ||||
|                 console.log('  ---'); | ||||
|                 console.log(content.text.split('\n').map((line) => '  ' + line).join('\n')); | ||||
|                 console.log('  ---'); | ||||
|             } | ||||
|             else if ('blob' in content && typeof content.blob === 'string') { | ||||
|                 console.log(`  [Binary data: ${content.blob.length} bytes]`); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.log(`Error reading resource ${uri}: ${error}`); | ||||
|     } | ||||
| } | ||||
| async function cleanup() { | ||||
|     if (client && transport) { | ||||
|         try { | ||||
|             // First try to terminate the session gracefully | ||||
|             if (transport.sessionId) { | ||||
|                 try { | ||||
|                     console.log('Terminating session before exit...'); | ||||
|                     await transport.terminateSession(); | ||||
|                     console.log('Session terminated successfully'); | ||||
|                 } | ||||
|                 catch (error) { | ||||
|                     console.error('Error terminating session:', error); | ||||
|                 } | ||||
|             } | ||||
|             // Then close the transport | ||||
|             await transport.close(); | ||||
|         } | ||||
|         catch (error) { | ||||
|             console.error('Error closing transport:', error); | ||||
|         } | ||||
|     } | ||||
|     process.stdin.setRawMode(false); | ||||
|     readline.close(); | ||||
|     console.log('\nGoodbye!'); | ||||
|     process.exit(0); | ||||
| } | ||||
| // Set up raw mode for keyboard input to capture Escape key | ||||
| process.stdin.setRawMode(true); | ||||
| process.stdin.on('data', async (data) => { | ||||
|     // Check for Escape key (27) | ||||
|     if (data.length === 1 && data[0] === 27) { | ||||
|         console.log('\nESC key pressed. Disconnecting from server...'); | ||||
|         // Abort current operation and disconnect from server | ||||
|         if (client && transport) { | ||||
|             await disconnect(); | ||||
|             console.log('Disconnected. Press Enter to continue.'); | ||||
|         } | ||||
|         else { | ||||
|             console.log('Not connected to server.'); | ||||
|         } | ||||
|         // Re-display the prompt | ||||
|         process.stdout.write('> '); | ||||
|     } | ||||
| }); | ||||
| // Handle Ctrl+C | ||||
| process.on('SIGINT', async () => { | ||||
|     console.log('\nReceived SIGINT. Cleaning up...'); | ||||
|     await cleanup(); | ||||
| }); | ||||
| // Start the interactive client | ||||
| main().catch((error) => { | ||||
|     console.error('Error running MCP client:', error); | ||||
|     process.exit(1); | ||||
| }); | ||||
| //# sourceMappingURL=simpleStreamableHttp.js.map | ||||
							
								
								
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleStreamableHttp.js.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleStreamableHttp.js.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/streamableHttpWithSseFallbackClient.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/streamableHttpWithSseFallbackClient.d.ts
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| export {}; | ||||
| //# sourceMappingURL=streamableHttpWithSseFallbackClient.d.ts.map | ||||
							
								
								
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/streamableHttpWithSseFallbackClient.d.ts.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/streamableHttpWithSseFallbackClient.d.ts.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| {"version":3,"file":"streamableHttpWithSseFallbackClient.d.ts","sourceRoot":"","sources":["../../../../src/examples/client/streamableHttpWithSseFallbackClient.ts"],"names":[],"mappings":""} | ||||
							
								
								
									
										166
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/streamableHttpWithSseFallbackClient.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/streamableHttpWithSseFallbackClient.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,166 @@ | ||||
| import { Client } from '../../client/index.js'; | ||||
| import { StreamableHTTPClientTransport } from '../../client/streamableHttp.js'; | ||||
| import { SSEClientTransport } from '../../client/sse.js'; | ||||
| import { ListToolsResultSchema, CallToolResultSchema, LoggingMessageNotificationSchema, } from '../../types.js'; | ||||
| /** | ||||
|  * Simplified Backwards Compatible MCP Client | ||||
|  * | ||||
|  * This client demonstrates backward compatibility with both: | ||||
|  * 1. Modern servers using Streamable HTTP transport (protocol version 2025-03-26) | ||||
|  * 2. Older servers using HTTP+SSE transport (protocol version 2024-11-05) | ||||
|  * | ||||
|  * Following the MCP specification for backwards compatibility: | ||||
|  * - Attempts to POST an initialize request to the server URL first (modern transport) | ||||
|  * - If that fails with 4xx status, falls back to GET request for SSE stream (older transport) | ||||
|  */ | ||||
| // Command line args processing | ||||
| const args = process.argv.slice(2); | ||||
| const serverUrl = args[0] || 'http://localhost:3000/mcp'; | ||||
| async function main() { | ||||
|     console.log('MCP Backwards Compatible Client'); | ||||
|     console.log('==============================='); | ||||
|     console.log(`Connecting to server at: ${serverUrl}`); | ||||
|     let client; | ||||
|     let transport; | ||||
|     try { | ||||
|         // Try connecting with automatic transport detection | ||||
|         const connection = await connectWithBackwardsCompatibility(serverUrl); | ||||
|         client = connection.client; | ||||
|         transport = connection.transport; | ||||
|         // Set up notification handler | ||||
|         client.setNotificationHandler(LoggingMessageNotificationSchema, (notification) => { | ||||
|             console.log(`Notification: ${notification.params.level} - ${notification.params.data}`); | ||||
|         }); | ||||
|         // DEMO WORKFLOW: | ||||
|         // 1. List available tools | ||||
|         console.log('\n=== Listing Available Tools ==='); | ||||
|         await listTools(client); | ||||
|         // 2. Call the notification tool | ||||
|         console.log('\n=== Starting Notification Stream ==='); | ||||
|         await startNotificationTool(client); | ||||
|         // 3. Wait for all notifications (5 seconds) | ||||
|         console.log('\n=== Waiting for all notifications ==='); | ||||
|         await new Promise(resolve => setTimeout(resolve, 5000)); | ||||
|         // 4. Disconnect | ||||
|         console.log('\n=== Disconnecting ==='); | ||||
|         await transport.close(); | ||||
|         console.log('Disconnected from MCP server'); | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.error('Error running client:', error); | ||||
|         process.exit(1); | ||||
|     } | ||||
| } | ||||
| /** | ||||
|  * Connect to an MCP server with backwards compatibility | ||||
|  * Following the spec for client backward compatibility | ||||
|  */ | ||||
| async function connectWithBackwardsCompatibility(url) { | ||||
|     console.log('1. Trying Streamable HTTP transport first...'); | ||||
|     // Step 1: Try Streamable HTTP transport first | ||||
|     const client = new Client({ | ||||
|         name: 'backwards-compatible-client', | ||||
|         version: '1.0.0' | ||||
|     }); | ||||
|     client.onerror = (error) => { | ||||
|         console.error('Client error:', error); | ||||
|     }; | ||||
|     const baseUrl = new URL(url); | ||||
|     try { | ||||
|         // Create modern transport | ||||
|         const streamableTransport = new StreamableHTTPClientTransport(baseUrl); | ||||
|         await client.connect(streamableTransport); | ||||
|         console.log('Successfully connected using modern Streamable HTTP transport.'); | ||||
|         return { | ||||
|             client, | ||||
|             transport: streamableTransport, | ||||
|             transportType: 'streamable-http' | ||||
|         }; | ||||
|     } | ||||
|     catch (error) { | ||||
|         // Step 2: If transport fails, try the older SSE transport | ||||
|         console.log(`StreamableHttp transport connection failed: ${error}`); | ||||
|         console.log('2. Falling back to deprecated HTTP+SSE transport...'); | ||||
|         try { | ||||
|             // Create SSE transport pointing to /sse endpoint | ||||
|             const sseTransport = new SSEClientTransport(baseUrl); | ||||
|             const sseClient = new Client({ | ||||
|                 name: 'backwards-compatible-client', | ||||
|                 version: '1.0.0' | ||||
|             }); | ||||
|             await sseClient.connect(sseTransport); | ||||
|             console.log('Successfully connected using deprecated HTTP+SSE transport.'); | ||||
|             return { | ||||
|                 client: sseClient, | ||||
|                 transport: sseTransport, | ||||
|                 transportType: 'sse' | ||||
|             }; | ||||
|         } | ||||
|         catch (sseError) { | ||||
|             console.error(`Failed to connect with either transport method:\n1. Streamable HTTP error: ${error}\n2. SSE error: ${sseError}`); | ||||
|             throw new Error('Could not connect to server with any available transport'); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| /** | ||||
|  * List available tools on the server | ||||
|  */ | ||||
| async function listTools(client) { | ||||
|     try { | ||||
|         const toolsRequest = { | ||||
|             method: 'tools/list', | ||||
|             params: {} | ||||
|         }; | ||||
|         const toolsResult = await client.request(toolsRequest, ListToolsResultSchema); | ||||
|         console.log('Available tools:'); | ||||
|         if (toolsResult.tools.length === 0) { | ||||
|             console.log('  No tools available'); | ||||
|         } | ||||
|         else { | ||||
|             for (const tool of toolsResult.tools) { | ||||
|                 console.log(`  - ${tool.name}: ${tool.description}`); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.log(`Tools not supported by this server: ${error}`); | ||||
|     } | ||||
| } | ||||
| /** | ||||
|  * Start a notification stream by calling the notification tool | ||||
|  */ | ||||
| async function startNotificationTool(client) { | ||||
|     try { | ||||
|         // Call the notification tool using reasonable defaults | ||||
|         const request = { | ||||
|             method: 'tools/call', | ||||
|             params: { | ||||
|                 name: 'start-notification-stream', | ||||
|                 arguments: { | ||||
|                     interval: 1000, // 1 second between notifications | ||||
|                     count: 5 // Send 5 notifications | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|         console.log('Calling notification tool...'); | ||||
|         const result = await client.request(request, CallToolResultSchema); | ||||
|         console.log('Tool result:'); | ||||
|         result.content.forEach(item => { | ||||
|             if (item.type === 'text') { | ||||
|                 console.log(`  ${item.text}`); | ||||
|             } | ||||
|             else { | ||||
|                 console.log(`  ${item.type} content:`, item); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|     catch (error) { | ||||
|         console.log(`Error calling notification tool: ${error}`); | ||||
|     } | ||||
| } | ||||
| // Start the client | ||||
| main().catch((error) => { | ||||
|     console.error('Error running MCP client:', error); | ||||
|     process.exit(1); | ||||
| }); | ||||
| //# sourceMappingURL=streamableHttpWithSseFallbackClient.js.map | ||||
							
								
								
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/streamableHttpWithSseFallbackClient.js.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								mcp-server/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/streamableHttpWithSseFallbackClient.js.map
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| {"version":3,"file":"streamableHttpWithSseFallbackClient.js","sourceRoot":"","sources":["../../../../src/examples/client/streamableHttpWithSseFallbackClient.ts"],"names":[],"mappings":"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"} | ||||
		Reference in New Issue
	
	Block a user
	 anthonyrawlins
					anthonyrawlins