agent402-mcp 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +45 -4
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -19,11 +19,16 @@
19
19
  import { createHash } from "node:crypto";
20
20
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
21
21
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
22
- import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
22
+ import {
23
+ CallToolRequestSchema,
24
+ ListToolsRequestSchema,
25
+ ListPromptsRequestSchema,
26
+ GetPromptRequestSchema,
27
+ } from "@modelcontextprotocol/sdk/types.js";
23
28
 
24
29
  const BASE = (process.env.AGENT402_URL || "https://agent402.tools").replace(/\/$/, "");
25
30
  const AGENT_KEY = process.env.AGENT_KEY || "";
26
- const VERSION = "0.4.0";
31
+ const VERSION = "0.6.0";
27
32
 
28
33
  // Spend controls — enforced BEFORE a payment is ever signed, so a confused or
29
34
  // runaway model cannot drain the wallet. Unset = unlimited (back-compat).
@@ -46,12 +51,19 @@ const log = (...a) => console.error("[agent402-mcp]", ...a);
46
51
  // ---------------------------------------------------------------------------
47
52
  // Catalog: built from the service's own machine-readable surfaces.
48
53
  const catalog = new Map(); // slug -> { slug, method, path, price, description, category, computePayable, inputSchema }
54
+ // Skill packs — curated multi-tool workflows, fetched at startup from the
55
+ // hosted service so the npm package picks up new packs without a republish.
56
+ // Empty if the discovery fetch fails (older services or transient errors);
57
+ // prompts/list will just return an empty array in that case.
58
+ let skillPacks = [];
49
59
 
50
60
  async function loadCatalog() {
51
- const [pricing, openapi] = await Promise.all([
61
+ const [pricing, openapi, packs] = await Promise.all([
52
62
  fetch(`${BASE}/api/pricing`).then((r) => r.json()),
53
63
  fetch(`${BASE}/openapi.json`).then((r) => r.json()),
64
+ fetch(`${BASE}/api/skill-packs.json`).then((r) => (r.ok ? r.json() : { packs: [] })).catch(() => ({ packs: [] })),
54
65
  ]);
66
+ skillPacks = Array.isArray(packs?.packs) ? packs.packs : [];
55
67
  for (const e of pricing.endpoints) {
56
68
  const slug = e.slug ?? e.docs?.split("/tools/").pop();
57
69
  if (!slug) continue;
@@ -209,7 +221,36 @@ function searchTools(query, limit = 10) {
209
221
 
210
222
  // ---------------------------------------------------------------------------
211
223
  // MCP wiring
212
- const server = new Server({ name: "agent402", version: VERSION }, { capabilities: { tools: {} } });
224
+ const server = new Server({ name: "agent402", version: VERSION }, { capabilities: { tools: {}, prompts: {} } });
225
+
226
+ // Skill packs are exposed as MCP prompts — discoverable in slash menus on any
227
+ // MCP-aware client. The list is fetched once at boot in loadCatalog(); the
228
+ // per-prompt rendering is delegated to the hosted service so the npm package
229
+ // stays thin and prompt text stays canonical with the website at /skills.
230
+ server.setRequestHandler(ListPromptsRequestSchema, async () => ({
231
+ prompts: skillPacks.map((p) => ({
232
+ name: p.slug,
233
+ title: p.title,
234
+ description: p.tagline,
235
+ arguments: (p.promptArgs || []).map((a) => ({
236
+ name: a.name,
237
+ description: a.description,
238
+ required: a.required ?? true,
239
+ })),
240
+ })),
241
+ }));
242
+ server.setRequestHandler(GetPromptRequestSchema, async (req) => {
243
+ const { name, arguments: args = {} } = req.params;
244
+ const pack = skillPacks.find((p) => p.slug === name);
245
+ if (!pack) throw new Error(`Unknown prompt "${name}". List available with prompts/list.`);
246
+ const url = new URL(`${BASE}/api/skill-packs/${encodeURIComponent(name)}/prompt`);
247
+ for (const [k, v] of Object.entries(args || {})) {
248
+ if (v !== undefined && v !== null && v !== "") url.searchParams.set(k, String(v));
249
+ }
250
+ const res = await fetch(url);
251
+ if (!res.ok) throw new Error(`Failed to render prompt "${name}" from ${BASE}: HTTP ${res.status}`);
252
+ return await res.json();
253
+ });
213
254
 
214
255
  let curated = [];
215
256
  let pricingInfo = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent402-mcp",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "mcpName": "io.github.MikeyPetrillo/agent402",
5
5
  "author": "Mikey Petrillo (https://github.com/MikeyPetrillo)",
6
6
  "homepage": "https://agent402.tools",