UNPKG

roundhr-mcp-server

Version:

MCP server for RoundHR database tools

129 lines (128 loc) 5.16 kB
#!/usr/bin/env node import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; import { RoundReportClient } from "./clients/round-report-client.js"; import { handleExecuteQuery, handleSchema } from "./handlers/report-handler.js"; import { ExecuteQueryArgsSchema } from "./schemas/report-schema.js"; // Configuration schema for Smithery export const configSchema = z.object({ API_KEY: z.string().describe("roundHR API Key"), }); export function createRoundMcpServer({ config }) { // Create a new MCP server per MCP spec const server = new McpServer({ name: "roundhr-mcp-server", version: "0.0.15", }); // Initialize Round mcp client with config const client = RoundReportClient.getInstance(); client.initialize({ apiKey: config.API_KEY, }); server.registerTool("get_database_schema", { description: "채용 관련 데이터에 대한 스키마 입니다. 해당 정보로 쿼리를 생성 할 수 있습니다. 쿼리가 생성되면 execute_query tool 을 호출 하여 결과를 알 수 있습니다.", inputSchema: {} }, async (_args) => { const result = await handleSchema(); return { content: [ { type: "text", text: JSON.stringify(result?.schema, null, 2), }, { type: "text", text: `쿼리에 주석은 포함하지 않고 생성, 쿼리를 만들때 항상 organization_id = ${result?.organization_id} 정보를 where 절에 포함하여 생성`, }, ] }; }); server.registerTool("execute_query", { description: "쿼리를 실행시키면 데이터를 리턴합니다.", inputSchema: ExecuteQueryArgsSchema.shape }, async (args) => { const result = await handleExecuteQuery(args); return { content: [ { type: "text", text: JSON.stringify(result, null, 2), }, ] }; }); return server.server; } // Export default for Smithery compatibility export default createRoundMcpServer; // Main function to run the server when executed directly async function main() { try { console.error("Starting MCP Server..."); const apiKey = process.env.API_KEY?.trim(); console.error("Environment variables:", { API_KEY: process.env.API_KEY ? `[${process.env.API_KEY.length} chars]` : 'undefined', }); if (!apiKey) { throw new Error(`Missing required environment variables: Please set these environment variables before running the server.`); } const config = { API_KEY: apiKey, }; console.error("Config loaded successfully"); // Validate config const validatedConfig = configSchema.parse(config); console.error("Config validated successfully"); // Create server instance const serverFactory = createRoundMcpServer({ config: validatedConfig }); console.error("Server factory created"); // Create transport and run server const transport = new StdioServerTransport(); console.error("Transport created, connecting..."); await serverFactory.connect(transport); console.error("Server connected and running"); } catch (error) { console.error("Error in main function:", error); throw error; } } // Run main function if this file is executed directly // Note: Always run main in CLI mode since this is an MCP server console.error("Starting MCP server initialization..."); console.error("process.argv:", process.argv); let isMainModule = false; try { // Try ESM approach first if (typeof import.meta !== 'undefined' && import.meta.url) { console.error("import.meta.url:", import.meta.url); isMainModule = import.meta.url === `file://${process.argv[1]}` || import.meta.url.endsWith(process.argv[1]) || process.argv[1].endsWith("index.js") || process.argv[1].includes("roundhr-mcp-server") || process.argv[1].endsWith(".bin/roundhr-mcp-server") || process.argv[1].includes("_npx"); } else { // Fallback for CommonJS or when import.meta is not available isMainModule = process.argv[1].endsWith("index.js") || process.argv[1].includes("roundhr-mcp-server"); } } catch (error) { // Fallback for environments where import.meta causes issues isMainModule = process.argv[1].endsWith("index.js") || process.argv[1].includes("roundhr-mcp-server"); } console.error("isMainModule:", isMainModule); if (isMainModule) { console.error("Running as main module, starting server..."); main().catch((error) => { console.error("Server failed to start:", error); process.exit(1); }); } else { console.error("Not running as main module, skipping server start"); }