diff --git a/src/server/lib/mcp_tool_convert.ts b/src/server/lib/mcp_tool_convert.ts index 363d029..c55f2b3 100644 --- a/src/server/lib/mcp_tool_convert.ts +++ b/src/server/lib/mcp_tool_convert.ts @@ -17,7 +17,7 @@ interface McpTool { /** * Convert OpenAPI 3.x JSON spec into MCP-compatible tool definitions. */ -export function convertOpenApiToMcpTools(openApiJson: any): McpTool[] { +export function convertOpenApiToMcpTools(openApiJson: any, filterTag: string): McpTool[] { const tools: McpTool[] = []; if (!openApiJson || typeof openApiJson !== "object") { @@ -47,7 +47,7 @@ export function convertOpenApiToMcpTools(openApiJson: any): McpTool[] { const tags: string[] = Array.isArray(operation.tags) ? operation.tags : []; if (!tags.length || !tags.some(t => - typeof t === "string" && t.toLowerCase().includes("mcp") + typeof t === "string" && t.toLowerCase().includes(filterTag) )) continue; try { @@ -356,15 +356,9 @@ function cleanToolName(name: string): string { /** * Ambil OpenAPI JSON dari endpoint dan konversi ke tools MCP */ -export async function getMcpTools(): Promise { +export async function getMcpTools(url: string, filterTag: string): Promise { try { - const baseUrl = process.env.BUN_PUBLIC_BASE_URL; - if (!baseUrl) { - throw new Error("BUN_PUBLIC_BASE_URL environment variable is not set"); - } - - const url = `${baseUrl}/docs/json`; console.log(`Fetching OpenAPI spec from: ${url}`); const response = await fetch(url); @@ -374,7 +368,7 @@ export async function getMcpTools(): Promise { } const openApiJson = await response.json(); - const tools = convertOpenApiToMcpTools(openApiJson); + const tools = convertOpenApiToMcpTools(openApiJson, filterTag); console.log(`āœ… Successfully generated ${tools.length} MCP tools`); @@ -385,28 +379,3 @@ export async function getMcpTools(): Promise { } } -// === CLI Mode === -if (import.meta.main) { - try { - const tools = await getMcpTools(); - - if (tools.length === 0) { - console.warn("āš ļø No tools generated. Check your OpenAPI spec."); - } - - await Bun.write("./tools.json", JSON.stringify(tools, null, 2)); - console.log(`āœ… Written ${tools.length} tools to tools.json`); - - console.log("\nšŸ“‹ Generated tools:"); - tools.forEach(tool => { - const reqCount = tool.inputSchema.required?.length || 0; - const propCount = Object.keys(tool.inputSchema.properties || {}).length; - console.log(` - ${tool.name}`); - console.log(` ${tool["x-props"].method} ${tool["x-props"].path}`); - console.log(` Props: ${propCount}, Required: ${reqCount}`); - }); - } catch (error) { - console.error("āŒ Failed to generate tools:", error); - process.exit(1); - } -} \ No newline at end of file diff --git a/src/server/routes/mcp_route.ts b/src/server/routes/mcp_route.ts index 2f52212..4dcec4b 100644 --- a/src/server/routes/mcp_route.ts +++ b/src/server/routes/mcp_route.ts @@ -1,8 +1,13 @@ import { Elysia } from "elysia"; import { getMcpTools } from "../lib/mcp_tool_convert"; -// import tools from "./../../../tools.json"; var tools = [] as any[]; +const OPENAPI_URL = process.env.BUN_PUBLIC_BASE_URL+"/docs/json"; +const FILTER_TAG = "mcp"; + +if (!process.env.BUN_PUBLIC_BASE_URL) { + throw new Error("BUN_PUBLIC_BASE_URL environment variable is not set"); +} // ===================== // MCP Protocol Types @@ -155,7 +160,7 @@ export const MCPRoute = new Elysia({ }) .post("/mcp", async ({ request, set }) => { if (!tools.length) { - tools = await getMcpTools(); + tools = await getMcpTools(OPENAPI_URL, FILTER_TAG); } set.headers["Content-Type"] = "application/json"; set.headers["Access-Control-Allow-Origin"] = "*"; @@ -189,7 +194,8 @@ export const MCPRoute = new Elysia({ // Tools list (debug) .get("/mcp/tools", async ({ set }) => { if (!tools.length) { - tools = await getMcpTools(); + + tools = await getMcpTools(OPENAPI_URL, FILTER_TAG); } set.headers["Access-Control-Allow-Origin"] = "*"; return { @@ -215,7 +221,7 @@ export const MCPRoute = new Elysia({ }) .get("/mcp/init", async ({ set }) => { - const _tools = await getMcpTools(); + const _tools = await getMcpTools(OPENAPI_URL, FILTER_TAG); tools = _tools; return { success: true,