Skip to main content
Glama

Time Tracking MCP

by markwharton
server.ts4.36 kB
// src/server.ts import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; import { toolRegistry } from './tools/registry.js'; import { readFile } from 'fs/promises'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; // Get version from package.json const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const packageJsonPath = join(__dirname, '../package.json'); const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf-8')); // Import all tools (they self-register) import './tools/log-time.js'; import './tools/check-hours.js'; import './tools/weekly-report.js'; import './tools/status.js'; class TimeTrackingMCPServer { private server: Server; constructor() { console.error(`[Time Tracking MCP] Initializing server v${packageJson.version}...`); this.server = new Server( { name: packageJson.name, version: packageJson.version, }, { capabilities: { tools: {}, }, } ); this.setupHandlers(); console.error('[Time Tracking MCP] Server initialized with registry pattern'); } private setupHandlers() { console.error('[Time Tracking MCP] Setting up handlers...'); this.server.setRequestHandler(ListToolsRequestSchema, async () => { console.error(`[Time Tracking MCP] Listing ${toolRegistry.size} tools`); const tools = Array.from(toolRegistry.values()) .sort((a, b) => a.name.localeCompare(b.name)); return { tools: tools.map(tool => ({ name: tool.name, description: tool.description, inputSchema: tool.inputSchema, annotations: tool.annotations })) }; }); this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { const tool = toolRegistry.get(name); if (!tool) { throw new Error(`Unknown tool: ${name}`); } console.error(`[Time Tracking MCP] Executing tool: ${name}`); const result = await tool.handler(args); return { content: result.content }; } catch (error) { console.error(`[Time Tracking MCP] Error in tool ${name}:`, error); return { content: [ { type: 'text' as const, text: `Error: ${error instanceof Error ? error.message : String(error)}` } ] }; } }); console.error('[Time Tracking MCP] Handlers set up'); } async run() { try { console.error('[Time Tracking MCP] Starting server...'); const transport = new StdioServerTransport(); await this.server.connect(transport); console.error('[Time Tracking MCP] Server running on stdio'); process.stdin.resume(); process.on('SIGINT', () => { console.error('[Time Tracking MCP] Received SIGINT, shutting down...'); process.exit(0); }); process.on('SIGTERM', () => { console.error('[Time Tracking MCP] Received SIGTERM, shutting down...'); process.exit(0); }); } catch (error) { console.error('[Time Tracking MCP] Failed to start server:', error); process.exit(1); } } } // Initialize and run server try { const server = new TimeTrackingMCPServer(); server.run().catch(error => { console.error('[Time Tracking MCP] Fatal error:', error); process.exit(1); }); } catch (error) { console.error('[Time Tracking MCP] Failed to initialize server:', error); process.exit(1); }

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/markwharton/time-tracking-mcp'

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