tambahan
This commit is contained in:
@@ -17,7 +17,7 @@ interface McpTool {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert OpenAPI 3.x JSON spec into MCP-compatible tool definitions (without run()).
|
* Convert OpenAPI 3.x JSON spec into MCP-compatible tool definitions (without run()).
|
||||||
* Each tool corresponds to an endpoint, with metadata stored under `x-props`.
|
* Hanya menyertakan endpoint yang memiliki tag berisi "mcp".
|
||||||
*/
|
*/
|
||||||
export function convertOpenApiToMcpTools(openApiJson: any): McpTool[] {
|
export function convertOpenApiToMcpTools(openApiJson: any): McpTool[] {
|
||||||
const tools: McpTool[] = [];
|
const tools: McpTool[] = [];
|
||||||
@@ -28,10 +28,14 @@ export function convertOpenApiToMcpTools(openApiJson: any): McpTool[] {
|
|||||||
if (path.startsWith("/mcp")) continue;
|
if (path.startsWith("/mcp")) continue;
|
||||||
|
|
||||||
for (const [method, operation] of Object.entries<any>(methods as any)) {
|
for (const [method, operation] of Object.entries<any>(methods as any)) {
|
||||||
|
const tags: string[] = Array.isArray(operation.tags) ? operation.tags : [];
|
||||||
|
|
||||||
|
// ✅ exclude semua yang tidak punya tag atau tag-nya tidak mengandung "mcp"
|
||||||
|
if (!tags.length || !tags.some(t => t.toLowerCase().includes("mcp"))) continue;
|
||||||
|
|
||||||
const rawName = _.snakeCase(operation.operationId || `${method}_${path}`) || "unnamed_tool";
|
const rawName = _.snakeCase(operation.operationId || `${method}_${path}`) || "unnamed_tool";
|
||||||
const name = cleanToolName(rawName);
|
const name = cleanToolName(rawName);
|
||||||
|
|
||||||
const summary = operation.summary || `Execute ${method.toUpperCase()} ${path}`;
|
|
||||||
const description =
|
const description =
|
||||||
operation.description ||
|
operation.description ||
|
||||||
operation.summary ||
|
operation.summary ||
|
||||||
@@ -51,9 +55,9 @@ export function convertOpenApiToMcpTools(openApiJson: any): McpTool[] {
|
|||||||
method: method.toUpperCase(),
|
method: method.toUpperCase(),
|
||||||
path,
|
path,
|
||||||
operationId: operation.operationId,
|
operationId: operation.operationId,
|
||||||
tag: Array.isArray(operation.tags) ? operation.tags[0] : undefined,
|
tag: tags[0],
|
||||||
deprecated: operation.deprecated || false,
|
deprecated: operation.deprecated || false,
|
||||||
summary: operation.summary, // ✅ tambahkan summary ke metadata
|
summary: operation.summary,
|
||||||
},
|
},
|
||||||
inputSchema: {
|
inputSchema: {
|
||||||
...schema,
|
...schema,
|
||||||
@@ -87,19 +91,18 @@ function cleanToolName(name: string): string {
|
|||||||
.replace(/(^_|_$)/g, "");
|
.replace(/(^_|_$)/g, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// === Contoh Pemakaian ===
|
/**
|
||||||
// import openApiJson from "./openapi.json";
|
* Ambil OpenAPI JSON dari endpoint dan konversi ke tools MCP
|
||||||
// const tools = convertOpenApiToMcpTools(openApiJson, "https://api.wibudev.com");
|
*/
|
||||||
// console.log(JSON.stringify(tools, null, 2));
|
export async function getMcpTools() {
|
||||||
|
|
||||||
export async function getMcpTools(){
|
|
||||||
const data = await fetch(`${process.env.BUN_PUBLIC_BASE_URL}/docs/json`);
|
const data = await fetch(`${process.env.BUN_PUBLIC_BASE_URL}/docs/json`);
|
||||||
const openApiJson = await data.json();
|
const openApiJson = await data.json();
|
||||||
const tools = convertOpenApiToMcpTools(openApiJson);
|
const tools = convertOpenApiToMcpTools(openApiJson);
|
||||||
return tools;
|
return tools;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// === CLI Mode ===
|
||||||
if (import.meta.main) {
|
if (import.meta.main) {
|
||||||
const tools = await getMcpTools();
|
const tools = await getMcpTools();
|
||||||
Bun.write("./tools.json", JSON.stringify(tools, null, 2));
|
await Bun.write("./tools.json", JSON.stringify(tools, null, 2));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ const LayananRoute = new Elysia({
|
|||||||
detail: {
|
detail: {
|
||||||
summary: "Create Layanan KTP/KK",
|
summary: "Create Layanan KTP/KK",
|
||||||
description: "Create a new service request for KTP or KK.",
|
description: "Create a new service request for KTP or KK.",
|
||||||
|
tags: ["mcp"],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -131,6 +132,7 @@ const LayananRoute = new Elysia({
|
|||||||
detail: {
|
detail: {
|
||||||
summary: "Cek Status KTP",
|
summary: "Cek Status KTP",
|
||||||
description: "Retrieve the current status of a KTP/KK request by unique ID.",
|
description: "Retrieve the current status of a KTP/KK request by unique ID.",
|
||||||
|
tags: ["mcp"],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ async function handleMCPRequestAsync(
|
|||||||
// Elysia MCP Server
|
// Elysia MCP Server
|
||||||
// =====================
|
// =====================
|
||||||
export const MCPRoute = new Elysia({
|
export const MCPRoute = new Elysia({
|
||||||
tags: ["MCP"]
|
tags: ["MCP Server"]
|
||||||
})
|
})
|
||||||
.post("/mcp", async ({ request, set }) => {
|
.post("/mcp", async ({ request, set }) => {
|
||||||
if (!tools.length) {
|
if (!tools.length) {
|
||||||
|
|||||||
Reference in New Issue
Block a user