nanoparse-mcp 2.0.0 → 2.0.1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 2.0.1 — 2026-11-14
2
+
3
+ - Price: $0.005 → **$0.002** per parse. Copy only: the hosted endpoint takes the
4
+ amount from the live 402 challenge, so no client change is needed.
5
+
1
6
  # Changelog
2
7
 
3
8
  All notable changes to nanoparse-mcp will be documented in this file.
package/README.md CHANGED
@@ -3,12 +3,15 @@
3
3
  [![npm version](https://img.shields.io/npm/v/nanoparse-mcp)](https://www.npmjs.com/package/nanoparse-mcp)
4
4
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5
5
  [![Website](https://img.shields.io/badge/web-nanoparse.app-22D3EE)](https://nanoparse.app)
6
+ [![MCP Score](https://checkmcp.dev/badge/nanoparse-app.svg?url=https%3A%2F%2Fnanoparse.app%2Fmcp)](https://checkmcp.dev/mcp/nanoparse-app)
7
+ [![MCPLookup Trust Index](https://mcplookup.com/badge/io.github.nanoparse-dev/nanoparse-mcp)](https://mcplookup.com/server/io.github.nanoparse-dev/nanoparse-mcp)
8
+ [![Listed on HookMCP](https://hookmcp.com/badge.svg)](https://hookmcp.com)
6
9
 
7
10
  **The easiest way for AI agents to read the web.** NanoParse MCP is a hosted Model Context Protocol server at `https://nanoparse.app/mcp` that turns any URL into clean Markdown your agent can actually use — with machine-readable trust signals attached.
8
11
 
9
12
  No install. No wallet key. No `.env`. Connect once and your agent can read the web.
10
13
 
11
- **Why agents choose NanoParse over Firecrawl or Jina Reader:** no account, no subscription, no API key. Pay $0.005 per parse via x402 when the free tier runs out. Full JavaScript/SPA rendering, native GFM tables, and Litmus trust signals — built for agents, not humans.
14
+ **Why agents choose NanoParse over Firecrawl or Jina Reader:** every page comes back with **Litmus** — 20 machine-readable signals that tell your agent *whether to trust and cite the page* before it reads a word. Pay $0.002 per parse via x402 once the free tier runs out. Full JavaScript/SPA rendering, native GFM tables. No account, no subscription, no API key.
12
15
 
13
16
  ## Quick start
14
17
 
@@ -18,6 +21,7 @@ Add this to your MCP client config:
18
21
  {
19
22
  "mcpServers": {
20
23
  "nanoparse": {
24
+ "type": "http",
21
25
  "url": "https://nanoparse.app/mcp"
22
26
  }
23
27
  }
@@ -43,41 +47,48 @@ That's it. Your agent can now fetch pages from inside any MCP-compatible client
43
47
 
44
48
  ## Real output
45
49
 
46
- Every parse returns `markdown` + `metadata` + `litmus`. Example — parsing an arXiv paper (`examples/example-output.json`, complete and unmodified):
50
+ Every parse returns `markdown` + `metadata` + `litmus`. Here is the full `litmus` object from a real parse of an arXiv paper (`examples/example-output.json` — markdown truncated there, litmus complete and unmodified):
47
51
 
48
52
  ```json
49
53
  {
50
54
  "litmus": {
51
55
  "source": { "type": "academic", "authority": 0.85, "rationale": "academic source" },
52
- "freshness": { "published": null, "stale_warning": "No publish date found — verify independently" },
56
+ "freshness": { "published": null, "age": "unknown", "stale_warning": "No publish date found — verify independently", "modified": null, "has_correction": false, "correction_note": null },
53
57
  "tldr": "Abstract page for arXiv paper 2401.14295: Demystifying Chains, Trees, and Graphs of Thoughts",
54
58
  "key_figures": [ { "value": "2,247", "context": "Thu, 25 Jan 2024 16:34:00 UTC (2,247 KB)" } ],
59
+ "structural_trust_score": { "level": "medium", "trust_factors": ["High-authority source", "No publish date found — verify independently"] },
60
+ "hedge_language": { "density": "low", "markers_found": 0, "per_500_words": 0 },
61
+ "content_density": { "thin_content": false, "substantive_sentence_ratio": 0.76 },
62
+ "syndication": { "detected": false, "note": null },
63
+ "paywall": { "detected": false, "note": null },
55
64
  "content_type": "academic_paper",
56
65
  "reading_time": { "minutes": 4 },
57
- "hedge_language": { "density": "low", "markers_found": 0 },
58
- "syndication": { "detected": false },
59
- "paywall": { "detected": false }
66
+ "is_archived": { "archive_org": true, "archive_is": false },
67
+ "outbound_authority": { "score": 0.54, "top_domains": ["ui.adsabs.harvard.edu", "scholar.google.com"] },
68
+ "boilerplate_ratio": { "ratio": 0.08, "confidence": "high" }
60
69
  }
61
70
  }
62
71
  ```
63
72
 
64
- The agent learns *before reading a word*: this is an academic source (0.85 authority), no publish date was found (verify independently), here's the one-sentence summary, the key numbers, and there's no paywall or syndication flag. See [`examples/agent-conversation.md`](examples/agent-conversation.md) for a full worked round-trip.
73
+ The agent learns *before reading a word*: this is an academic source (0.85 authority), structural trust is **medium** — high authority, but no publish date found, so verify independently. It also gets the one-sentence summary, the key numbers, and confirmation there's no paywall or syndication flag. See [`examples/agent-conversation.md`](examples/agent-conversation.md) for a full worked round-trip.
65
74
 
66
75
  ## Payments
67
76
 
68
- - **First 10 parses per network (subnet) are free** — lifetime, shared across your whole network. No account, no API key, no human required.
69
- - **After that: $0.005 per parse** (flat, no subscriptions) via **x402** — an open micropayment protocol. Your agent's wallet signs the payment automatically. To give your agent a Coinbase wallet, run `npx @coinbase/payments-mcp` and connect it alongside NanoParse.
77
+ - **10 free parses per month with a signed wallet** (sign the claim message — no payment), or 3 anonymous free tries per network. No account, no API key, no human required.
78
+ - **After that: $0.002 per parse** (flat, no subscriptions) via **x402** — an open micropayment protocol. Your agent's wallet signs the payment automatically. To give your agent a Coinbase wallet, run `npx @coinbase/payments-mcp` and connect it alongside NanoParse.
79
+
80
+ Copy-paste recipe for both paths — the wallet-MCP one with no code, and a ~40-line REST client — including the exact `402 → sign → retry` loop and the error codes worth branching on: [`examples/pay-with-x402.md`](examples/pay-with-x402.md).
70
81
 
71
82
  ## How payments work under the hood
72
83
 
73
- When an agent without free quota calls `nanoparse_fetch`, the endpoint responds with an **HTTP 402 — Payment Required** carrying x402 payment instructions. The agent's wallet signs a $0.005 USDC (Base) transfer, the facilitator settles it, and the parse proceeds. The hosted endpoint handles the entire challenge → settlement flow — the agent never needs a private key on your machine.
84
+ When an agent without free quota calls `nanoparse_fetch`, the endpoint responds with an **HTTP 402 — Payment Required** carrying x402 payment instructions. The agent's wallet signs a $0.002 USDC (Base) transfer, the facilitator settles it, and the parse proceeds. The hosted endpoint handles the entire challenge → settlement flow — the agent never needs a private key on your machine.
74
85
 
75
86
  ## Pricing vs Firecrawl
76
87
 
77
88
  | | NanoParse | Firecrawl Hobby |
78
89
  |---|---|---|
79
- | Billing | **$0.005 per parse, flat** | $16/mo subscription, credits expire monthly |
80
- | 5,000 parses | **$50.00** | $16 base — but ~$145 with JSON/extraction modes (9× credit burn) |
90
+ | Billing | **$0.002 per parse, flat** | $16/mo subscription, credits expire monthly |
91
+ | 5,000 parses | **$25.00** | $16 base — but ~$145 with JSON/extraction modes (9× credit burn) |
81
92
  | Account / API key | **None** | Required |
82
93
  | Agent can pay directly (x402) | **Yes** | No |
83
94
 
@@ -110,5 +121,7 @@ is the current, supported integration.
110
121
  - Quick start & integration: [nanoparse.app/quickstart](https://nanoparse.app/quickstart)
111
122
  - Compare & pricing: [nanoparse.app/compare](https://nanoparse.app/compare)
112
123
  - API + MCP endpoint: [nanoparse.app](https://nanoparse.app)
124
+ - Security policy: [SECURITY.md](SECURITY.md) — report a vulnerability to hello@nanoparse.app
125
+ (also published at `https://nanoparse.app/.well-known/security.txt`)
113
126
 
114
127
  MIT licensed.
@@ -36,6 +36,13 @@ word of the paper.
36
36
  { "value": "2,247", "context": "Thu, 25 Jan 2024 16:34:00 UTC (2,247 KB)" },
37
37
  { "value": "2,290", "context": "Sat, 30 Mar 2024 16:36:33 UTC (2,290 KB)" }
38
38
  ],
39
+ "structural_trust_score": {
40
+ "level": "medium",
41
+ "trust_factors": [
42
+ "High-authority source",
43
+ "No publish date found — verify independently"
44
+ ]
45
+ },
39
46
  "content_type": "academic_paper",
40
47
  "reading_time": { "minutes": 4 },
41
48
  "hedge_language": { "density": "low", "markers_found": 0, "per_500_words": 0 },
@@ -47,6 +54,10 @@ word of the paper.
47
54
 
48
55
  ## How the agent reasons about it
49
56
 
57
+ - **Structural trust: medium** — Litmus flags this as high-authority
58
+ (academic, 0.85) but with no publish date found, so the verdict is "verify
59
+ independently," not "trust blindly." The agent treats it as a solid source
60
+ it still needs to date-check.
50
61
  - **Authority 0.85, academic** — high-trust source class. Claims from this
51
62
  paper can be weighed accordingly. (Litmus scores the *source class*, not
52
63
  the truth of the content — the agent still reads and thinks.)
package/examples/costs.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Cost comparison: NanoParse vs Firecrawl
2
2
 
3
- Pricing verified 2026-08-28. NanoParse: **$0.01 per parse, flat** — no
3
+ Pricing verified 2026-08-28 (Firecrawl); NanoParse updated to the current flat rate. NanoParse: **$0.002 per parse, flat** — no
4
4
  subscription, no account, no API key. Litmus signals, full JS/SPA rendering,
5
5
  and GFM tables are included in every parse — there are no feature
6
6
  multipliers.
@@ -19,11 +19,11 @@ Two things the base rate hides:
19
19
 
20
20
  1. **Credits do not roll over.** A Hobby subscription is $16 every month —
21
21
  use 1,000 of 5,000 credits and you still paid $16. NanoParse bills only
22
- what you use: $10 for exactly 1,000 parses.
22
+ what you use: $5 for exactly 1,000 parses.
23
23
  2. **Feature multipliers.** JSON extraction and enhanced mode each add
24
24
  credits per page (up to 9 credits/page combined). At Hobby that makes a
25
- fully-featured parse ~$0.029/page — ~3× NanoParse's flat rate. Litmus,
26
- structured output, and rendering are included in NanoParse's $0.01 with
25
+ fully-featured parse ~$0.029/page — ~6× NanoParse's flat rate. Litmus,
26
+ structured output, and rendering are included in NanoParse's $0.002 with
27
27
  no multiplier.
28
28
 
29
29
  ## What a month of 5,000 parses costs
@@ -31,9 +31,9 @@ Two things the base rate hides:
31
31
  | | NanoParse | Firecrawl Hobby |
32
32
  |---|---|---|
33
33
  | Subscription | None — pay per parse | $16/mo, billed every month |
34
- | 5,000 plain scrapes | **$50.00** | $16 (base rate) |
35
- | 5,000 with extraction/features | **$50.00** | ~$145 (9× credit burn) |
36
- | Use only 1,000 of your quota | **$10.00** | $16 (credits expire) |
34
+ | 5,000 plain scrapes | **$25.00** | $16 (base rate) |
35
+ | 5,000 with extraction/features | **$25.00** | ~$145 (9× credit burn) |
36
+ | Use only 1,000 of your quota | **$5.00** | $16 (credits expire) |
37
37
  | Account / API key needed | No | Yes |
38
38
  | Agent can pay directly (x402) | Yes | No |
39
39
 
@@ -0,0 +1,272 @@
1
+ # Paying for a parse with x402
2
+
3
+ NanoParse answers an unauthenticated call with **HTTP 402** and machine-readable
4
+ terms — the price, the token, the chain, the recipient, and what a valid signature
5
+ must look like. No account, no API key, no card, no subscription.
6
+
7
+ - **10 free parses per month with a signed wallet**, or 3 anonymous free tries per
8
+ network.
9
+ - **After that: $0.002 USDC on Base per parse**, flat.
10
+ - Settlement runs **after** a page is read. A page that cannot be read — bot wall,
11
+ consent wall, paywall, JS shell with no text — is reported with a named reason
12
+ and **never charged**.
13
+
14
+ Every parse returns clean Markdown plus **Litmus** — 20 machine-readable signals
15
+ (source authority, freshness, structural trust, content density, syndication,
16
+ paywall state) in the same response, not as a second billed call.
17
+
18
+ Two ways to pay. Pick one.
19
+
20
+ ---
21
+
22
+ ## Option A — give the agent a wallet, write no code
23
+
24
+ Add NanoParse to your MCP client, and give the agent a wallet that can sign:
25
+
26
+ ```json
27
+ {
28
+ "mcpServers": {
29
+ "nanoparse": {
30
+ "url": "https://nanoparse.app/mcp"
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ ```
37
+ npx @coinbase/payments-mcp
38
+ ```
39
+
40
+ (The Coinbase agentic wallet MCP — self-custody, funded via Apple Pay. Docs:
41
+ <https://docs.cdp.coinbase.com/agentic-wallet/mcp/welcome>.)
42
+
43
+ Then the loop is two calls:
44
+
45
+ 1. `nanoparse_fetch(url)`. Once the free tier is spent, the tool returns an
46
+ `isError` result whose **`structuredContent` is the PaymentRequired object** —
47
+ `x402Version`, `accepts[]`, `extensions`. It is the quote, not a failure.
48
+ 2. Sign `accepts[0]` and retry the same tool with
49
+ `payment_signature` = the base64url JSON envelope. This argument works in
50
+ **every** MCP client; there are no custom headers to set. A client that can
51
+ set headers may instead send the same payload as `Payment-Signature`, or put
52
+ the envelope object in `_meta["x402/payment"]`.
53
+
54
+ `nanoparse_status(address)` is free and tells the agent what it needs to know
55
+ before spending: free parses remaining, wallet and USDC balance, whether the next
56
+ call will go through without payment.
57
+
58
+ ---
59
+
60
+ ## Option B — a REST client that pays its own way
61
+
62
+ ~40 lines of Node with [`viem`](https://viem.sh). No SDK, no server-side key:
63
+ the wallet is the caller's.
64
+
65
+ ```js
66
+ // read-page.mjs — read one page, paying $0.002 in USDC on Base only if asked.
67
+ // Usage: npm i viem && WALLET_KEY=0x... node read-page.mjs https://example.com
68
+ //
69
+ // 1. Try the free tier (10/month with a signed wallet, or 3 anonymous tries): a plain POST.
70
+ // 2. A 402 is the quote, not an error. Read the terms out of it.
71
+ // 3. Sign an EIP-3009 permit over those terms (gas is the facilitator's).
72
+ // 4. Retry with the signed envelope; poll /status (free) until the page lands.
73
+ import { privateKeyToAccount } from "viem/accounts";
74
+
75
+ const ENDPOINT = "https://nanoparse.app/fetch";
76
+ const account = privateKeyToAccount(process.env.WALLET_KEY);
77
+ const b64 = (o) => Buffer.from(JSON.stringify(o)).toString("base64");
78
+
79
+ async function readPage(url) {
80
+ const post = (headers) =>
81
+ fetch(ENDPOINT, {
82
+ method: "POST",
83
+ headers: { "Content-Type": "application/json", ...headers },
84
+ body: JSON.stringify({ url }),
85
+ });
86
+
87
+ // 1. Free tier first — no payment, no key, no account.
88
+ let res = await post();
89
+ if (res.status !== 402) {
90
+ if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
91
+ return poll(await res.json());
92
+ }
93
+
94
+ // 2. The terms. `amount` is micro-USDC ("2000" = $0.002) and `payTo` is the
95
+ // only address a permit should ever be signed for.
96
+ const terms = (await res.json()).payment_required.accepts[0];
97
+ const now = Math.floor(Date.now() / 1000);
98
+ const nonce = "0x" + Buffer.from(crypto.getRandomValues(new Uint8Array(32))).toString("hex");
99
+ const authorization = {
100
+ from: account.address,
101
+ to: terms.payTo,
102
+ value: terms.amount,
103
+ validAfter: String(now - 5),
104
+ validBefore: String(now + 895), // within maxTimeoutSeconds from the challenge
105
+ nonce,
106
+ };
107
+
108
+ // 3. EIP-3009 transferWithAuthorization. The EIP-712 domain belongs to the
109
+ // token contract, so take it from the challenge: extra.name is the domain
110
+ // name "USD Coin" — signing against the ticker "USDC" fails verification.
111
+ const signature = await account.signTypedData({
112
+ domain: {
113
+ name: terms.extra.name,
114
+ version: terms.extra.version,
115
+ chainId: 8453, // Base
116
+ verifyingContract: terms.asset,
117
+ },
118
+ types: {
119
+ TransferWithAuthorization: [
120
+ { name: "from", type: "address" },
121
+ { name: "to", type: "address" },
122
+ { name: "value", type: "uint256" },
123
+ { name: "validAfter", type: "uint256" },
124
+ { name: "validBefore", type: "uint256" },
125
+ { name: "nonce", type: "bytes32" },
126
+ ],
127
+ },
128
+ primaryType: "TransferWithAuthorization",
129
+ message: {
130
+ ...authorization,
131
+ value: BigInt(authorization.value),
132
+ validAfter: BigInt(authorization.validAfter),
133
+ validBefore: BigInt(authorization.validBefore),
134
+ },
135
+ });
136
+
137
+ // 4. Retry with the envelope the challenge quoted: accepted[] echoed verbatim.
138
+ res = await post({
139
+ "Payment-Signature": b64({ x402Version: 2, accepted: terms, payload: { signature, authorization } }),
140
+ });
141
+ const job = await res.json();
142
+ if (!res.ok) throw new Error(`${job.error_code}: ${job.message}`);
143
+ return poll(job); // 202 { jobId, statusUrl }
144
+ }
145
+
146
+ // /status is free and unauthenticated: watch a job without spending anything.
147
+ async function poll(job) {
148
+ for (;;) {
149
+ const out = await (await fetch(job.statusUrl)).json();
150
+ if (out.status === "completed") return out; // { markdown, metadata, litmus }
151
+ if (out.status !== "processing") throw new Error(`${out.status}: ${out.error_code ?? ""}`);
152
+ await new Promise((r) => setTimeout(r, 2000));
153
+ }
154
+ }
155
+
156
+ console.log((await readPage(process.argv[2])).markdown);
157
+ ```
158
+
159
+ ---
160
+
161
+ ## The 402 is the quote
162
+
163
+ Captured live, free tier exhausted, no payment attached:
164
+
165
+ ```json
166
+ {
167
+ "error": "payment_required",
168
+ "error_code": "free_tier_exhausted",
169
+ "free_calls_used": 10,
170
+ "free_calls_limit": 10,
171
+ "payment_required": {
172
+ "x402Version": 2,
173
+ "accepts": [
174
+ {
175
+ "scheme": "exact",
176
+ "network": "eip155:8453",
177
+ "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
178
+ "amount": "2000",
179
+ "payTo": "0x57a1d06873db575baeae1f6af30862a75c7bd570",
180
+ "maxTimeoutSeconds": 60,
181
+ "extra": { "assetTransferMethod": "eip3009", "name": "USD Coin", "version": "2" }
182
+ }
183
+ ]
184
+ }
185
+ }
186
+ ```
187
+
188
+ The same terms travel base64url-encoded in the `payment-required` response header,
189
+ and the recipient is repeated as a CAIP-style `pay-to: ethereum:base:0x…` header.
190
+ `access-control-allow-origin: *` and the `Content-Type, Payment-Signature,
191
+ Authorization` request headers are allowed on this route, so a browser-side agent
192
+ can send a signed payment too.
193
+
194
+ Four fields carry the weight:
195
+
196
+ - **`amount`** is micro-USDC — `"2000"` is $0.002 at six decimals. There is no
197
+ currency string to parse.
198
+ - **`network`** is a CAIP-2 chain id (`eip155:8453` is Base) and **`asset`** is the
199
+ USDC contract on it, so the client never guesses which USDC.
200
+ - **`extra.name` / `extra.version`** are the EIP-712 domain of the token contract:
201
+ `"USD Coin"` v2. Signing against `"USDC"` produces a signature that fails
202
+ verification — the domain is part of the digest.
203
+ - **`payTo`** is the only address a permit should ever be signed for. A payload
204
+ pointing anywhere else is rejected before any signature is checked.
205
+
206
+ ## What the server checks before the facilitator is called
207
+
208
+ A wrong shape costs nothing — it answers `400 invalid_payment_payload`:
209
+
210
+ - `x402Version` is exactly `2`.
211
+ - `accepted` repeats the terms verbatim: `scheme`, `network`, `asset`, `amount`,
212
+ `payTo`.
213
+ - `payload.signature` is `0x` + 130 hex characters (65-byte packed `r‖s‖v`).
214
+ - `payload.authorization.value` equals `amount` exactly.
215
+ - `payload.authorization.nonce` is `0x` + 64 hex characters, and single-use
216
+ on-chain — which is what makes "retry the same payload" safe rather than hopeful.
217
+ - `validAfter` is in the past and `validBefore` in the future.
218
+
219
+ ## Retry policy, as error codes
220
+
221
+ | `error_code` | What to do |
222
+ |---|---|
223
+ | `insufficient_usdc` | Fund the wallet and sign a **fresh** envelope. |
224
+ | `invalid_payment_payload`, `invalid_payment` | The shape or signature is wrong. Fix it; retrying unchanged cannot succeed. |
225
+ | `permit_expired`, `permit_not_yet_valid` | Sign a fresh permit. |
226
+ | `settlement_failed` | Ambiguous settle. Retry with the **same** envelope — it is idempotent. |
227
+ | `screening_declined` | Compliance screening declined. Do not retry. |
228
+ | `location_blocked` | A jurisdiction the facilitator does not serve. |
229
+ | `self_send_not_allowed` | Payer and recipient are the same address. |
230
+ | `content_insufficient` | The page rendered but yielded almost no text (JS shell, login wall). **Not charged.** |
231
+ | `domain_blocked` | The host repeatedly returned nothing parseable. **Not charged.** Do not retry. |
232
+
233
+ There is no refund path because nothing is charged up front: settlement runs after
234
+ a successful read, so a failed render simply never settles.
235
+
236
+ ## Check the recipient before you sign
237
+
238
+ `/.well-known/x402` publishes the address the endpoint claims, and the 402 repeats
239
+ it. Compare them before signing anything:
240
+
241
+ ```js
242
+ const accept = terms; // accepts[0] from the 402
243
+ const disc = await (await fetch("https://nanoparse.app/.well-known/x402")).json();
244
+ if (!disc.ownershipProofs.map((a) => a.toLowerCase()).includes(accept.payTo.toLowerCase()))
245
+ throw new Error("recipient not published by the endpoint");
246
+ ```
247
+
248
+ That buys consistency, not identity — both documents come from the same origin —
249
+ but it is one GET and it catches a swapped recipient.
250
+
251
+ ## What was verified
252
+
253
+ - The client under **Option B** was run verbatim against the live endpoint on
254
+ 2026-10-06 with a fresh, unfunded throwaway wallet: free tier exhausted → `402`
255
+ → signed envelope → retry → `insufficient_usdc: Payer's USDC balance is too low
256
+ for this call (needs 2000 micro-USDC on Base)`. The shape and signature were
257
+ accepted; nothing was charged.
258
+ - The **Option A** MCP loop was verified the same way: `tools/call` returned
259
+ `isError: true` with `structuredContent` = the PaymentRequired object, and the
260
+ retry carrying `payment_signature` answered
261
+ `-32000 / insufficient_usdc` for the unfunded payer.
262
+ - The settle leg — USDC actually moving to the treasury on Base — is exercised
263
+ end to end by our own labeled canary through this same paid path.
264
+
265
+ ## Docs
266
+
267
+ - Quick start: <https://nanoparse.app/quickstart>
268
+ - Machine spec: <https://nanoparse.app/openapi.json>
269
+ - Agent-facing description: <https://nanoparse.app/llms.txt>
270
+ - x402 discovery: <https://nanoparse.app/.well-known/x402>
271
+
272
+ MIT licensed.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nanoparse-mcp",
3
- "version": "2.0.0",
4
- "description": "NanoParse MCP — hosted Model Context Protocol server for AI agents. Any URL becomes clean Markdown with attribution signals. $0.005 per page via x402, no account or API key.",
3
+ "version": "2.0.1",
4
+ "description": "NanoParse MCP \u2014 hosted Model Context Protocol server for AI agents. Any URL becomes clean Markdown with attribution signals. $0.002 per page via x402, no account or API key.",
5
5
  "keywords": [
6
6
  "mcp",
7
7
  "model-context-protocol",