Skip to main content
Glama

Streamable HTTP Bridge

by masx200
Mulan Permissive Software License, Version 2
2
  • Linux
  • Apple
createMcpServer.ts8.11 kB
import { JSONSchemaToZod } from "@dmitryrechkin/json-schema-to-zod"; import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { GetPromptRequestSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, ReadResourceRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import { getServerCapabilities } from "./getServerCapabilities.js"; import { type McpServerConfig, type ServerInstance } from "./main.js"; import { selectTransport } from "./selectTransport.js"; // 创建MCP服务器实例 export async function createMcpServer( serverName: string, serverConfig: McpServerConfig, ): Promise<ServerInstance> { // 使用selectTransport函数选择合适的transport const transport = selectTransport(serverConfig); if (!transport) { throw new Error( "Failed to create transport, please check the configuration.", ); } console.log("clienttransport", transport); // const client= new McpClient() const client = new Client( { name: `bridge-client-${serverName}`, version: "1.0.0" }, { capabilities: { tools: {}, resources: {}, prompts: {}, }, }, ); //@ts-ignore await client.connect(transport); console.log("client connected", transport); const capabilities = (await getServerCapabilities(client)) ?? {}; console.log(`[${serverName}] capabilities:`, capabilities); const listOutputs = { tools: null as | Awaited<ReturnType<typeof client.listTools>> | undefined | null, prompts: null as | Awaited<ReturnType<typeof client.listPrompts>> | undefined | null, resources: null as | Awaited<ReturnType<typeof client.listResources>> | undefined | null, resourceTemplates: null as | Awaited<ReturnType<typeof client.listResourceTemplates>> | undefined | null, }; // 获取工具列表 try { const tools = await client.listTools(); console.log( `[${serverName}] Registering tools:`, JSON.stringify(tools, null, 4), ); listOutputs.tools = tools; capabilities.tools = { listChanged: true, }; } catch (error) { console.error(`[${serverName}] Error listing tools:`, error); capabilities.tools = undefined; } // 获取提示列表 try { const prompts = await client.listPrompts(); console.log( `[${serverName}] Registering prompts:`, JSON.stringify(prompts, null, 4), ); listOutputs.prompts = prompts; capabilities.prompts = { listChanged: true, }; } catch (error) { console.error(`[${serverName}] Error listing prompts:`, error); capabilities.prompts = undefined; } // 获取资源列表 try { const Resources = await client.listResources(); console.log( `[${serverName}] Registering Resources:`, JSON.stringify(Resources, null, 4), ); listOutputs.resources = Resources; capabilities.resources = { listChanged: true, }; } catch (error) { console.error(`[${serverName}] Error listing Resources:`, error); capabilities.resources = undefined; if (listOutputs.resources || listOutputs.resourceTemplates) { capabilities.resources = {}; } } try { const ResourcesTemplates = await client.listResourceTemplates(); console.log( `[${serverName}] Registering ResourcesTemplates:`, JSON.stringify(ResourcesTemplates, null, 4), ); listOutputs.resourceTemplates = ResourcesTemplates; capabilities.resources = { listChanged: true, }; } catch (error: any) { console.error(`[${serverName}] Error listing ResourcesTemplates:`, error); if ( String(error).includes("McpError: MCP error -32001: Request timed out") ) { throw error; } capabilities.resources = undefined; if (listOutputs.resources || listOutputs.resourceTemplates) { capabilities.resources = {}; } } const server = new McpServer( { name: `bridge-service-${serverName}`, version: "1.0.0", }, { capabilities: Object.assign(capabilities, { tools: { listChanged: true }, }), }, ); // 注册工具 try { if (capabilities.tools && listOutputs.tools) { server.server.registerCapabilities({ tools: { listChanged: true }, }); const tools = listOutputs.tools; await Promise.all( tools.tools.map(async (tool) => { console.log( `[${serverName}] Registering tool: `, JSON.stringify( { name: tool.name, description: tool.description, annotations: tool.annotations, }, null, 4, ), ); //@ts-ignore const inputSchema = JSONSchemaToZod.convert(tool.inputSchema).shape; const outputSchema = tool.outputSchema //@ts-ignore ? JSONSchemaToZod.convert(tool.outputSchema).shape : tool.outputSchema; server.registerTool( tool.name, { description: tool.description, annotations: tool.annotations, ...tool, inputSchema: inputSchema, outputSchema, }, //@ts-ignore async (params: any) => { console.log( `[${serverName}] Calling tool`, JSON.stringify({ name: tool.name, params }, null, 4), ); const result = await client.callTool({ name: tool.name, arguments: params, }); return result; }, ); }), ); } } catch (error) { console.error(`[${serverName}] Error Registering tools:`, error); } // 注册提示 try { if (capabilities.prompts && listOutputs.prompts) { //@ts-ignore server.server.setRequestHandler(ListPromptsRequestSchema, async () => { console.log(`[${serverName}] Listing prompts...`); return listOutputs.prompts; }); server.server.setRequestHandler( GetPromptRequestSchema, async (request) => { console.log( `[${serverName}] Getting prompt...`, JSON.stringify(request.params, null, 4), ); const result = await client.getPrompt(request.params); return result; }, ); } } catch (error) { console.error(`[${serverName}] Error Registering prompts:`, error); } // 注册资源 try { if (capabilities.resources && listOutputs.resources) { server.server.setRequestHandler( ReadResourceRequestSchema, async (request) => { console.log( `[${serverName}] Reading resource...`, JSON.stringify(request.params, null, 4), ); const result = await client.readResource(request.params); return result; }, ); server.server.setRequestHandler( ListResourcesRequestSchema, //@ts-ignore async (request) => { console.log( `[${serverName}] Listing resources...`, JSON.stringify(request.params, null, 4), ); return listOutputs.resources; }, ); server.server.setRequestHandler( ListResourceTemplatesRequestSchema, //@ts-ignore async (request) => { console.log( `[${serverName}] Listing resourceTemplates...`, JSON.stringify(request.params, null, 4), ); return listOutputs.resourceTemplates; }, ); } } catch (error) { console.error(`[${serverName}] Error Registering Resources:`, error); } console.log("getServerCapabilities", client.getServerCapabilities()); return { config: serverConfig, server, client, transport: transport, httpTransports: null as any, }; }

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/masx200/mcp-demo-streamable-http-bridge'

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