Skip to main content
Glama
srobbin
by srobbin
index.ts3.78 kB
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { Tool, CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; import 'dotenv/config'; // Import Socrata unified tool import { SOCRATA_TOOLS, handleSocrataTool } from './tools/socrata-tools.js'; import { getPortalInfo, PortalInfo } from './utils/portal-info.js'; // Initialize the server const server = new Server( { name: 'opengov-mcp', version: '0.1.0' }, { capabilities: { tools: {}, logging: {} } } ); // Handle tool calls server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { server.sendLoggingMessage({ level: 'info', data: { message: `Handling tool call: ${name}`, tool: name, arguments: args, timestamp: new Date().toISOString(), }, }); let result: unknown; if (name === 'get_data') { // Handle the unified data retrieval tool result = await handleSocrataTool(args || {}); } else { throw new Error(`Unknown tool: ${name}`); } // Log success server.sendLoggingMessage({ level: 'info', data: { message: `Successfully executed tool: ${name}`, tool: name, resultSize: JSON.stringify(result).length, timestamp: new Date().toISOString(), }, }); return { content: [{ type: 'text', text: JSON.stringify(result) }], isError: false, }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); server.sendLoggingMessage({ level: 'error', data: { message: `Error handling tool ${name}: ${errorMessage}`, tool: name, arguments: args, timestamp: new Date().toISOString(), error: errorMessage, }, }); return { content: [{ type: 'text', text: `Error: ${errorMessage}` }], isError: true, }; } }); // Enhanced tool with portal context function enhanceToolsWithPortalInfo(tools: Tool[], portalInfo: PortalInfo): Tool[] { return tools.map(tool => { // Create a copy of the tool const enhancedTool: Tool = { ...tool }; // Add portal info to the description enhancedTool.description = `[${portalInfo.title}] ${tool.description}`; return enhancedTool; }); } // Start the server async function runServer() { try { // Get information about the data portal const portalInfo = await getPortalInfo(); // Don't use console.log as it interferes with the JSON-RPC protocol // Instead, we'll log through the MCP logging capability after connecting // Update tools list with portal info const enhancedTools = enhanceToolsWithPortalInfo(SOCRATA_TOOLS, portalInfo); // Update the tools handler server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: enhancedTools, })); // Connect to transport const transport = new StdioServerTransport(); await server.connect(transport); server.sendLoggingMessage({ level: 'info', data: { message: `OpenGov MCP Server started for data portal: ${portalInfo.title}`, portalInfo, timestamp: new Date().toISOString(), }, }); } catch (error) { console.error('Error during server initialization:', error); process.exit(1); } } runServer().catch((error) => { // Need to use console.error for startup failures as logging API isn't available yet console.error('Fatal error running server:', error); process.exit(1); });

Implementation Reference

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/srobbin/opengov-mcp-server'

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