roundhr-mcp-server
Version:
MCP server for RoundHR database tools
129 lines (128 loc) • 5.16 kB
JavaScript
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");
}