agent402-mcp 0.13.11 → 0.13.12
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.
- package/README.md +1 -1
- package/index.js +24 -24
- package/networks.js +5 -5
- package/output-schemas.js +13 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
MCP server for [Agent402](https://agent402.tools), the applied layer of [Agentic Finance](https://agent402.tools/agentic-finance) - a catalog of **500+ pay-per-call web tools and curated multi-tool skill packs** for AI agents, paid per call in USDC via the [x402 protocol](https://www.x402.org), **with compute (proof-of-work)** when no wallet is configured, or through a prepaid credits key already issued. (The hosted API is dual-stack: it also accepts [MPP](https://agent402.tools/what-is-mpp) clients on the same 402, settling on Base/Celo or natively on Tempo; this package pays via x402 or credits.) Built by [Havok Holdings LLC](https://github.com/MikeyPetrillo/Agent402).
|
|
4
4
|
|
|
5
|
-
Your agent gets browser rendering, screenshots, PDF text extraction, URL→markdown, live web search **+ web answers with citations**, live **financial/crypto/macro data** (US equity quotes and daily bars from
|
|
5
|
+
Your agent gets browser rendering, screenshots, PDF text extraction, URL→markdown, live web search **+ web answers with citations**, live **financial/crypto/macro data** (US equity quotes and daily bars from a licensed feed, CoinGecko, FRED, ECB FX, World Bank, yield curve), **SEC EDGAR filings** (10-K/10-Q text, XBRL, insider, 13F, IPO calendar), **deterministic stats & forecasting** (Pearson correlation, OLS, Holt-Winters), **compression** (gzip/brotli), DNS/TLS/WHOIS + email-deliverability checks, wallet-keyed shared memory, and the pure-CPU utilities - plus **skill packs** like `security-audit`, `trend-analysis`, `structured-scrape`, `decode-blob`, and `forecasting-bake-off` callable as MCP prompts, and the **report products** (deep research, company dossier, 13F fund report, domain audit, token risk, FDA recall, insider flow, market brief) as ordinary catalog slugs. Payment handled invisibly underneath the MCP calls. No signup, no API key.
|
|
6
6
|
|
|
7
7
|
## Quick start
|
|
8
8
|
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// Agent402 MCP server
|
|
2
|
+
// Agent402 MCP server, exposes the agent402.tools catalog (1000+ pay-per-call
|
|
3
3
|
// web tools) to any MCP client (Claude, ChatGPT, custom agents) and settles
|
|
4
4
|
// payment underneath, so the model never sees the 402 dance:
|
|
5
5
|
//
|
|
@@ -13,15 +13,15 @@
|
|
|
13
13
|
//
|
|
14
14
|
// Config (env):
|
|
15
15
|
// AGENT402_URL target service (default https://agent402.tools)
|
|
16
|
-
// AGENT_KEY hex private key of a funded EVM wallet (USDC on Base/Polygon/Arbitrum)
|
|
17
|
-
// SOLANA_AGENT_KEY base58 (or JSON byte-array) secret key of a funded Solana wallet (USDC on Solana)
|
|
16
|
+
// AGENT_KEY hex private key of a funded EVM wallet (USDC on Base/Polygon/Arbitrum), optional
|
|
17
|
+
// SOLANA_AGENT_KEY base58 (or JSON byte-array) secret key of a funded Solana wallet (USDC on Solana), optional
|
|
18
18
|
// AGENT402_TOOLS comma-separated slugs to expose first-class (overrides default)
|
|
19
19
|
// AGENT402_MAX_PER_CALL refuse any single call priced above this many USD (e.g. 0.01)
|
|
20
20
|
// AGENT402_CREDITS_KEY a prepaid credits key (a402_...) already issued (new credits are not on
|
|
21
21
|
// sale); pays per successful call with no wallet
|
|
22
22
|
// AGENT402_BUDGET hard cap on total USDC spent this session (e.g. 1.00)
|
|
23
23
|
// AGENT402_NETWORKS restrict + order the chains to pay on (e.g. "robinhood" for USDG on
|
|
24
|
-
// Robinhood Chain, "base,solana", or a raw CAIP-2 like eip155:4663)
|
|
24
|
+
// Robinhood Chain, "base,solana", or a raw CAIP-2 like eip155:4663), optional
|
|
25
25
|
import { createHash } from "node:crypto";
|
|
26
26
|
import { readFileSync } from "node:fs";
|
|
27
27
|
import { parseNetworkPrefs, withNetworkPreference } from "./networks.js";
|
|
@@ -58,12 +58,12 @@ const HAS_WALLET = Boolean(AGENT_KEY || SOLANA_AGENT_KEY);
|
|
|
58
58
|
// list price only on a successful (200) call and returns X-Credits-Balance.
|
|
59
59
|
const CREDITS_KEY = (process.env.AGENT402_CREDITS_KEY || "").trim();
|
|
60
60
|
const HAS_CREDITS = /^a402_[A-Za-z0-9_-]{32,64}$/.test(CREDITS_KEY);
|
|
61
|
-
// Version comes from package.json
|
|
61
|
+
// Version comes from package.json, the serverInfo self-report drifted from
|
|
62
62
|
// the published version once (0.11.5 vs 0.12.1) because this was a hardcoded
|
|
63
63
|
// string bumped by hand. Reading the manifest makes drift impossible.
|
|
64
64
|
const VERSION = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8")).version;
|
|
65
65
|
|
|
66
|
-
// Spend controls
|
|
66
|
+
// Spend controls, enforced BEFORE a payment is ever signed, so a confused or
|
|
67
67
|
// runaway model cannot drain the wallet. Unset = unlimited (back-compat).
|
|
68
68
|
const num = (v) => (v !== undefined && v !== "" && Number.isFinite(Number(v)) ? Number(v) : undefined);
|
|
69
69
|
const MAX_PER_CALL = num(process.env.AGENT402_MAX_PER_CALL) ?? Infinity;
|
|
@@ -71,7 +71,7 @@ const BUDGET = num(process.env.AGENT402_BUDGET) ?? Infinity;
|
|
|
71
71
|
let spentUsd = 0;
|
|
72
72
|
|
|
73
73
|
const DEFAULT_CURATED = [
|
|
74
|
-
// Flagship demand set
|
|
74
|
+
// Flagship demand set, keep aligned with src/mcp-flagship.js FLAGSHIP_SLUGS.
|
|
75
75
|
// Search/answer is the front door; long tail stays behind catalog.search/catalog.call.
|
|
76
76
|
"search", "answer", "search-news", "render",
|
|
77
77
|
"stock-quote", "transcribe", "memory-read", "memory-write",
|
|
@@ -79,13 +79,13 @@ const DEFAULT_CURATED = [
|
|
|
79
79
|
"decide", "decide-execute",
|
|
80
80
|
];
|
|
81
81
|
|
|
82
|
-
// stdout is the MCP protocol channel
|
|
82
|
+
// stdout is the MCP protocol channel, all logging goes to stderr.
|
|
83
83
|
const log = (...a) => console.error("[agent402-mcp]", ...a);
|
|
84
84
|
|
|
85
85
|
// ---------------------------------------------------------------------------
|
|
86
86
|
// Catalog: built from the service's own machine-readable surfaces.
|
|
87
87
|
const catalog = new Map(); // slug -> { slug, method, path, price, description, category, computePayable, inputSchema }
|
|
88
|
-
// Skill packs
|
|
88
|
+
// Skill packs, curated multi-tool workflows, fetched at startup from the
|
|
89
89
|
// hosted service so the npm package picks up new packs without a republish.
|
|
90
90
|
// Empty if the discovery fetch fails (older services or transient errors);
|
|
91
91
|
// prompts/list will just return an empty array in that case.
|
|
@@ -162,7 +162,7 @@ function getPayFetch() {
|
|
|
162
162
|
return payFetchPromise;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
// @solana/kit KeyPairSigner from SOLANA_AGENT_KEY
|
|
165
|
+
// @solana/kit KeyPairSigner from SOLANA_AGENT_KEY, base58 64-byte secret key
|
|
166
166
|
// (Phantom / solana-keygen export) or a JSON byte array ([12,34,…]).
|
|
167
167
|
let solanaSignerPromise;
|
|
168
168
|
function solanaSigner() {
|
|
@@ -197,7 +197,7 @@ function walletRequiredText(tool) {
|
|
|
197
197
|
`"${tool.slug}" costs ${tool.price}/call and requires a USDC wallet (it is not eligible for the proof-of-work tier).`,
|
|
198
198
|
`To enable it: set AGENT_KEY on this MCP server to the hex private key of an EVM wallet funded with USDC`,
|
|
199
199
|
`on Base (or Polygon/Arbitrum), and/or SOLANA_AGENT_KEY to the base58 secret key of a Solana wallet funded`,
|
|
200
|
-
`with USDC on Solana. Payment is per call via the x402 protocol
|
|
200
|
+
`with USDC on Solana. Payment is per call via the x402 protocol: no signup or API key.`,
|
|
201
201
|
`Already hold a prepaid credits key? Set AGENT402_CREDITS_KEY to the a402_ key and it pays per successful call (new credits are not on sale).`,
|
|
202
202
|
`Pricing and details: ${BASE}/tools/${tool.slug}`,
|
|
203
203
|
].join(" ");
|
|
@@ -340,10 +340,10 @@ async function callEndpoint(tool, args = {}) {
|
|
|
340
340
|
const payFetch = await getPayFetch();
|
|
341
341
|
res = await payFetch(url, init);
|
|
342
342
|
// Count spend when the server confirms settlement (payment receipt header),
|
|
343
|
-
// falling back to any 2xx
|
|
343
|
+
// falling back to any 2xx, conservative in the buyer's favor.
|
|
344
344
|
if (res.headers.get("payment-response") || res.headers.get("x-payment-response") || res.ok) spentUsd += price;
|
|
345
345
|
} else if (tool.computePayable) {
|
|
346
|
-
// No wallet: pay with compute up front
|
|
346
|
+
// No wallet: pay with compute up front, solving before the call skips the
|
|
347
347
|
// 402 round-trip entirely (challenges are single-use and tool-scoped).
|
|
348
348
|
const challenge = await (await fetch(`${BASE}/api/pow/challenge?slug=${encodeURIComponent(tool.slug)}`)).json();
|
|
349
349
|
const nonce = solvePow(challenge);
|
|
@@ -382,7 +382,7 @@ function applyFrontDoorTerms(terms, q) {
|
|
|
382
382
|
if (!terms.includes("websearch") && (
|
|
383
383
|
/\b(search\s+the\s+web|web\s+search|search\s+online|google\s+|bing\s+|look\s+up\s+online|find\s+on\s+the\s+web)\b/.test(ql)
|
|
384
384
|
)) {
|
|
385
|
-
// pricing descriptions carry "web search" / "Live web search"
|
|
385
|
+
// pricing descriptions carry "web search" / "Live web search", boost those.
|
|
386
386
|
terms.push("web", "search");
|
|
387
387
|
}
|
|
388
388
|
if (!terms.includes("answer") && (
|
|
@@ -427,8 +427,8 @@ function searchTools(query, limit = 10) {
|
|
|
427
427
|
|
|
428
428
|
// Rank the curated multi-tool skill packs against the same query, so a single
|
|
429
429
|
// search_tools call also tells the agent "this looks like a `security-audit`
|
|
430
|
-
// or `email-deliverability` job
|
|
431
|
-
// Weighted slug/title/tagline/useCase/toolSlugs match
|
|
430
|
+
// or `email-deliverability` job, fetch the whole template via prompts/get".
|
|
431
|
+
// Weighted slug/title/tagline/useCase/toolSlugs match, same shape as the
|
|
432
432
|
// hosted /api/find ranking, kept inline here so the stdio package stays
|
|
433
433
|
// dependency-free. Returns [] when no pack scores above the noise floor.
|
|
434
434
|
function rankWorkflows(query, k = 2) {
|
|
@@ -482,7 +482,7 @@ const server = new Server(
|
|
|
482
482
|
{ capabilities: { tools: {}, prompts: {} }, instructions: INIT_INSTRUCTIONS },
|
|
483
483
|
);
|
|
484
484
|
|
|
485
|
-
// Skill packs are exposed as MCP prompts
|
|
485
|
+
// Skill packs are exposed as MCP prompts, discoverable in slash menus on any
|
|
486
486
|
// MCP-aware client. The list is fetched once at boot in loadCatalog(); the
|
|
487
487
|
// per-prompt rendering is delegated to the hosted service so the npm package
|
|
488
488
|
// stays thin and prompt text stays canonical with the website at /skills.
|
|
@@ -816,7 +816,7 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
816
816
|
const include = args.include === "all" ? "all" : "external";
|
|
817
817
|
// /api/leaderboard is free + unpaywalled, so this stays free regardless
|
|
818
818
|
// of payment mode. Honor its query params verbatim so the surface is a
|
|
819
|
-
// thin pass-through
|
|
819
|
+
// thin pass-through, single source of truth for ranking + filtering.
|
|
820
820
|
const url = new URL(`${BASE}/api/leaderboard`);
|
|
821
821
|
url.searchParams.set("top", String(limit));
|
|
822
822
|
url.searchParams.set("sort", sort);
|
|
@@ -826,7 +826,7 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
826
826
|
return { content: [{ type: "text", text: `Failed to fetch leaderboard from ${BASE}: HTTP ${res.status}` }], isError: true };
|
|
827
827
|
}
|
|
828
828
|
const snap = await res.json();
|
|
829
|
-
// Trim to the same compact row shape the hosted MCP connector returns
|
|
829
|
+
// Trim to the same compact row shape the hosted MCP connector returns,
|
|
830
830
|
// cross-surface agents see one mental model. Full row (origins,
|
|
831
831
|
// endpoints, scan metadata) stays accessible at /api/leaderboard.
|
|
832
832
|
// Same untrusted-content marking as the hosted connector: a seller's
|
|
@@ -851,7 +851,7 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
851
851
|
include: snap.include || include,
|
|
852
852
|
totalSellers: snap.totalSellers ?? (snap.leaderboard || []).length,
|
|
853
853
|
results: rows,
|
|
854
|
-
...(snap.warming || snap.scanSkipped ? { note: "Cache is warming
|
|
854
|
+
...(snap.warming || snap.scanSkipped ? { note: "Cache is warming: results may be partial. Retry in ~60s." } : {}),
|
|
855
855
|
source: `${BASE}/api/leaderboard`,
|
|
856
856
|
});
|
|
857
857
|
}
|
|
@@ -867,13 +867,13 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
867
867
|
: maxUsd > 0.005 ? "route-execute-plus"
|
|
868
868
|
: "route-execute";
|
|
869
869
|
const tool = catalog.get(slug);
|
|
870
|
-
if (!tool) return { content: [{ type: "text", text: `External routing (${slug}) is not in the catalog from ${BASE} yet
|
|
870
|
+
if (!tool) return { content: [{ type: "text", text: `External routing (${slug}) is not in the catalog from ${BASE} yet. It may be rolling out; retry shortly.` }], isError: true };
|
|
871
871
|
// Body matches the route-execute input schema; include:"external" is what
|
|
872
872
|
// pays an OUTSIDE seller (vs this host's catalog). Paid via callEndpoint.
|
|
873
873
|
return await callEndpoint(tool, { task, include: "external", maxUsd, ...(args.params && typeof args.params === "object" ? { params: args.params } : {}) });
|
|
874
874
|
}
|
|
875
875
|
// Curated tools are exposed verb_noun for tools/list consistency, but the
|
|
876
|
-
// real slug is kebab
|
|
876
|
+
// real slug is kebab, accept exposed name, plain snake, or raw slug.
|
|
877
877
|
const mcpToSlug = new Map(Object.entries(FLAGSHIP_MCP_NAMES).map(([slug, mcp]) => [mcp, slug]));
|
|
878
878
|
const wanted = name === "catalog.call"
|
|
879
879
|
? String(args.slug ?? "")
|
|
@@ -903,11 +903,11 @@ try {
|
|
|
903
903
|
pricingInfo = await loadCatalog();
|
|
904
904
|
} catch (err) {
|
|
905
905
|
// Don't hard-exit: starting with an empty catalog still lets the server
|
|
906
|
-
// connect and answer introspection (tools/list)
|
|
906
|
+
// connect and answer introspection (tools/list), required to pass directory
|
|
907
907
|
// health checks (e.g. Glama) and more resilient if the catalog endpoint is
|
|
908
908
|
// briefly unreachable. catalog.search/catalog.call just return nothing until the
|
|
909
909
|
// catalog is reachable again.
|
|
910
|
-
log(`Could not load the catalog from ${BASE}: ${err.message}
|
|
910
|
+
log(`Could not load the catalog from ${BASE}: ${err.message}: starting with an empty catalog`);
|
|
911
911
|
}
|
|
912
912
|
const requested = (process.env.AGENT402_TOOLS || DEFAULT_CURATED.join(","))
|
|
913
913
|
.split(",").map((s) => s.trim()).filter(Boolean);
|
package/networks.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
// Network preference for the x402 buyer
|
|
1
|
+
// Network preference for the x402 buyer, pure helpers, no side effects.
|
|
2
2
|
//
|
|
3
3
|
// AGENT402_NETWORKS (comma-separated, e.g. "robinhood" or "base,solana" or a
|
|
4
4
|
// raw CAIP-2 like "eip155:4663") restricts AND orders which payment options
|
|
5
5
|
// the buyer will consider from a seller's 402 `accepts`. Without it the
|
|
6
|
-
// underlying @x402 client picks whichever registered scheme matches first
|
|
6
|
+
// underlying @x402 client picks whichever registered scheme matches first,
|
|
7
7
|
// which on a multi-chain seller is effectively always Base, making rails like
|
|
8
8
|
// USDG on Robinhood Chain unreachable no matter what the wallet holds.
|
|
9
9
|
|
|
@@ -30,7 +30,7 @@ export function parseNetworkPrefs(raw) {
|
|
|
30
30
|
|
|
31
31
|
/** Filter a 402's accepts to the preferred networks, ordered by preference
|
|
32
32
|
* (all accepts for the 1st preferred chain, then the 2nd, …). Throws with an
|
|
33
|
-
* actionable message when nothing matches
|
|
33
|
+
* actionable message when nothing matches, better than silently paying on a
|
|
34
34
|
* chain the operator excluded. No prefs → accepts unchanged. */
|
|
35
35
|
export function filterAcceptsByNetworks(accepts, prefs) {
|
|
36
36
|
if (!prefs?.length) return accepts;
|
|
@@ -39,14 +39,14 @@ export function filterAcceptsByNetworks(accepts, prefs) {
|
|
|
39
39
|
if (!picked.length) {
|
|
40
40
|
const offered = [...new Set(list.map((a) => a?.network).filter(Boolean))];
|
|
41
41
|
throw new Error(
|
|
42
|
-
`AGENT402_NETWORKS matched none of the seller's payment options
|
|
42
|
+
`AGENT402_NETWORKS matched none of the seller's payment options: wanted [${prefs.join(", ")}], offered [${offered.join(", ")}]. ` +
|
|
43
43
|
"Remove the restriction or add one of the offered networks."
|
|
44
44
|
);
|
|
45
45
|
}
|
|
46
46
|
return picked;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
/** Apply the preference to an @x402 client (duck-typed
|
|
49
|
+
/** Apply the preference to an @x402 client (duck-typed, any version with
|
|
50
50
|
* createPaymentPayload works): the client only ever sees the filtered,
|
|
51
51
|
* preference-ordered accepts. Returns the same client for chaining. */
|
|
52
52
|
export function withNetworkPreference(client, prefs) {
|
package/output-schemas.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// (stdio package cannot import src/ when published). Keep in sync manually
|
|
3
3
|
// when flagship names or output schemas change.
|
|
4
4
|
|
|
5
|
-
// Flagship MCP surface
|
|
5
|
+
// Flagship MCP surface, the small default tools/list agents see first.
|
|
6
6
|
//
|
|
7
7
|
// Product intent: Agent402 is a tools and models layer for agents -
|
|
8
8
|
// deterministic utilities, a metered model gateway, finished reports. Default
|
|
@@ -26,7 +26,7 @@ export const FLAGSHIP_SLUGS = [
|
|
|
26
26
|
"memory-write",
|
|
27
27
|
];
|
|
28
28
|
|
|
29
|
-
// Smithery Naming grades DOT notation (domain.action tree), not snake_case
|
|
29
|
+
// Smithery Naming grades DOT notation (domain.action tree), not snake_case,
|
|
30
30
|
// stuck-at-98 lesson: "Tool names should form a navigable tree using
|
|
31
31
|
// dot-notation (e.g. admin.tools.list)". CallTool still accepts prior snake /
|
|
32
32
|
// digit names via MCP_CALL_ALIASES.
|
|
@@ -43,7 +43,7 @@ export const FLAGSHIP_MCP_NAMES = {
|
|
|
43
43
|
"decide-execute": "decide.execute",
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
-
/** Meta tools listed alongside flagships
|
|
46
|
+
/** Meta tools listed alongside flagships, dotted canonical names. */
|
|
47
47
|
export const META_MCP_NAMES = {
|
|
48
48
|
search_tools: "catalog.search",
|
|
49
49
|
find_tool: "catalog.find",
|
|
@@ -92,7 +92,7 @@ export function resolveListedName(name) {
|
|
|
92
92
|
return name;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
/** Open-world / egress tools
|
|
95
|
+
/** Open-world / egress tools, honest annotations for directory clients. */
|
|
96
96
|
export const FLAGSHIP_OPEN_WORLD = new Set([
|
|
97
97
|
"search", "answer", "search-news", "render", "stock-quote", "transcribe", "decide",
|
|
98
98
|
]);
|
|
@@ -108,7 +108,7 @@ export const MCP_SERVER_DESCRIPTION =
|
|
|
108
108
|
export const MCP_SERVER_WEBSITE = "https://agent402.tools";
|
|
109
109
|
|
|
110
110
|
// ---------------------------------------------------------------------------
|
|
111
|
-
// outputSchema (JSON Schema) for every listed tool
|
|
111
|
+
// outputSchema (JSON Schema) for every listed tool, Smithery Capability
|
|
112
112
|
// Quality grades presence of named-field schemas; bare {type:"object"} does
|
|
113
113
|
// not count. Keep in sync with CallTool structuredContent shapes in mcp-http.js
|
|
114
114
|
// and the duplicated copy in mcp/output-schemas.js (stdio package).
|
|
@@ -225,7 +225,7 @@ export const META_OUTPUT_SCHEMAS = {
|
|
|
225
225
|
},
|
|
226
226
|
additionalProperties: true,
|
|
227
227
|
},
|
|
228
|
-
// Smithery Naming wants pure [a-z_]+ verb_noun
|
|
228
|
+
// Smithery Naming wants pure [a-z_]+ verb_noun, no digits / brand tokens
|
|
229
229
|
// (describe_agent402 / list_x402_sellers failed the scan). Old names stay
|
|
230
230
|
// CallTool aliases.
|
|
231
231
|
"server.describe": {
|
|
@@ -496,17 +496,17 @@ export function mcpInstallHints(baseUrl) {
|
|
|
496
496
|
},
|
|
497
497
|
},
|
|
498
498
|
npm: "npx -y agent402-mcp",
|
|
499
|
-
smithery:
|
|
499
|
+
smithery: `Paste ${hosted} into the add-server form at https://smithery.ai/new. Submission is external; Agent402 does not auto-publish.`,
|
|
500
500
|
maintainer: "Havok Holdings LLC",
|
|
501
501
|
};
|
|
502
502
|
}
|
|
503
503
|
|
|
504
504
|
/**
|
|
505
|
-
* MCP initialize.instructions
|
|
505
|
+
* MCP initialize.instructions, orientation for clients that never call
|
|
506
506
|
* server.describe. Keep tool names listed-only (dotted Smithery form) (self-consistency) and lead
|
|
507
507
|
* with search/answer as the front door.
|
|
508
508
|
*/
|
|
509
|
-
export function mcpInitializeInstructions(baseUrl, { decide = false } = {}) {
|
|
509
|
+
export function mcpInitializeInstructions(baseUrl, { decide = false, mpp = false } = {}) {
|
|
510
510
|
const install = mcpInstallHints(baseUrl);
|
|
511
511
|
const hosted = install.hostedUrl;
|
|
512
512
|
return [
|
|
@@ -520,9 +520,11 @@ export function mcpInitializeInstructions(baseUrl, { decide = false } = {}) {
|
|
|
520
520
|
"Orientation: call server.describe. Payment rails / wallet setup: call payment.info.",
|
|
521
521
|
"Missing a tool: call demand.request. Ecosystem sellers: call sellers.list.",
|
|
522
522
|
`Install (npm + wallet, pays for web.search, web.answer and the rest): ${install.claudeCodeNpm}`,
|
|
523
|
-
|
|
523
|
+
// The hosted line says what that connector takes: with MPP on it, a wallet
|
|
524
|
+
// can pay the other tools there too.
|
|
525
|
+
`${mpp ? "Hosted (proof-of-work tools free; the rest payable there over MPP from a wallet)" : "No wallet yet (hosted, proof-of-work tools only)"}: ${install.claudeCodeHosted}`,
|
|
524
526
|
`Cursor mcp.json: { "mcpServers": { "agent402": { "url": "${hosted}" } } }`,
|
|
525
|
-
`Why pay here (usage priced under a quoted ceiling, a failed call is not charged and the receipt proves it, keyed retries never pay twice, one key for tools + models + reports, no wallet needed for the proof-of-work tools or a report by card, proof at /status and /revenue): ${baseUrl}
|
|
527
|
+
`Why pay here (usage priced under a quoted ceiling, a failed call is not charged and the receipt proves it, keyed retries never pay twice, one key for tools + models + reports, no wallet needed for the proof-of-work tools or a report by card, proof at /status and /revenue): ${baseUrl}/#why`,
|
|
526
528
|
`Docs: ${baseUrl}/llms.txt · ${baseUrl}/api/find?q=… · status ${baseUrl}/status`,
|
|
527
529
|
].join("\n");
|
|
528
530
|
}
|
package/package.json
CHANGED