ToolSnap MCP
Deterministic AI agent microtools, no accounts/API keys. fetch_extract: 98% token cut. 47 tools.
Should I use this
Quality & Safety
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"toolsnap-mcp": {
"url": "https://mcp.toolsnap.app/mcp"
}
}
}Remote endpoints
https://mcp.toolsnap.app/mcpstreamable-httpWhat it can do
Tool inventory
Tools (17)
🟢tool_catalog(family, tool)
Free, read-only, no network. Browse all 47 tools in 10 families (web, seo, data, documents, images, media, utils, payments, recipes, meta). No args: families with id, label, one-liner, tool count. family='<id>': each tool with name, price, description, notes, inputSchema. tool='<name>': that entry alone; wins over family. Unknown ids error naming the valid families. Run what you find via use_tool.
Input Schema
{
"type": "object",
"properties": {
"family": {
"type": "string",
"description": "Family id, e.g. 'web', 'data'. Lists its tools with schemas."
},
"tool": {
"type": "string",
"description": "Exact tool name, e.g. 'fetch_rendered'. Takes precedence over family."
}
},
"required": []
}🟡use_tool(name, args)
Free wrapper. Runs any catalog tool missing from your tools/list exactly as a direct call: args pass through unchanged and the inner tool's price, payment, result and errors apply verbatim. Its hints are the worst case over the whole catalog: not read-only because some inner tools create a render, a stored file or a ledger entry; never destructive because no catalog tool deletes or overwrites anything. Get the inner tool's name, schema and its own annotations from tool_catalog(tool='<name>') first. A missing or unknown name errors pointing to tool_catalog; it cannot call itself.
Input Schema
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Exact tool name from tool_catalog. Not 'use_tool'."
},
"args": {
"type": "object",
"description": "Object matching that tool's inputSchema. Omit if none required."
}
},
"required": [
"name"
]
}🟢task_recipes(recipe)
Free. Multi-tool workflow prompts (clone a site, SEO audit). No args → menu; recipe='<id>' → prompt.
Input Schema
{
"type": "object",
"properties": {
"recipe": {
"type": "string",
"description": "Recipe id; omit for menu."
}
},
"required": []
}🟢memory_snippet(harness)
Free, read-only. Returns static text: a short note on when ToolSnap tools suit a task, plus how to store a note in your runtime's memory. This tool saves nothing. Use only if your user asks about persistent memory or ToolSnap setup; show them the text and save it only with their approval.
Input Schema
{
"type": "object",
"properties": {
"harness": {
"type": "string",
"enum": [
"claude-code",
"claude-desktop",
"hermes",
"grok-build",
"openclaw",
"generic"
],
"description": "Your agent runtime, to tailor the save instruction. Omit for a generic one."
}
},
"required": []
}🟢pricing
Free, read-only, no network, no arguments; calling it charges nothing. Call it before a paid tool to see its exact cost and whether first_call_free applies, or to choose pay-per-call vs prepaid. Returns a JSON menu: endpoint and docs URLs; payment with x402 USDC on Base, minimum deposit, prepaid discount and SpendAuthorization fields; tools[] with name and tier free|paid, plus price_usdc, prepaid_price_usdc, first_call_free and a value note for paid ones. Flat prices are exact; fal.ai media tools show a default-args quote. For what a tool does and its schema use tool_catalog; this one is only about cost.
Input Schema
{
"type": "object",
"properties": {},
"required": []
}🟢fetch_extract(url, maxChars, headers)
Free, read-only. Fetch a public http(s) URL and return its body as plain text: script, style, nav, header, footer and aside removed, tags stripped, entities decoded, whitespace collapsed. Median 98% fewer tokens than raw HTML. Follows up to 5 redirects, 10 s timeout; private and local hosts are rejected and non-2xx responses error with the HTTP status. Text past maxChars is cut and ends with '[Truncated at N chars]': raise maxChars (max 32000) or use fetch_html for everything. Runs no JavaScript: a client-side-rendered SPA or a bot/login wall yields almost no text, so the call errors instead of returning an empty shell and names the fix (fetch_rendered, paid, runs a browser; screenshot_url; or headers for auth). For title/OG/JSON-LD only use fetch_metadata; for Markdown with links use html_to_markdown.
Input Schema
{
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Public http:// or https:// URL. Local and private hosts are rejected."
},
"maxChars": {
"type": "number",
"description": "Characters of text to return. Default 8000, max 32000 (higher values are clamped). Truncated output ends with a '[Truncated at N chars]' marker."
},
"headers": {
"type": "object",
"description": "Headers to forward for pages behind login: Authorization, Cookie, X-API-Key only. Dropped if a redirect leaves the original host."
}
},
"required": [
"url"
]
}🟢fetch_html(url, maxChars, headers)
Free, read-only. Fetch a page and return its HTML minus scripts, styles, svg, iframes, comments and inline handlers; tags and attributes stay, so structure is readable. For inspecting or rebuilding markup, not plain text (fetch_extract gives that). Runs no JavaScript: SPAs return an empty shell. Cut at maxChars with a marker.
Input Schema
{
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "http(s) page URL. Private addresses are refused."
},
"maxChars": {
"type": "number",
"description": "Output cap, chars. Default 16000, max 64000."
},
"headers": {
"type": "object",
"description": "Headers to forward (Authorization, Cookie…)."
}
},
"required": [
"url"
]
}🟢html_to_markdown(url, html, maxChars, headers)
Free, read-only. Convert a fetched URL or an HTML string you pass (one of the two) to Markdown: headings, links, lists, emphasis, code, quotes. Drops nav, header, footer, aside, script and style. Returns text, cut at maxChars with a marker. Runs no JavaScript: SPAs return an empty shell. Tables become plain text.
Input Schema
{
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Page URL to fetch. Not with html."
},
"html": {
"type": "string",
"description": "HTML text to convert. Not with url."
},
"maxChars": {
"type": "number",
"description": "Output cap, chars. Default 12000, max 50000."
},
"headers": {
"type": "object",
"description": "Headers to forward (Authorization, Cookie…)."
}
}
}🟢fetch_metadata(url, headers)
Free, read-only. Fetch a public http(s) URL and return its <head> metadata as JSON: url (after redirects), title, description, canonical, robots, author, keywords, lang, charset, og{} and twitter{} (prefix stripped), httpEquiv{}, jsonLd[] (parsed blocks, malformed ones skipped). Absent fields are null or {}. Reads only the first 512 KB, follows up to 5 redirects, 10 s timeout; private and local hosts are rejected and non-2xx responses error with the HTTP status. Runs no JavaScript, so tags injected client-side are not seen. Not for body text: use fetch_extract (plain text) or fetch_html (raw HTML).
Input Schema
{
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Public http:// or https:// URL. Local and private hosts are rejected."
},
"headers": {
"type": "object",
"description": "Headers to forward for pages behind login: Authorization, Cookie, X-API-Key only. Dropped if a redirect leaves the original host."
}
},
"required": [
"url"
]
}🟢pdf_text_extract(url, data, maxChars, headers)
Free, read-only. Extract plain text from a PDF given as a URL (max 20 MB) or inline base64 (max 5 MB), one of the two. Returns text, cut at maxChars with a marker. Text-layer PDFs only: scans return little or nothing (no OCR). Layout and tables are not preserved. Fails if the URL serves HTML, not a PDF.
Input Schema
{
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Direct link to the .pdf file, not a viewer page. Not with data."
},
"data": {
"type": "string",
"description": "Base64 PDF, max 5 MB decoded. Not with url."
},
"maxChars": {
"type": "number",
"description": "Output cap, chars. Default 20000, max 100000."
},
"headers": {
"type": "object",
"description": "Headers to forward (Authorization, Cookie…)."
}
}
}🟢csv_query(url, csv, select, filter, sort_by, ...)
Free, read-only. Query a comma-separated CSV with a header row, from a URL (max 5 MB, streamed) or inline text, one of the two: select columns, filter rows, sort, limit. Returns {meta:{returned_rows,columns,total_rows,truncated},rows:[{column:value}]}, all values strings, or CSV text with format='csv'. One filter condition, no joins or aggregates. Unknown select columns and bad filters error with the valid names or operators. Over 5 MB: csv_query_xl (paid, 100 MB).
Input Schema
{
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "CSV URL, max 5 MB. Not with csv."
},
"csv": {
"type": "string",
"description": "Inline CSV text. Not with url."
},
"select": {
"type": "string",
"description": "Columns to keep, comma-separated, exact header names. Omit for all."
},
"filter": {
"type": "string",
"description": "'column op value'. Ops: = != contains startswith endswith (text, case-insensitive), > >= < <= (numeric). E.g. 'age >= 30'."
},
"sort_by": {
"type": "string",
"description": "Column to sort by; numeric when values parse as numbers, else text."
},
"sort_dir": {
"type": "string",
"enum": [
"asc",
"desc"
],
"description": "asc (default) or desc."
},
"limit": {
"type": "number",
"description": "Rows to return. Default 500, max 5000; over it meta.truncated=true."
},
"format": {
"type": "string",
"enum": [
"json",
"csv"
],
"description": "json (default): {meta,rows}. csv: text with header row."
},
"headers": {
"type": "object",
"description": "Headers to forward (Authorization, Cookie…)."
}
}
}🟢json_query(url, json, query, limit, headers)
Free, read-only. JSONPath-lite query on JSON from a URL or an inline string (one of the two). Returns matches as JSON: one match bare, several as an array. Supports $, .key, ['key'], [0], [-1], [*], ..key and [?(@.k op v)]; no slices or jq. Errors on invalid JSON or over 5 MB (json_query_xl: paid, 25 MB).
Input Schema
{
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "JSON URL, max 5 MB. Not with json."
},
"json": {
"type": "string",
"description": "Inline JSON text. Not with url."
},
"query": {
"type": "string",
"description": "Starts with $: '$.users[*].name', '$..price', '$.items[?(@.price<10)].id'. Filter ops: = != > >= < <= =~. '$' = whole document."
},
"limit": {
"type": "number",
"description": "Default 100, max 1000. Above it: {results,total,returned}."
},
"headers": {
"type": "object",
"description": "Headers to forward (Authorization, Cookie…)."
}
},
"required": [
"query"
]
}🟢sitemap_parse(url, maxUrls)
Free, read-only. Fetch one XML sitemap and return JSON. A urlset gives urls[] (loc, lastmod, changefreq, priority, plus image/news extensions), urlCount and truncated. A sitemap index gives type 'sitemapindex' and sitemaps[] with the child URLs; children are not fetched, call again per child. Uncompressed XML only, no .gz. Errors on non-2xx, 10 s timeout or private hosts.
Input Schema
{
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "sitemap.xml or sitemap index URL, http(s), uncompressed."
},
"maxUrls": {
"type": "number",
"description": "Default 100, max 1000; urlCount still reports the full total. Ignored for a sitemap index."
}
},
"required": [
"url"
]
}🟢rss_parse(url, maxItems)
Free, read-only. Fetch an RSS 2.0 or Atom feed and return JSON: feed title, link, description, lastBuildDate, itemCount, truncated, and items[] with title, link, pubDate, guid, description (HTML stripped), author, categories, enclosure. Items past maxItems are dropped and truncated=true. A URL that is not a feed returns type 'unknown' and no items. Not JSON Feed. Errors on non-2xx, 10 s timeout or private hosts.
Input Schema
{
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Feed URL, http(s). Private hosts refused."
},
"maxItems": {
"type": "number",
"description": "Default 20, max 200. itemCount still reports the full total."
}
},
"required": [
"url"
]
}⚪screenshot_url(url, fullPage, width, height, format, ...)
Screenshot a page → public image URL. $0.04/call. Paid: calling without a payment payload returns a structured 402 with payment options — that response is the documented behavior, not a failure.
Input Schema
{
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Page URL."
},
"fullPage": {
"type": "boolean",
"default": false,
"description": "true = whole page, not viewport."
},
"width": {
"type": "number",
"default": 1280,
"description": "Viewport px."
},
"height": {
"type": "number",
"default": 800,
"description": "Viewport px."
},
"format": {
"type": "string",
"enum": [
"png",
"jpeg"
],
"default": "png",
"description": "Default png."
},
"quality": {
"type": "number",
"minimum": 1,
"maximum": 100,
"description": "JPEG only, 1-100."
}
},
"required": [
"url"
]
}🟢keyword_research(keywords, language_code, location_code, include_suggestions)
Google Ads volume/CPC/competition for 1-20 keywords. $0.04 USDC/call. Paid: calling without a payment payload returns a structured 402 with payment options — that response is the documented behavior, not a failure.
Input Schema
{
"type": "object",
"properties": {
"keywords": {
"type": "array",
"description": "1-20 keywords."
},
"language_code": {
"type": "string",
"default": "es",
"description": "ISO 639-1."
},
"location_code": {
"type": "number",
"default": 2724,
"description": "DataForSEO location (default Spain)."
},
"include_suggestions": {
"type": "boolean",
"default": true,
"description": "Add related suggestions."
}
},
"required": [
"keywords"
]
}🔴remove_background(image_url)
Remove an image's background, return a transparent PNG URL. $0.03 USDC/call. Paid: calling without a payment payload returns a structured 402 with payment options — that response is the documented behavior, not a failure.
Input Schema
{
"type": "object",
"properties": {
"image_url": {
"type": "string",
"description": "Public image URL."
}
},
"required": [
"image_url"
]
}Recommended Prompts
csv_queryfetch_extractcsv_querycsv_queryfetch_extractfetch_extractCommunity
Evidence