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()
.post(
'/mcp',
async ({ body, request, set }) => {
async ({ request, body, set }) => {
const sessionId = request.headers.get('mcp-session-id') ?? undefined;
let transport: StreamableHTTPServerTransport;
// Jika ada sessionId lama, gunakan ulang transport-nya
// Reuse existing session jika ada
if (sessionId && transports[sessionId]) {
transport = transports[sessionId];
}
// Jika request inisialisasi baru
// Jika ini permintaan inisialisasi MCP baru
else if (!sessionId && isInitializeRequest(body)) {
transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => randomUUID(),
onsessioninitialized: (sid) => {
transports[sid] = transport;
console.log(`🟢 Session initialized: ${sid}`);
},
});
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({
name: 'example-server',
name: 'elysia-mcp-server',
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);
// Tunggu sampai session terbentuk
// Tunggu hingga session ID terbentuk
await new Promise<void>((resolve) => {
const check = () => {
if (transport.sessionId) return resolve();
setTimeout(check, 5);
const wait = () => {
if (transport.sessionId) resolve();
else setTimeout(wait, 5);
};
check();
wait();
});
// Kirim sessionId kembali ke client
// Kirim sessionId ke client
set.headers['mcp-session-id'] = transport.sessionId!;
set.status = 200;
return { sessionId: transport.sessionId };
}
// Jika request invalid
// Jika tidak valid
else {
set.status = 400;
return {
@@ -67,14 +73,21 @@ const McpRoute = new Elysia()
};
}
// Jalankan handler HTTP MCP
return await transport.handleRequest(request, new Response(), body);
// ✅ Gunakan interface Web (Bun/Elysia) langsung
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 }) => {
const sessionId = request.headers.get('mcp-session-id') ?? undefined;
const transport = sessionId ? transports[sessionId] : undefined;
@@ -84,10 +97,15 @@ const McpRoute = new Elysia()
return 'Invalid or missing session ID';
}
const webTransport = transport as any;
if (typeof webTransport.handleRequestWeb === 'function') {
return await webTransport.handleRequestWeb(request);
}
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 }) => {
const sessionId = request.headers.get('mcp-session-id') ?? undefined;
const transport = sessionId ? transports[sessionId] : undefined;
@@ -97,8 +115,13 @@ const McpRoute = new Elysia()
return 'Invalid or missing session ID';
}
const webTransport = transport as any;
if (typeof webTransport.handleRequestWeb === 'function') {
return await webTransport.handleRequestWeb(request);
}
set.status = 200;
return await transport.handleRequest(request, new Response());
return new Response('Session deleted');
})
export default McpRoute