Skip to main content
Glama
server.ts4.76 kB
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { CallToolRequestSchema, ListToolsRequestSchema, type Tool, type CallToolResult, type CallToolRequest, ListPromptsRequestSchema, type Prompt, GetPromptRequestSchema, type GetPromptRequest, type GetPromptResult, } from '@modelcontextprotocol/sdk/types.js'; import SwaggerParser from '@apidevtools/swagger-parser'; import { extractToolsFromApi } from './parser/index.js'; import { Config, type SchemaConfig } from './config.js'; import { getSpec } from './utils/get-spec.js'; import type { OpenAPIV3DocumentX } from './types/open-api-document-x.js'; import { executeApiTool, type McpToolDefinition, } from './utils/execute-api-tool.js'; async function mapToolDefinitions(config: SchemaConfig) { const spec = (await getSpec(config.specUrl)) as OpenAPIV3DocumentX; const api = (await SwaggerParser.dereference(spec)) as OpenAPIV3DocumentX; const tools = extractToolsFromApi(api, config.prefix); const blacklist = Array.isArray(api['x-mcp-blacklist']) ? api['x-mcp-blacklist'].map((e) => `${config.prefix}${e.toLowerCase()}`) : []; const toolDefinitionMap: Record<string, McpToolDefinition> = {}; for (const tool of tools) { if (blacklist.includes(tool.name)) continue; toolDefinitionMap[tool.name] = { ...tool, baseUrl: config.baseUrl, }; } return toolDefinitionMap; } export async function serverSetup( config: SchemaConfig | SchemaConfig[] = [ Config.EVM_CONFIG, Config.SOL_CONFIG, ], ) { let configArray = Array.isArray(config) ? config : [config]; if (Config.SERVER_CONFIG) configArray = [Config.SERVER_CONFIG]; /** * MCP Server instance */ const server = new Server( { name: Config.SERVER_NAME, version: Config.SERVER_VERSION }, { capabilities: { tools: {}, prompts: {} } }, ); /** * Map of tool definitions by name */ let toolDefinitionMap: Record<string, McpToolDefinition> = {}; for (const config of configArray) toolDefinitionMap = { ...toolDefinitionMap, ...(await mapToolDefinitions(config)), }; /** * Security schemes from the OpenAPI spec */ const securitySchemes = { ApiKeyAuth: { type: 'apiKey', in: 'header', name: 'X-API-Key', 'x-default': 'test', }, }; server.setRequestHandler(ListToolsRequestSchema, async () => { const toolsForClient: Tool[] = Object.values(toolDefinitionMap).map( (def) => ({ name: def.name, description: def.description, inputSchema: def.inputSchema, }), ); return { tools: toolsForClient }; }); server.setRequestHandler( CallToolRequestSchema, async (request: CallToolRequest, c): Promise<CallToolResult> => { const { name: toolName, arguments: toolArgs } = request.params; const toolDefinition = toolDefinitionMap[toolName]; if (!toolDefinition) { console.error(`Error: Unknown tool requested: ${toolName}`); return { content: [ { type: 'text', text: `Error: Unknown tool requested: ${toolName}`, }, ], }; } return executeApiTool( toolName, toolDefinition, toolArgs ?? {}, securitySchemes, c.authInfo?.token, ); }, ); server.setRequestHandler(ListPromptsRequestSchema, async () => { const promptsForClient: Prompt[] = []; for (const tool of Object.values(toolDefinitionMap)) { if (tool.prompt) { promptsForClient.push({ name: tool.name, description: tool.prompt, arguments: tool.parameters, }); } } return { prompts: promptsForClient }; }); server.setRequestHandler( GetPromptRequestSchema, async (request: GetPromptRequest, c): Promise<GetPromptResult> => { const { name: toolName, arguments: toolArgs } = request.params; const toolDefinition = toolDefinitionMap[toolName]; if (!toolDefinition) { console.error(`Error: Unknown prompt requested: ${toolName}`); return { messages: [ { role: 'user', content: { type: 'text', text: `Error: Unknown prompt requested: ${toolName}`, }, }, ], }; } const toolResult = await executeApiTool( toolName, toolDefinition, toolArgs ?? {}, securitySchemes, c.authInfo?.token, ); return { messages: toolResult.content.map((content) => ({ role: 'user', content, })), }; }, ); return server; }

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/MoralisWeb3/moralis-mcp-server'

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