diff --git a/src/server/routes/mcp_route.ts b/src/server/routes/mcp_route.ts index e6d2247..967c2e6 100644 --- a/src/server/routes/mcp_route.ts +++ b/src/server/routes/mcp_route.ts @@ -1,67 +1,72 @@ -import Elysia from "elysia"; +import { Elysia } from "elysia"; import { t } from "elysia"; -export const MCPRoute = new Elysia({ - prefix: "/mcp-server", - tags: ["mcp-server"], -}) - .post("/mcp", ({ body }) => { - const { id, method, params } = body; +export const MCPRoute = new Elysia({ prefix: "/mcp-server" }) + .post("/mcp", async ({ body, set }) => { + const { id, method, params } = body; + set.headers['Content-Type'] = 'application/json'; + set.headers['Transfer-Encoding'] = 'chunked'; // ✅ Streaming-required for n8n - // ==== TOOLS EXECUTION ==== + // ---- STREAMING RESPONSE CONSTRUCTION ---- + const stream = new ReadableStream({ + async start(controller) { + // Jika tools/sayHello → kirim stream if (method === "tools/sayHello") { - - return { - jsonrpc: "2.0", - id, - result: { - message: `Hello from MCP Server`, - }, - }; - } - - // ==== LIST ALL TOOLS ==== - if (method === "tools/list") { - return { - jsonrpc: "2.0", - id, - result: [ - { - name: "sayHello", - description: "Greets a user with a name", - inputSchema: { - type: "object", - properties: { - name: { type: "string" }, - }, - required: ["name"], - }, - }, - ], - }; - } - - // ==== IF METHOD NOT FOUND ==== - return { + controller.enqueue(JSON.stringify({ jsonrpc: "2.0", id, - error: { - code: -32601, - message: `Method '${method}' not found`, - }, - }; - }, { - // ✅ Body JSON-RPC 2.0 schema (params & id bisa optional) - body: t.Object({ - jsonrpc: t.Optional(t.String()), - method: t.String(), - params: t.Optional(t.Record(t.String(), t.Any())), - id: t.Optional(t.Union([t.String(), t.Number()])), - }), - detail: { - summary: "MCP Server Endpoint", - description: "Handle MCP JSON-RPC requests for tools and discovery.", - }, + result: { message: "Processing..." } + }) + "\n"); // kirim chunk pertama + + await Bun.sleep(500); // contoh delay + controller.enqueue(JSON.stringify({ + jsonrpc: "2.0", + id, + result: { message: `Hello ` } + }) + "\n"); + + controller.close(); + } + + // Jika tools/list → kirim langsung tapi tetap stream + else if (method === "tools/list") { + controller.enqueue(JSON.stringify({ + jsonrpc: "2.0", + id, + result: [ + { + name: "sayHello", + description: "Greets user", + inputSchema: { + type: "object", + properties: { name: { type: "string" } }, + } + } + ] + })); + controller.close(); + } + + // Jika tidak ada method + else { + controller.enqueue(JSON.stringify({ + jsonrpc: "2.0", + id, + error: { code: -32601, message: `Method ${method} not found` } + })); + controller.close(); + } + } }); + return new Response(stream); + }, { + body: t.Object({ + jsonrpc: t.Optional(t.String()), + method: t.String(), + params: t.Optional(t.Record(t.String(), t.Any())), + id: t.Optional(t.Union([t.String(), t.Number()])), + }) + }); + export default MCPRoute;