Skip to main content
Glama
client-example.ts7.08 kB
#!/usr/bin/env node /** * 客户端示例 - 演示如何连接到兼容服务器 * * 此示例展示了: * 1. 尝试连接 Streamable HTTP (推荐) * 2. 如果失败,降级到传统 SSE * 3. 调用 MCP 工具 */ import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js"; type TransportType = "streamable-http" | "sse"; /** * 向后兼容的连接函数 * 按照 MCP 规范的向后兼容策略 */ async function connectWithBackwardsCompatibility( baseUrl: string ): Promise<{ client: Client; transport: StreamableHTTPClientTransport | SSEClientTransport; transportType: TransportType; }> { console.log("🔄 尝试连接到 MCP 服务器...\n"); // 步骤 1: 优先尝试 Streamable HTTP (现代协议) console.log("1️⃣ 尝试 Streamable HTTP 传输 (协议版本: 2025-03-26)"); const client = new Client({ name: "example-client", version: "1.0.0", }); client.onerror = (error) => { console.error("❌ 客户端错误:", error.message); }; try { const streamableUrl = new URL(baseUrl); streamableUrl.pathname = "/mcp"; console.log(` 连接到: ${streamableUrl.href}`); const streamableTransport = new StreamableHTTPClientTransport(streamableUrl); await client.connect(streamableTransport); console.log("✅ 成功使用 Streamable HTTP 传输连接\n"); return { client, transport: streamableTransport, transportType: "streamable-http", }; } catch (error) { console.log(`⚠️ Streamable HTTP 连接失败: ${error instanceof Error ? error.message : String(error)}\n`); // 步骤 2: 降级到传统 SSE (旧协议) console.log("2️⃣ 降级到传统 SSE 传输 (协议版本: 2024-11-05)"); try { const sseUrl = new URL(baseUrl); sseUrl.pathname = "/sse"; console.log(` 连接到: ${sseUrl.href}`); const sseTransport = new SSEClientTransport(sseUrl); const sseClient = new Client({ name: "example-client", version: "1.0.0", }); await sseClient.connect(sseTransport); console.log("✅ 成功使用传统 SSE 传输连接\n"); return { client: sseClient, transport: sseTransport, transportType: "sse", }; } catch (sseError) { console.error( `\n❌ 两种传输方式都失败:\n` + ` 1. Streamable HTTP: ${error}\n` + ` 2. SSE: ${sseError}` ); throw new Error("无法使用任何可用的传输方式连接到服务器"); } } } /** * 演示如何使用连接的客户端 */ async function demonstrateUsage( client: Client, transportType: TransportType ) { console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); console.log(`📋 使用 ${transportType === "streamable-http" ? "Streamable HTTP" : "传统 SSE"} 传输演示 MCP 功能`); console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"); try { // 1. 列出可用工具 console.log("1️⃣ 获取可用工具列表..."); const toolsResult = await client.listTools(); console.log(`✅ 找到 ${toolsResult.tools.length} 个工具:\n`); toolsResult.tools.forEach((tool, index) => { console.log(` ${index + 1}. ${tool.name}`); console.log(` ${tool.description || "无描述"}`); }); console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"); // 2. 调用示例工具 (使用 investigate_error) console.log("2️⃣ 调用工具示例: investigate_error"); console.log(" 参数:"); console.log(" - filePath: src/main/java/example/Service.java"); console.log(" - lineNumber: 42\n"); try { const result = await client.callTool({ name: "investigate_error", arguments: { filePath: "src/main/java/example/Service.java", lineNumber: 42, branch: "release/1.5" }, }); console.log("✅ 工具调用成功!"); console.log("\n📊 返回结果:"); // Type guard for content array const content = result.content as Array<{ type: string; text?: string }> | undefined; if (content && content.length > 0) { const firstContent = content[0]; if (firstContent.type === "text" && firstContent.text) { try { const parsed = JSON.parse(firstContent.text); console.log(JSON.stringify(parsed, null, 2)); } catch { console.log(firstContent.text); } } } } catch (error) { // 工具调用失败是预期的(因为可能没有实际的 Bitbucket 配置) console.log("⚠️ 工具调用失败(这是预期的,如果没有配置 Bitbucket):"); console.log(` ${error instanceof Error ? error.message : String(error)}`); } console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"); } catch (error) { console.error("❌ 演示过程中出错:", error); } } /** * 主函数 */ async function main() { const serverUrl = process.env.SERVER_URL || "http://localhost:3000"; console.log("╔════════════════════════════════════════════════╗"); console.log("║ MCP 兼容客户端示例 ║"); console.log("╚════════════════════════════════════════════════╝\n"); console.log(`🌐 服务器地址: ${serverUrl}\n`); try { // 连接到服务器(自动向后兼容) const { client, transportType } = await connectWithBackwardsCompatibility(serverUrl); // 演示功能 await demonstrateUsage(client, transportType); // 关闭连接 console.log("👋 关闭连接..."); await client.close(); console.log("✅ 连接已关闭\n"); console.log("╔════════════════════════════════════════════════╗"); console.log("║ 演示完成! ║"); console.log("╚════════════════════════════════════════════════╝"); } catch (error) { console.error("\n❌ 致命错误:", error); process.exit(1); } } // 运行主函数 main().catch((error) => { console.error("未捕获的错误:", error); process.exit(1); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wycCome/mcp-error-tracing'

If you have feedback or need assistance with the MCP directory API, please join our Discord server