import express from "express"; import { randomUUID } from "node:crypto"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js"; import { CourierRegistry } from "./registry.js"; import { loadConfig } from "./config.js"; import { buildMcpServer, TOOLS } from "./server.js"; import path from "node:path"; import { fileURLToPath } from "node:url"; import pg from "pg"; const dbUrl = process.env.DATABASE_URL || "postgresql://postgres:AMeyaNUsvKN9GR4zs33YZFQw2ZjeBXRacp5K09bz4vwDMsLejuO1KxBGIZtDLVCw@ernix50nvuq9ur9jy8na8tgr:5432/aura_auth"; let dbPool = null; try { dbPool = new pg.Pool({ connectionString: dbUrl, max: 4, idleTimeoutMillis: 30000 }); } catch (_) { } const PORT = Number(process.env.PORT || 8080); const APP_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); const LANDING = path.join(APP_DIR, "index.html"); const HEALTH_HTML = path.join(APP_DIR, "health.html"); const MCP_EXPLORER_HTML = path.join(APP_DIR, "mcp_explorer.html"); // Pull this client's courier keys from request headers or query params, with fallback to environment function keysFromRequest(req) { const h = req.headers; const q = req.query; const pick = (header, query, envVar) => { const hv = h[header]; const v = (Array.isArray(hv) ? hv[0] : hv) ?? q[query]; return v ? String(v) : (envVar ? process.env[envVar] : undefined); }; return { STEADFAST_API_KEY: pick("x-steadfast-api-key", "steadfast_key", "STEADFAST_API_KEY"), STEADFAST_SECRET_KEY: pick("x-steadfast-secret-key", "steadfast_secret", "STEADFAST_SECRET_KEY"), STEADFAST_BASE_URL: pick("x-steadfast-base-url", "steadfast_base_url", "STEADFAST_BASE_URL"), PATHAO_CLIENT_ID: pick("x-pathao-client-id", "pathao_client_id", "PATHAO_CLIENT_ID"), PATHAO_CLIENT_SECRET: pick("x-pathao-client-secret", "pathao_client_secret", "PATHAO_CLIENT_SECRET"), PATHAO_USERNAME: pick("x-pathao-username", "pathao_username", "PATHAO_USERNAME"), PATHAO_PASSWORD: pick("x-pathao-password", "pathao_password", "PATHAO_PASSWORD"), PATHAO_STORE_ID: pick("x-pathao-store-id", "pathao_store_id", "PATHAO_STORE_ID"), PATHAO_BASE_URL: pick("x-pathao-base-url", "pathao_base_url", "PATHAO_BASE_URL"), REDX_API_TOKEN: pick("x-redx-api-token", "redx_token", "REDX_API_TOKEN"), REDX_BASE_URL: pick("x-redx-base-url", "redx_base_url", "REDX_BASE_URL"), REDX_PICKUP_STORE_ID: pick("x-redx-pickup-store-id", "redx_pickup_store_id", "REDX_PICKUP_STORE_ID"), PAPERFLY_API_KEY: pick("x-paperfly-api-key", "paperfly_key", "PAPERFLY_API_KEY"), PAPERFLY_USERNAME: pick("x-paperfly-username", "paperfly_username", "PAPERFLY_USERNAME"), PAPERFLY_PASSWORD: pick("x-paperfly-password", "paperfly_password", "PAPERFLY_PASSWORD"), PAPERFLY_STORE_NAME: pick("x-paperfly-store-name", "paperfly_store", "PAPERFLY_STORE_NAME"), GOOGLE_MAPS_API_KEY: pick("x-google-maps-key", "google_maps_key", "GOOGLE_MAPS_API_KEY"), }; } const app = express(); app.use(express.json({ limit: "1mb" })); // Allow browser-based and cross-origin MCP clients. app.use((req, res, next) => { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, mcp-session-id, mcp-protocol-version, x-steadfast-api-key, x-steadfast-secret-key, x-steadfast-base-url, x-pathao-client-id, x-pathao-client-secret, x-pathao-username, x-pathao-password, x-pathao-store-id, x-pathao-base-url, x-redx-api-token, x-redx-base-url, x-redx-pickup-store-id, x-paperfly-api-key, x-paperfly-username, x-paperfly-password, x-paperfly-store-name, x-google-maps-key"); res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS"); res.header("Access-Control-Expose-Headers", "mcp-session-id"); if (req.method === "OPTIONS") { res.sendStatus(204); return; } next(); }); const sessions = new Map(); const SESSION_TTL_MS = 60 * 60 * 1000; // 1-hour idle expiration // Sweep abandoned sessions every 15 minutes to prevent heap bloat setInterval(() => { const now = Date.now(); for (const [sid, entry] of sessions.entries()) { if (now - entry.lastActiveAt > SESSION_TTL_MS) { console.log(`[Memory GC] Evicting stale MCP session: ${sid}`); try { entry.transport.close?.(); } catch { } sessions.delete(sid); } } }, 15 * 60 * 1000).unref(); app.post("/mcp", async (req, res) => { const sessionId = req.headers["mcp-session-id"]; let transport; if (sessionId && sessions.has(sessionId)) { const entry = sessions.get(sessionId); entry.lastActiveAt = Date.now(); transport = entry.transport; } else if (!sessionId && isInitializeRequest(req.body)) { const registry = new CourierRegistry(loadConfig(keysFromRequest(req))); const server = buildMcpServer(registry); transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), // Return application/json for POST responses instead of SSE — far more compatible with // MCP clients/registries (e.g. Glama's connector test) that don't consume the event stream. enableJsonResponse: true, onsessioninitialized: (sid) => { sessions.set(sid, { transport, lastActiveAt: Date.now() }); }, }); transport.onclose = () => { if (transport.sessionId) sessions.delete(transport.sessionId); }; await server.connect(transport); } else { res.status(400).json({ jsonrpc: "2.0", error: { code: -32000, message: "Bad Request: missing or invalid session. Send an initialize request first." }, id: null, }); return; } try { await transport.handleRequest(req, res, req.body); } catch (err) { if (!res.headersSent) { res.status(500).json({ jsonrpc: "2.0", error: { code: -32603, message: `Internal error: ${err?.message || String(err)}` }, id: null, }); } } }); // GET (server->client SSE stream or Browser Explorer) app.get("/mcp", async (req, res) => { const sessionId = req.headers["mcp-session-id"]; if (!sessionId || !sessions.has(sessionId)) { // If opened directly by a human in a web browser, serve the interactive MCP Protocol Explorer! if (req.headers.accept?.includes("text/html")) { return res.sendFile(MCP_EXPLORER_HTML, (err) => { if (err && !res.headersSent) { res.status(400).send("Invalid or missing session ID. Visit https://courier.auraajenticai.cloud for instructions."); } }); } res.status(400).send("Invalid or missing session ID"); return; } const entry = sessions.get(sessionId); entry.lastActiveAt = Date.now(); await entry.transport.handleRequest(req, res); }); // DELETE (end session) for an existing session. app.delete("/mcp", async (req, res) => { const sessionId = req.headers["mcp-session-id"]; if (!sessionId || !sessions.has(sessionId)) { res.status(400).send("Invalid or missing session ID"); return; } const entry = sessions.get(sessionId); entry.lastActiveAt = Date.now(); await entry.transport.handleRequest(req, res); }); /** * Official Steadfast Webhook Integration Endpoint * Callback URL: https://courier.auraajenticai.cloud/webhooks/steadfast */ app.post("/webhooks/steadfast", (req, res) => { const payload = req.body; console.log("[Steadfast Webhook Received]:", JSON.stringify(payload)); if (!payload || !payload.consignment_id) { return res.status(400).json({ status: "error", message: "Invalid consignment ID.", }); } const notifType = payload.notification_type || "delivery_status"; const consignmentId = payload.consignment_id; const status = payload.status; const invoice = payload.invoice; console.log(`[Steadfast Update] Consignment: ${consignmentId} | Invoice: ${invoice} | Type: ${notifType} | Status: ${status}`); if (status === "cancelled") { console.warn(`[Steadfast NDR Alert] Consignment ${consignmentId} was cancelled. Initiating NDR triage.`); } return res.status(200).json({ status: "success", message: "Webhook received successfully.", }); }); /** * Official Pathao Webhook Integration Endpoint * Callback URL: https://courier.auraajenticai.cloud/webhooks/pathao */ app.post("/webhooks/pathao", (req, res) => { const payload = req.body; console.log("[Pathao Webhook Received]:", JSON.stringify(payload)); return res.status(200).json({ status: "success", message: "Pathao webhook received successfully.", }); }); /** * Official RedX Webhook Integration Endpoint * Callback URL: https://courier.auraajenticai.cloud/webhooks/redx */ app.post("/webhooks/redx", (req, res) => { const payload = req.body; console.log("[RedX Webhook Received]:", JSON.stringify(payload)); return res.status(200).json({ status: "success", message: "RedX webhook received successfully.", }); }); /** * Official Paperfly Webhook Integration Endpoint * Callback URL: https://courier.auraajenticai.cloud/webhooks/paperfly */ app.post("/webhooks/paperfly", (req, res) => { const payload = req.body; console.log("[Paperfly Webhook Received]:", JSON.stringify(payload)); return res.status(200).json({ status: "success", message: "Paperfly webhook received successfully.", }); }); /** * Live Consumer & Merchant Cyber-Dark Tracking Hub * GET /track/:code */ app.get("/track/:code", async (req, res) => { const code = req.params.code; const format = req.query.format; let courier = (req.query.courier || "").toLowerCase(); if (!courier) { if (code.toUpperCase().startsWith("DS") || code.toUpperCase().startsWith("DB")) courier = "pathao"; else if (code.toUpperCase().startsWith("SF") || /^\d{8,12}$/.test(code)) courier = "steadfast"; else if (code.toUpperCase().startsWith("REDX") || code.toUpperCase().startsWith("RX")) courier = "redx"; else if (code.toUpperCase().startsWith("PF")) courier = "paperfly"; else courier = "pathao"; } // 1. Check persistent database for authentic booking records (Customer name, destination, COD amount) let dbParcel = null; if (dbPool) { try { const qRes = await dbPool.query("SELECT * FROM courier_parcels WHERE tracking_code = $1 LIMIT 1", [code]); if (qRes.rows && qRes.rows.length > 0) { dbParcel = qRes.rows[0]; } } catch (e) { console.warn("DB lookup error for parcel:", e.message); } } // 2. Query carrier live telemetry API via MCP const registry = new CourierRegistry(loadConfig(keysFromRequest(req))); let trackResult = null; let errorMsg = null; try { trackResult = await registry.trackParcel(code, courier); } catch (err) { errorMsg = err?.message || String(err); } if (format === "json" || (!req.headers.accept?.includes("text/html") && format !== "html")) { return res.json(trackResult || (dbParcel ? { success: true, parcel: dbParcel } : { success: false, tracking_code: code, error: errorMsg })); } const raw = trackResult?.raw_response?.data || trackResult?.raw_response || (dbParcel?.raw?.data || dbParcel?.raw) || {}; const recipientName = dbParcel?.customer_name || raw.recipient_name || raw.customer_name || raw.name || "Verified Customer"; const recipientAddress = dbParcel?.address || raw.recipient_address || raw.address || "Bangladesh"; const codAmount = dbParcel?.cod_amount || raw.order_amount || raw.amount_to_collect || raw.cod_amount || raw.collectable_amount || 0; const statusText = trackResult?.status || raw.order_status || (dbParcel?.status ? dbParcel.status.charAt(0).toUpperCase() + dbParcel.status.slice(1) : "In Transit"); const resolvedCourier = (dbParcel?.courier || courier || "pathao").toLowerCase(); const carrierName = resolvedCourier === "pathao" ? "Pathao Express" : (resolvedCourier === "steadfast" ? "Steadfast Courier" : resolvedCourier === "redx" ? "RedX Delivery" : resolvedCourier === "paperfly" ? "Paperfly Go" : resolvedCourier.toUpperCase()); const shortLink = raw.short_link || (carrierName.toLowerCase().includes("pathao") ? `https://merchant.pathao.com/tracking?consignment_id=${code}` : (carrierName.toLowerCase().includes("steadfast") ? `https://steadfast.com.bd/t/${code}` : "")); const updatedAt = raw.order_status_updated_at || raw.updated_at || trackResult?.updated_at || (dbParcel?.updated_at ? new Date(dbParcel.updated_at).toLocaleString('en-GB') : new Date().toLocaleString()); const isDelivered = String(statusText).toLowerCase().includes("deliv"); const isAtHub = String(statusText).toLowerCase().includes("hub"); const isTransit = String(statusText).toLowerCase().includes("way") || String(statusText).toLowerCase().includes("transit") || String(statusText).toLowerCase().includes("progress"); const isPickedUp = isDelivered || isAtHub || isTransit || String(statusText).toLowerCase().includes("pick"); res.type("html").send(`
${carrierName} • Direct Live Telemetry
Enterprise Bangladesh courier MCP & Google Maps Platform spatial hub.
` + `Connect your AI to POST /mcp with Streamable-HTTP.
Webhooks: POST /webhooks/steadfast · POST /webhooks/pathao