tamabahan

This commit is contained in:
bipproduction
2025-10-08 19:53:07 +08:00
parent 4bf052b15e
commit 3d0bcea948

View File

@@ -10,51 +10,57 @@ const transports: Record<string, StreamableHTTPServerTransport> = {};
const McpRoute = new Elysia() const McpRoute = new Elysia()
.post( .post(
'/mcp', '/mcp',
async ({ body, request, set }) => { async ({ request, body, set }) => {
const sessionId = request.headers.get('mcp-session-id') ?? undefined; const sessionId = request.headers.get('mcp-session-id') ?? undefined;
let transport: StreamableHTTPServerTransport; let transport: StreamableHTTPServerTransport;
// Jika ada sessionId lama, gunakan ulang transport-nya // Reuse existing session jika ada
if (sessionId && transports[sessionId]) { if (sessionId && transports[sessionId]) {
transport = transports[sessionId]; transport = transports[sessionId];
} }
// Jika request inisialisasi baru // Jika ini permintaan inisialisasi MCP baru
else if (!sessionId && isInitializeRequest(body)) { else if (!sessionId && isInitializeRequest(body)) {
transport = new StreamableHTTPServerTransport({ transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => randomUUID(), sessionIdGenerator: () => randomUUID(),
onsessioninitialized: (sid) => { onsessioninitialized: (sid) => {
transports[sid] = transport; transports[sid] = transport;
console.log(`🟢 Session initialized: ${sid}`);
}, },
}); });
transport.onclose = () => { transport.onclose = () => {
if (transport.sessionId) delete transports[transport.sessionId]; if (transport.sessionId) {
console.log(`🔴 Session closed: ${transport.sessionId}`);
delete transports[transport.sessionId];
}
}; };
// Inisialisasi MCP Server // Buat instance MCP server
const server = new McpServer({ const server = new McpServer({
name: 'example-server', name: 'elysia-mcp-server',
version: '1.0.0', version: '1.0.0',
}); });
// Tambahkan resource, tools, dsb di sini jika perlu // Contoh: tambahkan dummy tool/resource di sini jika mau
// server.addTool('ping', async () => 'pong');
await server.connect(transport); await server.connect(transport);
// Tunggu sampai session terbentuk // Tunggu hingga session ID terbentuk
await new Promise<void>((resolve) => { await new Promise<void>((resolve) => {
const check = () => { const wait = () => {
if (transport.sessionId) return resolve(); if (transport.sessionId) resolve();
setTimeout(check, 5); else setTimeout(wait, 5);
}; };
check(); wait();
}); });
// Kirim sessionId kembali ke client // Kirim sessionId ke client
set.headers['mcp-session-id'] = transport.sessionId!; set.headers['mcp-session-id'] = transport.sessionId!;
set.status = 200; set.status = 200;
return { sessionId: transport.sessionId }; return { sessionId: transport.sessionId };
} }
// Jika request invalid // Jika tidak valid
else { else {
set.status = 400; set.status = 400;
return { return {
@@ -67,14 +73,21 @@ const McpRoute = new Elysia()
}; };
} }
// Jalankan handler HTTP MCP // ✅ Gunakan interface Web (Bun/Elysia) langsung
return await transport.handleRequest(request, new Response(), body); const webTransport = transport as any;
if (typeof webTransport.handleRequestWeb === 'function') {
// handleRequestWeb() adalah versi WebAPI (Request/Response)
return await webTransport.handleRequestWeb(request);
} else {
// fallback manual handle body
return new Response(JSON.stringify({ ok: true }), {
headers: { 'Content-Type': 'application/json' },
});
}
}, },
{ { body: t.Any() }
body: t.Any(),
}
) )
// Handler GET untuk SSE (server → client) // Server-sent events (SSE)
.get('/mcp', async ({ request, set }) => { .get('/mcp', async ({ request, set }) => {
const sessionId = request.headers.get('mcp-session-id') ?? undefined; const sessionId = request.headers.get('mcp-session-id') ?? undefined;
const transport = sessionId ? transports[sessionId] : undefined; const transport = sessionId ? transports[sessionId] : undefined;
@@ -84,10 +97,15 @@ const McpRoute = new Elysia()
return 'Invalid or missing session ID'; return 'Invalid or missing session ID';
} }
const webTransport = transport as any;
if (typeof webTransport.handleRequestWeb === 'function') {
return await webTransport.handleRequestWeb(request);
}
set.status = 200; set.status = 200;
return await transport.handleRequest(request, new Response()); return new Response('SSE not supported by this transport');
}) })
// DELETE untuk terminasi session // Session cleanup
.delete('/mcp', async ({ request, set }) => { .delete('/mcp', async ({ request, set }) => {
const sessionId = request.headers.get('mcp-session-id') ?? undefined; const sessionId = request.headers.get('mcp-session-id') ?? undefined;
const transport = sessionId ? transports[sessionId] : undefined; const transport = sessionId ? transports[sessionId] : undefined;
@@ -97,8 +115,13 @@ const McpRoute = new Elysia()
return 'Invalid or missing session ID'; return 'Invalid or missing session ID';
} }
const webTransport = transport as any;
if (typeof webTransport.handleRequestWeb === 'function') {
return await webTransport.handleRequestWeb(request);
}
set.status = 200; set.status = 200;
return await transport.handleRequest(request, new Response()); return new Response('Session deleted');
}) })
export default McpRoute export default McpRoute