toll402-mcp 0.4.1 → 0.5.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.
- package/README.md +60 -1
- package/dist/mcp.js +34 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,10 +11,69 @@ Env: `TOLL402_URL` (default https://toll402.dev) · `TOLL402_WALLET_KEY` (0x pri
|
|
|
11
11
|
Claude Code / Cursor / Claude Desktop / OpenClaw:
|
|
12
12
|
```json
|
|
13
13
|
{ "mcpServers": { "toll402": { "command": "npx", "args": ["-y", "toll402-mcp"], "env": { "TOLL402_API_KEY": "tk_..." } } } }
|
|
14
|
-
// or with a wallet: "env": { "TOLL402_WALLET_KEY": "0x...", "TOLL402_MAX_USD": "0.25" }
|
|
15
14
|
```
|
|
15
|
+
Or with a wallet (x402):
|
|
16
|
+
```json
|
|
17
|
+
{ "mcpServers": { "toll402": { "command": "npx", "args": ["-y", "toll402-mcp"], "env": { "TOLL402_WALLET_KEY": "0x...", "TOLL402_MAX_USD": "0.25" } } } }
|
|
18
|
+
```
|
|
19
|
+
Remote, no install: `https://toll402.dev/mcp` (send `x-toll402-key` as a header, `?key=tk_…` in the URL for clients without headers, or x402 headers). Per-client setup for Claude Code, Cursor, Codex, ChatGPT, Windsurf, VS Code, Gemini CLI, Hermes, OpenClaw and more: https://toll402.dev/#connect
|
|
20
|
+
|
|
16
21
|
You are charged only when a call succeeds (2xx). Catalog and prices: https://toll402.dev/v1/catalog · Docs for agents: https://toll402.dev/llms.txt
|
|
17
22
|
|
|
23
|
+
## Tools
|
|
24
|
+
|
|
25
|
+
16 first-party tools, 167 community-forged tools and 2,466 provider API endpoints, all exposed as MCP tools (the provider endpoints through `find` and `do`). Prices are per call; charged only on success.
|
|
26
|
+
|
|
27
|
+
### Account tools (free, need `TOLL402_API_KEY`)
|
|
28
|
+
|
|
29
|
+
- **toll402_review**: rate a paid call you just used (`callId`, `useful`, optional `reason`). Reviews move tool ranking for every agent.
|
|
30
|
+
- **toll402_job**: check an image or video generation task by `jobId`; returns the result URLs when done. Failed tasks are refunded.
|
|
31
|
+
- **toll402_history**: this key's recent paid calls with cost, input summary and links to the stored answers (24 h).
|
|
32
|
+
|
|
33
|
+
### First-party
|
|
34
|
+
|
|
35
|
+
- **read_url** ($0.002): Fetch any public web page (or PDF) and return clean, LLM-ready Markdown with title, metadata and links.
|
|
36
|
+
- **pdf_to_text** ($0.005): Download a PDF from a URL and return its full text, page count and title.
|
|
37
|
+
- **verify_email** ($0.001): Validate an email address: syntax, MX/A records, disposable-domain, free-provider and role-account detection, with a 0-100 score.
|
|
38
|
+
- **fx_rate** ($0.001): Exchange rate between two ISO currencies (ECB reference rates), optionally converting an amount.
|
|
39
|
+
- **extract_structured** ($0.06): Turn a web page or raw text into JSON that matches YOUR JSON Schema.
|
|
40
|
+
- **summarize** ($0.05): Faithful summary of a URL or text in the style, length and language you choose.
|
|
41
|
+
- **judge_output** ($0.07): Independent LLM-as-judge: scores a candidate output against a task and criteria (0-100), with pass/fail, issues and suggestions.
|
|
42
|
+
- **provenance** ($0.01): Human or synthetic? Provenance evidence for a URL: archive first-capture date, domain age, authorship markup, curated source tier, AI disclosures and stylometric signals, aggregated into a calibrated 0-100 human-origin score with every piece of evidence.
|
|
43
|
+
- **trusted_lookup** ($0.01): Answer from TRUSTED sources only (Wikipedia, Wikidata, arXiv, Crossref/DOI, World Bank): returns passages with URL, reliability tier and retrieval time for citation.
|
|
44
|
+
- **business_search** ($0.005): Global business directory for agents (any city in the world; unknown cities are seeded on demand).
|
|
45
|
+
- **business_verify** ($0.01): Is this business real, and is its contact info live? Give an id, website, phone or name: matches it against the directory and runs live checks now (site up, name on site, phone on site, domain age, phone format).
|
|
46
|
+
- **business_details** ($0.08): Deep profile of a business from its OWN website: crawls up to 5 relevant pages (menu, services, prices, hours, contact, booking) and returns a machine-readable profile — summary, hours (OSM syntax), services with prices, booking channels, payments, languages, social links.
|
|
47
|
+
- **business_shortlist** ($0.25): Sourcing for agents whose principal is launching or buying something: describe the need ("opening a coffee brand in Monterrey, need packaging suppliers and a designer") and get a ranked shortlist of real businesses with a reason, fit score, best contact channel, staff size from official registries, verification level and website summary when curated.
|
|
48
|
+
- **list_service** ($1): Buy a verified listing for YOUR x402 endpoint, remote MCP server or A2A agent — paid by the agent in USDC, no humans.
|
|
49
|
+
- **forge_tool** ($0.25): Create a NEW tool from a description, an input schema and test examples.
|
|
50
|
+
- **do** ($0.02): One endpoint for everything (OpenRouter-style): describe what you need and pass the input; Toll402 picks the best tool from the whole catalog (built-in, community-forged, external x402 services) and runs it.
|
|
51
|
+
|
|
52
|
+
### Community-forged (sample)
|
|
53
|
+
|
|
54
|
+
- **github_repo_stats** ($0.003): Stars, forks, open issues, license and last push for a GitHub repo via https://api.github.com/repos/<owner>/<repo>.
|
|
55
|
+
- **ip_geolocate** ($0.002): Country, region, city, timezone and ASN for an IPv4/IPv6 address via https://ipapi.co/<ip>/json/.
|
|
56
|
+
- **hn_top** ($0.005): Top N Hacker News stories (title, url, score) via https://hacker-news.firebaseio.com/v0/topstories.json and /v0/item/<id>.json.
|
|
57
|
+
- **rss_latest** ($0.003): Parse an RSS/Atom feed URL and return the latest N items (title, link, published).
|
|
58
|
+
- **npm_package_info** ($0.003): Latest version, description, license, weekly downloads (via api.npmjs.org) and homepage for an npm package.
|
|
59
|
+
- **text_stats** ($0.001): Word/sentence/paragraph counts, reading time (200 wpm), top 10 keywords (stopwords removed) for a text.
|
|
60
|
+
- **url_status** ($0.001): HTTP status, final content-type and response size for a URL (HEAD then GET fallback).
|
|
61
|
+
- **wikipedia_summary** ($0.002): Summary extract and canonical URL for a Wikipedia topic via https://<lang>.wikipedia.org/api/rest_v1/page/summary/<title>.
|
|
62
|
+
- **json_schema_validate** ($0.001): Validate a JSON value against a JSON Schema subset (type, properties, required, enum, minimum/maximum, minLength/maxLength, items) and retur.
|
|
63
|
+
- **crypto_price** ($0.002): Spot price in USD for a crypto asset symbol using https://api.coinbase.com/v2/prices/<SYMBOL>-USD/spot.
|
|
64
|
+
- **jsonld_extract** ($0.003): Fetches a public URL, extracts all <script type="application/ld+json"> blocks, parses them as JSON, and returns the parsed objects along wit.
|
|
65
|
+
- **mst_vn_validate** ($0.001): Offline structural validator for a Vietnamese Enterprise/Tax Code (Mã số thuế, MST).
|
|
66
|
+
- **partita_iva_validate** ($0.001): Offline validator for an Italian Partita IVA (VAT number): verifies the value is 11 numeric digits and recomputes the Luhn-like check digit .
|
|
67
|
+
- **pan_in_validate** ($0.001): Offline validator for an Indian PAN (Permanent Account Number): normalizes input to uppercase, checks the 10-character AAAAA9999A pattern, a.
|
|
68
|
+
- **siren_validate** ($0.001): Offline validator for a French SIREN (9-digit business identifier).
|
|
69
|
+
- **cin_in_validate** ($0.001): Offline structural validator for an Indian CIN (Corporate Identity Number, 21 characters).
|
|
70
|
+
- **vat_fr_validate** ($0.001): Offline validator for a French VAT number (TVA intracommunautaire, e.g.
|
|
71
|
+
- **cpr_dk_validate** ($0.001): Offline validator/normalizer for a Danish CPR-nummer (personal identification number, format DDMMYY-SSSS).
|
|
72
|
+
- **cvr_dk_validate** ($0.001): Offline validator for a Danish CVR-nummer (8-digit business registration number issued by the Danish Business Authority).
|
|
73
|
+
- **rrn_be_validate** ($0.001): Offline validator for a Belgian National Register Number (Rijksregisternummer / Numéro de registre national), format YYMMDDXXXCC.
|
|
74
|
+
|
|
75
|
+
…and 147 more forged tools plus 2,466 provider API endpoints (SEO, social, enrichment, ads, market data, AI generation): browse at https://toll402.dev/catalog or call `find` with what you need.
|
|
76
|
+
|
|
18
77
|
## Get listed (paid listings, agent-native)
|
|
19
78
|
|
|
20
79
|
Own an x402 endpoint, a remote MCP server or an A2A agent? Buy a verified listing (x402 or credits). No humans, no forms:
|
package/dist/mcp.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* TOLL402_URL base URL of the Toll402 server (default https://toll402.dev)
|
|
8
8
|
* TOLL402_WALLET_KEY 0x-prefixed EVM private key holding USDC on Base (omit for free instances)
|
|
9
9
|
* TOLL402_MAX_USD max USD per single payment (default 0.25)
|
|
10
|
+
* TOLL402_API_KEY prepaid-credits key (tk_…) instead of a wallet; enables toll402_review, toll402_job, toll402_history
|
|
10
11
|
*/
|
|
11
12
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
12
13
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -38,21 +39,38 @@ async function main() {
|
|
|
38
39
|
else {
|
|
39
40
|
console.error("toll402-mcp: TOLL402_WALLET_KEY not set — calls will fail with 402 unless the server is free");
|
|
40
41
|
}
|
|
41
|
-
const server = new Server({ name: "toll402", version: "0.
|
|
42
|
+
const server = new Server({ name: "toll402", version: "0.5.0" }, { capabilities: { tools: {} }, instructions: INSTRUCTIONS });
|
|
43
|
+
const META = [
|
|
44
|
+
{ name: "toll402_review", description: "Rate a paid Toll402 call you just used: was the answer useful? Reviews move tool ranking for every agent. Free. Needs TOLL402_API_KEY.", inputSchema: { type: "object", properties: { callId: { type: "number", description: "The call id shown after a charged call" }, useful: { type: "boolean" }, reason: { type: "string" } }, required: ["callId", "useful"] } },
|
|
45
|
+
{ name: "toll402_job", description: "Check an async Toll402 task (image or video generation) by job id: status, and result URLs when done. Free. Poll every 30-60 s.", inputSchema: { type: "object", properties: { jobId: { type: "string" } }, required: ["jobId"] } },
|
|
46
|
+
{ name: "toll402_history", description: "Recent paid Toll402 calls of this key with cost, input summary and links to stored answers (24 h). Free.", inputSchema: { type: "object", properties: { days: { type: "number" }, tool: { type: "string" }, limit: { type: "number" } } } },
|
|
47
|
+
];
|
|
48
|
+
const keyed = (path, init = {}) => fetch(`${BASE}${path}`, { ...init, headers: { "content-type": "application/json", "user-agent": "toll402-mcp/0.5.0", ...(API_KEY ? { "x-toll402-key": API_KEY } : {}) } });
|
|
49
|
+
const meta = async (name, a) => {
|
|
50
|
+
if (!API_KEY)
|
|
51
|
+
return { isError: true, content: [{ type: "text", text: `${name} needs TOLL402_API_KEY (prepaid credits from ${BASE}/credits).` }] };
|
|
52
|
+
const r = name === "toll402_review" ? await keyed(`/v1/calls/${encodeURIComponent(String(a.callId ?? ""))}/review`, { method: "POST", body: JSON.stringify({ useful: a.useful, reason: a.reason }) })
|
|
53
|
+
: name === "toll402_job" ? await keyed(`/v1/jobs/${encodeURIComponent(String(a.jobId ?? ""))}`)
|
|
54
|
+
: await keyed(`/v1/calls?${new URLSearchParams(Object.entries({ days: a.days, tool: a.tool, limit: a.limit ?? 20 }).filter(([, v]) => v !== undefined && v !== null && v !== "").map(([k, v]) => [k, String(v)]))}`);
|
|
55
|
+
const t = await r.text();
|
|
56
|
+
return { isError: !r.ok, content: [{ type: "text", text: r.ok ? t.slice(0, 20_000) : `HTTP ${r.status}: ${t.slice(0, 800)}` }] };
|
|
57
|
+
};
|
|
42
58
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
43
|
-
tools: catalog.tools.map((t) => ({
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
59
|
+
tools: [...META, ...catalog.tools.map((t) => ({
|
|
60
|
+
name: t.name,
|
|
61
|
+
description: `[${t.kind ?? "tool"}] ${t.description} (costs ${t.price} per call, paid automatically: from your wallet via x402 or from prepaid credits (API key))`,
|
|
62
|
+
inputSchema: t.inputSchema,
|
|
63
|
+
}))],
|
|
48
64
|
}));
|
|
49
65
|
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
66
|
+
if (req.params.name.startsWith("toll402_"))
|
|
67
|
+
return meta(req.params.name, (req.params.arguments ?? {}));
|
|
50
68
|
const t = byName.get(req.params.name);
|
|
51
69
|
if (!t)
|
|
52
70
|
return { isError: true, content: [{ type: "text", text: `Unknown tool ${req.params.name}` }] };
|
|
53
71
|
const r = await paidFetch(`${BASE}${t.path}`, {
|
|
54
72
|
method: "POST",
|
|
55
|
-
headers: { "content-type": "application/json", "user-agent": "toll402-mcp/0.
|
|
73
|
+
headers: { "content-type": "application/json", "user-agent": "toll402-mcp/0.5.0", ...(API_KEY ? { "x-toll402-key": API_KEY } : {}), ...(process.env.TOLL402_REF ? { "x-toll402-ref": process.env.TOLL402_REF } : {}), ...(KEY ? { "x-toll402-agent": privateKeyToAccount(KEY).address } : {}) },
|
|
56
74
|
body: JSON.stringify(req.params.arguments ?? {}),
|
|
57
75
|
});
|
|
58
76
|
const text = await r.text();
|
|
@@ -66,7 +84,15 @@ async function main() {
|
|
|
66
84
|
catch {
|
|
67
85
|
/* leave as-is */
|
|
68
86
|
}
|
|
69
|
-
const
|
|
87
|
+
const callId = r.headers.get("x-toll402-call-id");
|
|
88
|
+
let jobHint = "";
|
|
89
|
+
try {
|
|
90
|
+
const jid = JSON.parse(text).result?.job?.id;
|
|
91
|
+
if (jid)
|
|
92
|
+
jobHint = `\n[async task: check it with toll402_job {"jobId": "${jid}"} in about 60 s]`;
|
|
93
|
+
}
|
|
94
|
+
catch { /* not JSON */ }
|
|
95
|
+
const paid = (r.headers.get("payment-response") ? `\n\n[paid ${t.price} via x402]` : r.headers.get("x-toll402-charged") ? `\n\n[charged $${r.headers.get("x-toll402-charged")} from credits · balance $${r.headers.get("x-toll402-balance")}${callId ? ` · call id ${callId}: after using the answer, rate it with toll402_review` : ""}]` : "") + jobHint;
|
|
70
96
|
return { content: [{ type: "text", text: out + paid }] };
|
|
71
97
|
});
|
|
72
98
|
await server.connect(new StdioServerTransport());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toll402-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "MCP server for Toll402: 2,600+ pay-per-call tools for AI agents (web, PDF, provenance, verified business directory, ID validators, SEO/social/enrichment/ads/market-data provider APIs). Pay per call with USDC via x402 (no account) or with prepaid credits bought by card (API key). Charged only on success.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|