tamabahan
This commit is contained in:
@@ -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
|
||||||
Reference in New Issue
Block a user