Skip to main content
Glama

MCP-APIKit

by scarqin
mcpServer.ts7.63 kB
/** * MCP Server implementation for API Kit * * This file creates and configures the MCP server for Eolink OpenAPI integration */ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { z } from "zod"; import eolinkService from './eolinkService.js'; import { Api, Project } from '../models/api.js'; class Server { private server: McpServer; private projects: Project[] = []; private apis: Record<string, Api[]> = {}; constructor() { // Initialize the MCP server this.server = new McpServer({ name: 'API Kit', version: '1.0.0', description: 'MCP server for Eolink OpenAPI integration', capabilities: { // Define server capabilities here api_testing: true, api_documentation: true } }); // Register handlers for MCP methods this.registerHandlers(); // Load initial data this.loadProjects(); } /** * Get the MCP server instance */ getServer(): McpServer { return this.server; } /** * Register handlers for MCP methods */ private registerHandlers(): void { // Register tool handlers using the new SDK pattern this.server.tool( "list_projects", {}, // No parameters async () => { const projects = await this.getProjects(); return { content: [{ type: "text", text: JSON.stringify({ projects }, null, 2) }] }; } ); this.server.tool( "get_project", { projectId: z.string().describe("Project ID") }, async ({ projectId }) => { const project = await eolinkService.getProject(projectId); return { content: [{ type: "text", text: JSON.stringify({ project }, null, 2) }] }; } ); this.server.tool( "list_apis", { projectId: z.string().optional().describe("Project ID") , spaceId: z.string().optional().describe("Space ID") }, async ({ projectId, spaceId }) => { const apis = await this.getApis(projectId, spaceId ); return { content: [{ type: "text", text: JSON.stringify({ apis }, null, 2) }] }; } ); this.server.tool( "get_api", { projectId: z.string().describe("Project ID"), apiId: z.string().describe("API ID") }, async ({ projectId, apiId }) => { const api = await eolinkService.getApi(projectId, apiId); return { content: [{ type: "text", text: JSON.stringify({ api }, null, 2) }] }; } ); this.server.tool( "search_apis", { query: z.string().describe("Search query") }, async ({ query }) => { const apis = await eolinkService.searchApis(query); return { content: [{ type: "text", text: JSON.stringify({ apis }, null, 2) }] }; } ); this.server.tool( "test_api", { projectId: z.string().describe("Project ID"), apiId: z.string().describe("API ID"), headers: z.record(z.string()).optional().describe("Request headers"), queryParams: z.record(z.string()).optional().describe("Query parameters"), pathParams: z.record(z.string()).optional().describe("Path parameters"), body: z.any().optional().describe("Request body") }, async (params) => { const response = await eolinkService.testApi(params); return { content: [{ type: "text", text: JSON.stringify({ response }, null, 2) }] }; } ); // Add a resource example for API documentation this.server.resource( "api-docs", "api-docs://{projectId}/{apiId}", async (uri) => { // Extract parameters from the URI const uriParts = uri.pathname.split('/'); const projectId = uriParts[1] || ''; const apiId = uriParts[2] || ''; const api = await eolinkService.getApi(projectId, apiId); if (!api) { return { contents: [] }; } // Format API documentation const documentation = this.formatApiDocumentation(api); return { contents: [{ uri: uri.href, text: documentation }] }; } ); } /** * Format API documentation as markdown */ private formatApiDocumentation(api: Api): string { let doc = `# ${api.name}\n\n`; doc += `**Path:** ${api.path}\n`; doc += `**Method:** ${api.method}\n`; if (api.description) { doc += `\n## Description\n${api.description}\n`; } if (api.requestHeaders && api.requestHeaders.length > 0) { doc += `\n## Request Headers\n`; api.requestHeaders.forEach(header => { doc += `- **${header.name}** ${header.required ? '(Required)' : '(Optional)'}: ${header.description || ''}\n`; }); } if (api.requestParams && api.requestParams.length > 0) { doc += `\n## Parameters\n`; api.requestParams.forEach(param => { doc += `- **${param.name}** (${param.in}) ${param.required ? '(Required)' : '(Optional)'}: ${param.description || ''}\n`; }); } if (api.requestBody) { doc += `\n## Request Body\n`; doc += `Content Type: ${api.requestBody.contentType}\n`; if (api.requestBody.schema) { doc += `Schema: ${JSON.stringify(api.requestBody.schema, null, 2)}\n`; } if (api.requestBody.example) { doc += `Example: ${JSON.stringify(api.requestBody.example, null, 2)}\n`; } } if (api.responses && api.responses.length > 0) { doc += `\n## Responses\n`; api.responses.forEach(response => { doc += `### Status Code: ${response.statusCode}\n`; if (response.description) { doc += `${response.description}\n`; } if (response.contentType) { doc += `Content Type: ${response.contentType}\n`; } if (response.schema) { doc += `Schema: ${JSON.stringify(response.schema, null, 2)}\n`; } if (response.example) { doc += `Example: ${JSON.stringify(response.example, null, 2)}\n`; } }); } return doc; } /** * Load all projects from Eolink */ private async loadProjects(): Promise<void> { try { this.projects = await eolinkService.getProjects(); console.log(`Loaded ${this.projects.length} projects from Eolink`); } catch (error) { console.error('Error loading projects:', error); } } /** * Get all projects (with caching) */ private async getProjects(): Promise<Project[]> { // Refresh projects if needed if (this.projects.length === 0) { await this.loadProjects(); } return this.projects; } /** * Get all APIs for a project (with caching) */ private async getApis(projectId: string='FuP13lBce885f9b8437ad8346d3b8576eaf134272a61f7d', spaceId?: string): Promise<Api[]> { // Check cache first if (!this.apis[projectId]) { try { this.apis[projectId] = await eolinkService.getApis(projectId, spaceId); console.log(`Loaded ${this.apis[projectId].length} APIs for project ${projectId}`); } catch (error) { console.error(`Error loading APIs for project ${projectId}:`, error); } } return this.apis[projectId]; } } // Export a singleton instance export default new Server();

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/scarqin/mcp-apikit'

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