#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, McpError, ErrorCode, } from "@modelcontextprotocol/sdk/types.js"; import { z } from "zod"; import { UpworkClient } from "./services/upwork-client.js"; import { toolHandlers, tools } from "./tools/index.js"; import { SERVER_INFO } from "./utils/constants.js"; class UpworkServer { private server: Server; private upworkClient: UpworkClient; constructor() { this.server = new Server( { name: SERVER_INFO.name, version: SERVER_INFO.version, }, { capabilities: { tools: {}, }, } ); // Initialize Upwork client this.upworkClient = new UpworkClient(); this.setupHandlers(); } private setupHandlers() { // List tools handler this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: tools, }; }); // Call tool handler this.server.setRequestHandler(CallToolRequestSchema, async (request) => { try { const { name, arguments: args } = request.params; // Check if tool exists if (!(name in toolHandlers)) { throw new McpError( ErrorCode.MethodNotFound, `Unknown tool: ${name}` ); } // Call the appropriate handler return await (toolHandlers as any)[name](args, this.upworkClient); } catch (error) { if (error instanceof z.ZodError) { throw new McpError( ErrorCode.InvalidParams, `Invalid parameters: ${error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ')}` ); } throw error; } }); } async run() { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error("Upwork MCP server running on stdio"); } } // Start the server const server = new UpworkServer(); server.run().catch(console.error);