// =============================================================================
// MCP SERVER ENTRY POINT (with A2A)
// =============================================================================
// This is the same as the basic MCP server, but uses HTTP transport instead of stdio.
// HTTP is needed because A2A requires network communication between agents.
//
// Protocols:
// - MCP: Cursor talks to THIS server
// - A2A: THIS server talks to other agents (DoorDash, UberEats, Grubhub)
// - AP2: Payment processing (NEW: implemented in ap2-client.ts and ap2-tools.ts)
// =============================================================================
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import { createServer as createHttpServer } from 'http';
import { createServer } from './server.js';
const PORT = 8000;
// Store sessions
const sessions = new Map<string, { transport: StreamableHTTPServerTransport; server: McpServer }>();
async function startServer(): Promise<void> {
createHttpServer(async (req, res) => {
if (!req.url?.startsWith('/mcp')) {
res.writeHead(404);
res.end('Not Found');
return;
}
// Get session ID from header (may be undefined for first request)
const sessionId = req.headers['mcp-session-id'] as string | undefined;
// POST - main MCP requests
if (req.method === 'POST') {
let session = sessionId ? sessions.get(sessionId) : undefined;
// Create new session if needed
if (!session) {
const newSessionId = `session-${Date.now()}-${Math.random().toString(36).slice(2)}`;
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => newSessionId,
});
const mcpServer = await createServer();
await mcpServer.server.connect(transport);
session = { transport, server: mcpServer };
sessions.set(newSessionId, session);
}
await session.transport.handleRequest(req, res);
return;
}
// GET - SSE stream
if (req.method === 'GET' && sessionId) {
const session = sessions.get(sessionId);
if (session) {
await session.transport.handleRequest(req, res);
return;
}
}
// DELETE - cleanup
if (req.method === 'DELETE' && sessionId) {
sessions.delete(sessionId);
res.writeHead(200);
res.end();
return;
}
res.writeHead(404);
res.end('Not Found');
}).listen(PORT, '0.0.0.0', () => {
console.log(`MCP Server: http://localhost:${PORT}/mcp`);
});
}
startServer();