UNPKG

@access-mcp/shared

Version:

Shared utilities for ACCESS-CI MCP servers

108 lines (107 loc) 3.87 kB
import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import axios from "axios"; export class BaseAccessServer { serverName; version; baseURL; server; transport; _httpClient; constructor(serverName, version, baseURL = "https://support.access-ci.org/api") { this.serverName = serverName; this.version = version; this.baseURL = baseURL; this.server = new Server({ name: serverName, version: version, }, { capabilities: { resources: {}, tools: {}, }, }); this.transport = new StdioServerTransport(); this.setupHandlers(); } get httpClient() { if (!this._httpClient) { const headers = { "User-Agent": `${this.serverName}/${this.version}`, }; // Add authentication if API key is provided const apiKey = process.env.ACCESS_CI_API_KEY; if (apiKey) { headers["Authorization"] = `Bearer ${apiKey}`; } this._httpClient = axios.create({ baseURL: this.baseURL, timeout: 5000, headers, validateStatus: () => true, // Don't throw on HTTP errors }); } return this._httpClient; } setupHandlers() { this.server.setRequestHandler(ListToolsRequestSchema, async () => { try { return { tools: this.getTools() }; } catch (error) { // Silent error handling for MCP compatibility return { tools: [] }; } }); this.server.setRequestHandler(ListResourcesRequestSchema, async () => { try { return { resources: this.getResources() }; } catch (error) { // Silent error handling for MCP compatibility return { resources: [] }; } }); this.server.setRequestHandler(CallToolRequestSchema, async (request) => { try { return await this.handleToolCall(request); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.error("Error handling tool call:", errorMessage); return { content: [ { type: "text", text: `Error: ${errorMessage}`, }, ], }; } }); this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => { try { return await this.handleResourceRead(request); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.error("Error reading resource:", errorMessage); return { contents: [ { uri: request.params.uri, mimeType: "text/plain", text: `Error: ${errorMessage}`, }, ], }; } }); } async start() { await this.server.connect(this.transport); // MCP servers should not output anything to stderr/stdout when running // as it interferes with JSON-RPC communication } }