# Toolshed — tools for agents · a Lemon field directory Site: https://toolshed.lemon-agent.dev API: https://toolshed.lemon-agent.dev Generated: 2026-09-29 Source: entries.yaml — 47 entries across 6 shelves. 19 hosted · 28 local references. Every hosted call is priced per call — $0.002–$0.006 in USDC via x402. Availability check: GET https://toolshed.lemon-agent.dev/check?from=&to= Field-bound match, case-insensitive: from is matched against the "have" side only, to against the "need" side only. A parameter matches on a substring of the prose name OR on an exact alias — extensions and MIME types both work, with or without a leading dot (md, .md, text/markdown, yml, .yaml, text/html). Every match carries its own x_aliases and y_aliases, so the accepted spellings can be read rather than guessed. No parameters returns every hosted tool. Convert: POST https://toolshed.lemon-agent.dev/convert/ with the raw file as the body (256 KB cap). The converted file comes back as the body, with the right Content-Type. Free fixed sample: the md-html entry in https://toolshed.lemon-agent.dev/catalog.json carries the exact hosted.sample.request and hosted.sample.response shown on the human converter card. It accepts no caller input and invokes no endpoint. Tiers: there is no free tier. Every hosted call is a paid call, priced per call, and an unauthenticated POST answers HTTP 402 immediately with the envelope to pay against — the 402 is the front door, not a rejection. You are charged only for conversions actually served. Payment: an unpaid call answers HTTP 402 with an x402 envelope — exact scheme, USDC on Base or on Solana — naming the price, the payTo address and an outputSchema describing the request body and the response. The accepts array lists the rails that are live, Base first, at the same price on either (USDC is 6 decimals on both chains); take the first entry you can pay rather than assuming there is exactly one. No accounts, no keys, per-call pricing. Pay with an x402-capable client (x402-fetch, the x402 SDK, Coinbase AgentKit) holding a wallet key with USDC on one of those rails; it signs and retries with an X-PAYMENT header. The payment is verified with the Coinbase CDP facilitator before the conversion is served: a verified call comes back with x-payment-verified: true and settles on the rail it was paid on immediately afterwards; a payment the facilitator rejects gets the 402 again with an invalidReason and no conversion; and if the facilitator cannot be reached the call is served anyway, saying so with x-payment-verified: false and x-payment-error. Settlement is queued only for a conversion that was actually served, so a 400 on input we cannot convert is never charged, and a body over the 256 KB cap is refused with 413 before an envelope is built. On a deployment with no receiving address configured, calls answer HTTP 429 instead of 402. x402 v1 + v2 dual-stack: the same 402 carries the v1 envelope in the body and the v2 envelope base64 in a PAYMENT-REQUIRED response header; pay with X-PAYMENT (v1) or PAYMENT-SIGNATURE (v2). OpenAPI: https://toolshed.lemon-agent.dev/openapi.json Skill: npx skills add algonormative/lemon-toolshed MCP: claude mcp add toolshed -- npx -y github:algonormative/lemon-toolshed Tools: toolshed_check, toolshed_convert, toolshed_catalog. Base URL via TOOLSHED_URL. Editorial stance: Post a file to a hosted tool and read the converted file back — nothing to install. Where we do not host the job, the entry names the tool worth reaching for and what bites about it. We prefer the plain deterministic tool wherever one works, and a model only where the answer is a judgment call. Every verdict below is engineering judgment, not measurement. Curation is an owner-taste surface and these entries are drafts for review. The same fields are available as structured JSON in catalog.json. ## Saved HTML page / static HTML file -> Markdown id: html-markdown hosted: yes hosted_path: POST /convert/html-markdown hosted_price: $0.006/call · x402 hosted_status: live aliases_from: html, htm, text/html, application/xhtml+xml aliases_to: markdown, md, mdown, text/markdown, text/x-markdown local_tool: pandoc local_install: brew install pandoc kind: deterministic verdict: For HTML already on disk, pandoc's reader is exact and fast, and `--wrap=none` keeps the output diff-friendly. Feeding a whole page to a model to "clean it up" burns tokens and invents heading levels; pandoc preserves precisely the structure that is there. The hosted endpoint runs Turndown instead of pandoc — same job, no install — as a priced x402 call, like every other hosted tool here. caveats: Pandoc converts everything, including nav, ads and cookie banners — pre-strip with a readability-style extractor (trafilatura, readability-lxml) if you only want the article body. The hosted endpoint has the same blind spot. escalate: Never for the markup. Boilerplate removal is a heuristic problem first; a model is a last resort for pages where the article body is genuinely ambiguous. url: https://pandoc.org verified: 2026-08-18 ## Markdown -> HTML id: md-html hosted: yes hosted_path: POST /convert/md-html hosted_price: $0.004/call · x402 hosted_status: live aliases_from: markdown, md, mdown, text/markdown, text/x-markdown aliases_to: html, htm, text/html, application/xhtml+xml local_tool: pandoc local_install: brew install pandoc kind: deterministic verdict: Markdown to HTML is a solved parse, so the only real questions are which dialect and which extensions. Pandoc is the local answer and handles tables, footnotes and math; the hosted endpoint runs `marked` over CommonMark plus GitHub tables, which is what most agents actually want when they say "render this Markdown". caveats: The hosted endpoint emits an HTML fragment, not a full document — no ``, no stylesheet. It does not sanitize: raw HTML in the input passes through, so do not render untrusted output into a page without sanitizing it yourself. escalate: Never. url: https://pandoc.org verified: 2026-08-18 ## Markdown with a frontmatter fence -> JSON with the metadata and the body split apart id: frontmatter-json hosted: yes hosted_path: POST /convert/frontmatter-json hosted_price: $0.004/call · x402 hosted_status: live aliases_from: frontmatter, md, markdown, yaml frontmatter, text/markdown aliases_to: json, application/json, text/json local_tool: python-frontmatter local_install: pip install python-frontmatter kind: deterministic verdict: Splitting on the `---` fence is three lines of code that everyone writes slightly wrong: the fence has to be the first thing in the file, the closing fence has to be on its own line, and a `---` inside the body is a horizontal rule rather than a delimiter. The hosted endpoint returns `{"data": ..., "content": ...}` — parsed frontmatter and the untouched body — which is what a static-site pipeline or a content audit actually needs. caveats: YAML frontmatter only — TOML (`+++`) and JSON frontmatter are not recognised. A file with no opening fence is an error rather than an empty `data` object, because silently reporting "no metadata" for a file whose fence you mistyped is the bug this would otherwise hide. The body is returned byte-for-byte, unrendered. escalate: Never for the split. A model is the right tool only for the different job of inferring metadata a document never carried. url: https://python-frontmatter.readthedocs.io verified: 2026-08-30 ## Markdown -> JSON token tree plus a table of contents id: markdown-json hosted: yes hosted_path: POST /convert/markdown-json hosted_price: $0.004/call · x402 hosted_status: live aliases_from: markdown, md, mdown, text/markdown, text/x-markdown aliases_to: json, application/json, text/json local_tool: pandoc local_install: brew install pandoc kind: deterministic verdict: `pandoc -t json` gives you pandoc's AST locally. The hosted endpoint returns `marked`'s token stream plus a derived `toc` array of `{depth, text}` — the cheap thing an agent usually wants, which is the document's shape without having to render it and re-parse the HTML. Asking a model to "extract the headings" costs tokens for an answer that quietly renumbers on the next input; a lexer does not. caveats: The token shape is `marked`'s, not pandoc's and not a standard — it is stable across a call but it is a library's data structure, so pin behaviour you depend on with your own test. `toc` is built from ATX and setext headings only; a bold line pretending to be a heading was never structure and does not appear. escalate: Only when the headings you want do not exist as headings and someone has to decide what the document's sections really are. url: https://pandoc.org verified: 2026-08-30 ## Saved HTML page / static HTML file -> Plain text, readable id: html-text hosted: yes hosted_path: POST /convert/html-text hosted_price: $0.006/call · x402 hosted_status: live aliases_from: html, htm, text/html, application/xhtml+xml aliases_to: plain text, txt, text, text/plain local_tool: lynx local_install: brew install lynx kind: deterministic verdict: `lynx -dump -nolist` is the classic local answer. The hosted endpoint parses the page with a real DOM and walks it, so block elements become paragraph breaks and `