@codespar/mcp-ap2
Advanced tools
+42
-5
@@ -31,2 +31,4 @@ #!/usr/bin/env node | ||
| import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; | ||
| import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; | ||
| import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js"; | ||
| import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; | ||
@@ -420,9 +422,44 @@ const API_KEY = process.env.AP2_API_KEY || ""; | ||
| async function main() { | ||
| if (!API_KEY) { | ||
| console.error("AP2_API_KEY environment variable is required"); | ||
| process.exit(1); | ||
| if (process.argv.includes("--http") || process.env.MCP_HTTP === "true") { | ||
| const { default: express } = await import("express"); | ||
| const { randomUUID } = await import("node:crypto"); | ||
| const app = express(); | ||
| app.use(express.json()); | ||
| const transports = new Map(); | ||
| app.get("/health", (_req, res) => res.json({ status: "ok", sessions: transports.size })); | ||
| app.post("/mcp", async (req, res) => { | ||
| const sid = req.headers["mcp-session-id"]; | ||
| if (sid && transports.has(sid)) { | ||
| await transports.get(sid).handleRequest(req, res, req.body); | ||
| return; | ||
| } | ||
| if (!sid && isInitializeRequest(req.body)) { | ||
| const t = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), onsessioninitialized: (id) => { transports.set(id, t); } }); | ||
| t.onclose = () => { if (t.sessionId) | ||
| transports.delete(t.sessionId); }; | ||
| const s = new Server({ name: "mcp-ap2", version: "0.1.0" }, { capabilities: { tools: {} } }); | ||
| server._requestHandlers.forEach((v, k) => s._requestHandlers.set(k, v)); | ||
| server._notificationHandlers?.forEach((v, k) => s._notificationHandlers.set(k, v)); | ||
| await s.connect(t); | ||
| await t.handleRequest(req, res, req.body); | ||
| return; | ||
| } | ||
| res.status(400).json({ jsonrpc: "2.0", error: { code: -32000, message: "Bad Request" }, id: null }); | ||
| }); | ||
| app.get("/mcp", async (req, res) => { const sid = req.headers["mcp-session-id"]; if (sid && transports.has(sid)) | ||
| await transports.get(sid).handleRequest(req, res); | ||
| else | ||
| res.status(400).send("Invalid session"); }); | ||
| app.delete("/mcp", async (req, res) => { const sid = req.headers["mcp-session-id"]; if (sid && transports.has(sid)) | ||
| await transports.get(sid).handleRequest(req, res); | ||
| else | ||
| res.status(400).send("Invalid session"); }); | ||
| const port = Number(process.env.MCP_PORT) || 3000; | ||
| app.listen(port, () => { console.error(`MCP HTTP server on http://localhost:${port}/mcp`); }); | ||
| } | ||
| const transport = new StdioServerTransport(); | ||
| await server.connect(transport); | ||
| else { | ||
| const transport = new StdioServerTransport(); | ||
| await server.connect(transport); | ||
| } | ||
| } | ||
| main().catch(console.error); |
+6
-3
| { | ||
| "name": "@codespar/mcp-ap2", | ||
| "version": "0.1.1", | ||
| "version": "0.1.2", | ||
| "description": "MCP server for AP2 — Google's Agent-to-Agent Payment Protocol (authorization, audit, trust)", | ||
@@ -10,3 +10,5 @@ "type": "module", | ||
| }, | ||
| "files": ["dist"], | ||
| "files": [ | ||
| "dist" | ||
| ], | ||
| "scripts": { | ||
@@ -34,3 +36,4 @@ "build": "tsc", | ||
| "payment-protocol" | ||
| ] | ||
| ], | ||
| "mcpName": "io.github.codespar/mcp-ap2" | ||
| } |
+4
-0
@@ -131,4 +131,8 @@ # @codespar/mcp-ap2 | ||
| ## Enterprise | ||
| Need governance, budget limits, and audit trails for agent payments? [CodeSpar Enterprise](https://codespar.dev/enterprise) adds policy engine, payment routing, and compliance templates on top of these MCP servers. | ||
| ## License | ||
| MIT |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
28823
9.86%492
8.13%138
2.99%7
40%