Skip to main content
Glama
mcpService.ts5.29 kB
import fetch from "node-fetch"; import dotenv from "dotenv"; dotenv.config(); const GITHUB_MCP_URL = process.env.GITHUB_MCP_URL || ""; const MONGODB_URI = process.env.MONGODB_URI || ''; const DB_NAME = process.env.DB_NAME || ""; const COLLECTION_NAME = process.env.COLLECTION_NAME || ""; export interface Tool { name: string; description: string; category?: string; inputSchema: { type: "object"; properties: Record<string, any>; required?: string[]; }; } class MCPService { private githubSessionId: string | null = null; private currentToken: string | null = null; async initializeGitHubSession(token: string) { try { const response = await fetch(GITHUB_MCP_URL, { method: "POST", headers: { "Authorization": `Bearer ${token}`, "Content-Type": "application/json", }, body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "initialize", params: { protocolVersion: "2025-03-26", capabilities: { tools: { listChanged: true }, }, clientInfo: { name: "MCP Server Proxy", version: "1.0.0", }, }, }), }); const sessionId = response.headers.get('mcp-session-id'); if (sessionId) { this.githubSessionId = sessionId; this.currentToken = token; } const text = await response.text(); if (!response.ok) { throw new Error(`GitHub MCP Initialize Error (${response.status}): ${text}`); } return JSON.parse(text); } catch (error) { throw error; } } async getToolSpecs(): Promise<Tool[]> { try { const { MongoClient } = await import("mongodb"); const client = new MongoClient(MONGODB_URI); await client.connect(); const db = client.db(DB_NAME); const collection = db.collection(COLLECTION_NAME); const tools = await collection.find({}).toArray(); await client.close(); return tools.map(tool => ({ name: tool.toolId, description: tool.toolDescription, category: tool.category, inputSchema: { type: "object", properties: tool.parameters.reduce((acc: Record<string, any>, param: any) => { acc[param.key] = { type: "string", description: param.description || `${param.key} parameter`, }; return acc; }, {}), required: tool.parameters .filter((param: any) => param.required === true) .map((param: any) => param.key), }, })); } catch (error) { console.error("MongoDB Error:", error); throw error; } } async proxyToGitHub(method: string, params: object, token: string) { if (!this.githubSessionId || this.currentToken !== token) { await this.initializeGitHubSession(token); } const requestBody = { jsonrpc: "2.0", id: 1, method, params, }; const headers: Record<string, string> = { "Authorization": `Bearer ${token}`, "Content-Type": "application/json", }; if (this.githubSessionId) { headers["Mcp-Session-Id"] = this.githubSessionId; } const response = await fetch(GITHUB_MCP_URL, { method: "POST", headers, body: JSON.stringify(requestBody), }); const text = await response.text(); if (!response.ok) { // If session expired, try to reinitialize if (response.status === 400 && text.includes("Invalid session ID")) { this.githubSessionId = null; await this.initializeGitHubSession(token); // Retry the request with new session const retryHeaders = { ...headers, "Mcp-Session-Id": this.githubSessionId!, }; const retryResponse = await fetch(GITHUB_MCP_URL, { method: "POST", headers: retryHeaders, body: JSON.stringify(requestBody), }); const retryText = await retryResponse.text(); if (!retryResponse.ok) { throw new Error(`GitHub MCP Error (${retryResponse.status}): ${retryText}`); } return JSON.parse(retryText).result; } throw new Error(`GitHub MCP Error (${response.status}): ${text}`); } try { const parsed = JSON.parse(text); return parsed.result; } catch (e) { throw new Error(`Invalid JSON from GitHub MCP: ${text}`); } } async executeTool(toolName: string, parameters: Record<string, any>, token: string) { const tools = await this.getToolSpecs(); const tool = tools.find(t => t.name === toolName); if (!tool) { throw new Error("Tool not found"); } if (toolName === "github_token") { return { content: [ { text: `Your GitHub token has been received: ${parameters.token}`, }, ], }; } else { const result = await this.proxyToGitHub("tools/call", { name: toolName, arguments: parameters, }, token); return result; } } } export const mcpService = new MCPService();

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/Rohitkumar0056/GitHub-MCP'

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