fix mcp generator
This commit is contained in:
@@ -17,7 +17,7 @@ interface McpTool {
|
|||||||
/**
|
/**
|
||||||
* Convert OpenAPI 3.x JSON spec into MCP-compatible tool definitions.
|
* 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[] = [];
|
const tools: McpTool[] = [];
|
||||||
|
|
||||||
if (!openApiJson || typeof openApiJson !== "object") {
|
if (!openApiJson || typeof openApiJson !== "object") {
|
||||||
@@ -47,7 +47,7 @@ export function convertOpenApiToMcpTools(openApiJson: any): McpTool[] {
|
|||||||
const tags: string[] = Array.isArray(operation.tags) ? operation.tags : [];
|
const tags: string[] = Array.isArray(operation.tags) ? operation.tags : [];
|
||||||
|
|
||||||
if (!tags.length || !tags.some(t =>
|
if (!tags.length || !tags.some(t =>
|
||||||
typeof t === "string" && t.toLowerCase().includes("mcp")
|
typeof t === "string" && t.toLowerCase().includes(filterTag)
|
||||||
)) continue;
|
)) continue;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -356,15 +356,9 @@ function cleanToolName(name: string): string {
|
|||||||
/**
|
/**
|
||||||
* Ambil OpenAPI JSON dari endpoint dan konversi ke tools MCP
|
* Ambil OpenAPI JSON dari endpoint dan konversi ke tools MCP
|
||||||
*/
|
*/
|
||||||
export async function getMcpTools(): Promise<McpTool[]> {
|
export async function getMcpTools(url: string, filterTag: string): Promise<McpTool[]> {
|
||||||
try {
|
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}`);
|
console.log(`Fetching OpenAPI spec from: ${url}`);
|
||||||
|
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
@@ -374,7 +368,7 @@ export async function getMcpTools(): Promise<McpTool[]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const openApiJson = await response.json();
|
const openApiJson = await response.json();
|
||||||
const tools = convertOpenApiToMcpTools(openApiJson);
|
const tools = convertOpenApiToMcpTools(openApiJson, filterTag);
|
||||||
|
|
||||||
console.log(`✅ Successfully generated ${tools.length} MCP tools`);
|
console.log(`✅ Successfully generated ${tools.length} MCP tools`);
|
||||||
|
|
||||||
@@ -385,28 +379,3 @@ export async function getMcpTools(): Promise<McpTool[]> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// === 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
import { Elysia } from "elysia";
|
import { Elysia } from "elysia";
|
||||||
import { getMcpTools } from "../lib/mcp_tool_convert";
|
import { getMcpTools } from "../lib/mcp_tool_convert";
|
||||||
// import tools from "./../../../tools.json";
|
|
||||||
|
|
||||||
var tools = [] as any[];
|
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
|
// MCP Protocol Types
|
||||||
@@ -155,7 +160,7 @@ export const MCPRoute = new Elysia({
|
|||||||
})
|
})
|
||||||
.post("/mcp", async ({ request, set }) => {
|
.post("/mcp", async ({ request, set }) => {
|
||||||
if (!tools.length) {
|
if (!tools.length) {
|
||||||
tools = await getMcpTools();
|
tools = await getMcpTools(OPENAPI_URL, FILTER_TAG);
|
||||||
}
|
}
|
||||||
set.headers["Content-Type"] = "application/json";
|
set.headers["Content-Type"] = "application/json";
|
||||||
set.headers["Access-Control-Allow-Origin"] = "*";
|
set.headers["Access-Control-Allow-Origin"] = "*";
|
||||||
@@ -189,7 +194,8 @@ export const MCPRoute = new Elysia({
|
|||||||
// Tools list (debug)
|
// Tools list (debug)
|
||||||
.get("/mcp/tools", async ({ set }) => {
|
.get("/mcp/tools", async ({ set }) => {
|
||||||
if (!tools.length) {
|
if (!tools.length) {
|
||||||
tools = await getMcpTools();
|
|
||||||
|
tools = await getMcpTools(OPENAPI_URL, FILTER_TAG);
|
||||||
}
|
}
|
||||||
set.headers["Access-Control-Allow-Origin"] = "*";
|
set.headers["Access-Control-Allow-Origin"] = "*";
|
||||||
return {
|
return {
|
||||||
@@ -215,7 +221,7 @@ export const MCPRoute = new Elysia({
|
|||||||
})
|
})
|
||||||
.get("/mcp/init", async ({ set }) => {
|
.get("/mcp/init", async ({ set }) => {
|
||||||
|
|
||||||
const _tools = await getMcpTools();
|
const _tools = await getMcpTools(OPENAPI_URL, FILTER_TAG);
|
||||||
tools = _tools;
|
tools = _tools;
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user