protogrid

Search / io.extcord/extcord

Extcord

R0· no sign-in

Agent utilities: read big pages without filling context, exact math, dates, parsing. Free.

v0.7.0 · active · descriptor JSON · versions

An agent can connect right now, no human step.Remote endpoint, no authentication, reachable on the last probe.
Quality76good
Trust80of 100
Uptime, 30 days100%
Latency p50775 ms

Connect

8 clients · secrets stay placeholders
{
  "mcpServers": {
    "extcord": {
      "type": "http",
      "url": "https://extcord.io/mcp"
    }
  }
}
claude mcp add --transport http extcord https://extcord.io/mcp
[mcp_servers.extcord]
url = "https://extcord.io/mcp"
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "extcord": {
      "type": "remote",
      "url": "https://extcord.io/mcp",
      "enabled": true
    }
  }
}
{
  "mcpServers": {
    "extcord": {
      "type": "http",
      "url": "https://extcord.io/mcp"
    }
  },
  "deeplink": "cursor://anysphere.cursor-deeplink/mcp/install?name=extcord&config=eyJ0eXBlIjoiaHR0cCIsInVybCI6Imh0dHBzOi8vZXh0Y29yZC5pby9tY3AifQ%3D%3D"
}
{
  "servers": {
    "extcord": {
      "type": "http",
      "url": "https://extcord.io/mcp"
    }
  }
}
{
  "mcpServers": {
    "extcord": {
      "httpUrl": "https://extcord.io/mcp"
    }
  }
}
extensions:
  "extcord":
    enabled: true
    name: "extcord"
    type: streamable_http
    uri: "https://extcord.io/mcp"
    timeout: 300

Quality 76 / 100good

protocol88 · weight 25
  • pass
    protocol.modernsupports 2026-07-28 (server/discover)
  • pass
    protocol.statelessanswers without a session
  • pass
    protocol.transportstreamable HTTP
  • warn
    protocol.list_ttltools/list declares ttlMs 0, so clients re-fetch it on every use
authorizationn/a · weight 15
  • n/a
    auth.prm, auth.as_metadata, auth.cimdno remote uses OAuth
  • n/a
    auth.secret_in_urlno templated URL
tool hygiene93 · weight 30
  • pass
    tools.descriptionsevery tool has a description
  • warn
    tools.description_length3 tools have descriptions over 1,024 characters, which crowds the context
  • pass
    tools.schemasevery tool has an object input schema
  • pass
    tools.annotations11 of 11 tools declare readOnlyHint or destructiveHint
  • pass
    tools.directory_hintsevery tool declares readOnlyHint, destructiveHint, idempotentHint and openWorldHint
  • pass
    tools.token_costabout 5,225 tokens to load every tool
  • pass
    tools.api_dumptools are not a one-to-one API dump
stability25 · weight 15
  • warn
    stability.changes27 tool changes in 30 days
  • fail
    stability.rug_pull8 tools kept their name but changed most of their description in 30 days; review before trusting them
dependenciesn/a · weight 15
  • n/a
    deps.known_vulns, deps.mcp_sdk_version, deps.resolvableno npm or PyPI package

11 tools, about 5,225 tokens to load them all · tool set 38fe57a4873d · tools last changed 2026-10-11 · checked 2026-10-20 09:31 UTC

Tool changes

  • inspectremoved

    Look at a handle: its summary, its value one page at a time, or its provenance. Check est_tokens in the summary before reading a big value; it's usually cheaper to narrow it with an op first (find, select, filter, fit).

  • discoverremoved

    Find the right op or recipe for a job. With query: the best matches, led by recipes other agents already proved ("solved_before"). With op: that op's full contract and examples. With no arguments: every op by category with a one-line intent. To read everything at once, use the resource extcord://catalog.

  • package_inforemoved

    A package's latest version, release date, license, Python or Node requirement, summary and links, in one call. The raw registry response this replaces can run to hundreds of thousands of tokens (numpy's PyPI JSON is about 900,000); this answer is about 150. Example: package_info(ecosystem="pypi", name="numpy").

  • datesremoved

    Dates and times done right: models don't know today's date and slip on calendar math; this is exact and DST-aware. now: current date and time in any zone. add: add or subtract days, months (month ends handled) or business days. between: days, weeks, years/months/days and business days between two dates. info: weekday, week number, time zone conversion. e.g. dates(action="add", date="2026-10-07", add={"business_days": 10}).

  • calculateremoved

    Exact arithmetic with no floating-point surprises: 0.1 + 0.2 = 0.3, money strings read as numbers, round half-up, percentages (pct, pct_change), sqrt, sum, mean, median, min, max, comparisons. Use it instead of doing math in your head. Example: calculate(expr="price * qty * (1 + tax/100)", vars={"price": "$19.99", "qty": 3, "tax": 8.25}, places=2) gives 64.92.

  • invokeremoved

    Run any of the 43 ops by id. data: json_parse, get, filter, pick, pluck, sort, unique, count_by, stats; format: to_markdown, to_csv, to_text, join, template; compute: calc, now, date_info, date_add, date_diff, encode, decode, url_parse, validate; html: html_clean, html_to_text, select, extract_links, extract_tables, extract_meta; structure: outline; network: fetch; text: find, contains, slice, fit, chunk, replace, split, regex_extract, normalize, count, diff; integrity: hash. discover(op=<id>) shows an op's args and examples. The result comes back as a handle: the value itself if small, else a preview you can pass to the next op. Example: invoke(op="html_to_text", input="h_...") or invoke(op="json_parse", input="{'a': 1,}", args={"lenient": true}).

  • delete_recipeadded

    Permanently delete a recipe you saved, with its version history and track record, using the edit_key from its first save. Use this to withdraw a recipe that's wrong or no longer needed; to change one, publish a new version with save_recipe and the same key instead. Other agents can no longer run it. Recipes that repaired it stay published and are listed in the reply. The name is retired, never reused, so anyone who refers to it gets a clear 'deleted' error rather than a different pipeline. Built-in recipes can't be deleted; a wrong key, or a name that doesn't match exactly, returns an error and changes nothing.

  • save_recipechangeddescription, input schema, output schema, annotationsmeaning changed
    before

    Give a working pipeline to the commons so any agent can reuse it with run_recipe. With an example it's verified before it's accepted; with expect its track record reflects correct results, not just non-crashing ones. Returns an edit key (keep it) for publishing new versions later.

    after · 20% of words in common

    Publish a pipeline that worked as a public recipe any agent can run with run_recipe, or publish a new version of one you saved before (pass its edit_key). With an example, the recipe is run once (this fetches live pages, counting toward your fetch limit) and only published if it runs without error and meets expect (with no expect, running without error is the test); without an example it's published as unverified. A new version that fails verification is refused and the current version stays live. Recipes are public: never put secrets, personal data or private URLs in steps or examples. The first save returns an edit_key, shown once and not recoverable: keep it to publish versions or delete_recipe later (without it, a recipe can only be superseded by a repair). To fix someone else's broken recipe, save yours under a new name with repairs=<their name>; discover_ops(query=...) then lists yours first. Limited to 10 saves an hour per client; a taken name, a bad key or a failed verification returns the reason and fix.

  • run_recipechangeddescription, input schema, output schemameaning changed
    before

    Run a recipe from the commons in one call. Its result is checked against the recipe's expectations, and the outcome feeds its track record. Built-ins include pypi_package, npm_package and crate_info (package facts), github_readme_outline, page_to_markdown, page_outline, page_links, page_tables and find_on_page.

    after · 16% of words in common

    Run a saved recipe (a named, parameterized pipeline, built in or published by agents) in one call; its result is checked against the recipe's expectations. version runs an earlier version from its history, checked against that version's own expect and recorded on that version. Use this when discover_ops lists a recipe for your job (see solved_before); for single pages and package lookups use read_page and read_package_info, which run the built-in recipes for you, and for your own one-off chain use run_pipeline. params must match the recipe's declared params (see discover_ops(recipe=<name>)); defaults can be left out, and missing or unknown params return the param list. verified.correct=false means it ran but the result looks wrong (often a site changed): verified.advice names any repaired recipe. Each real run is recorded in the recipe's public run statistics (success rate, agents using it); only runs with the recipe's own example can mark it broken. dry_run runs and records nothing. Recipes that fetch count toward 60 fetches a minute. An unknown name returns a did-you-mean.

  • read_handleadded

    Read a stored result (handle) without running anything: view=summary for its type, size, est_tokens and suggested next ops; view=value for the data itself one page at a time (follow next_offset); view=provenance for the ops, args and source URLs that produced it. Use this when a result came back as a preview and you need more of it. Check est_tokens first: for a large value it's usually cheaper to narrow it with run_op (find, select, filter, fit) than to page through it. Handles expire 60 minutes after they're made; an expired or unknown id returns handle_not_found with a suggestion to re-run the step.

Showing the latest 10. Full history: list_changes · trend: quality JSON.

Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed. How it is computed.

Trust 80 / 100

no-repository
provenance45
liveness100
freshness100
hygiene80

+dns-namespace +reachable +uptime-100% +updated-9d-ago -no-repository

Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed. How it is computed.

Endpoints

remoteauthreachableuptime 30dp50protocollast ok
https://extcord.io/mcp streamable-httpnoneyes100%775 ms2026-07-282026-10-20

Tools (11)

calculate_dateread-onlyGet the current date and time, or do calendar math exactly, DST-aware. action=now: the current time in tz. action=add: shifts date by the add object, e.g. {"months": 1} or {"business_days": 10}; month ends are clamped (Jan 31 + 1 month = Feb 28). action=between: the time from date to end, as days (end minus start), weeks, a years/months/days breakdown and business days. Business days are Monday to Friday counted after the start day, with no holidays. If end is earlier, the numbers are negative and the result says "direction": "backward". action=info: weekday, week number and quarter of date, converted to to_tz if given. A date with its own offset keeps it; others are read in tz. Use this instead of guessing today's date or counting days yourself; use calculate_expression for plain numbers. Dates in almost any format are accepted; ambiguous ones like 03/04/2026 are read month-first unless dayfirst=true, and notes say how input was read. Missing or unreadable inputs return an error naming the parameter.
calculate_expressionread-onlyEvaluate an arithmetic expression exactly: + - * / // % ** use rational numbers, not floats, so 0.1 + 0.2 = 0.3, and money strings like "$1,200.50" read as numbers. Roots, logs and exp are computed to 50 significant digits (returned in decimal when a JSON number can't hold them); trig is in radians, at float precision. Use this instead of doing math in your head; use calculate_date for anything with dates or times, and run_op("stats") to summarize a column of data. Pure computation: no network, same answer every time. Unknown names, syntax errors and results over 5,000 digits are refused with a suggested fix. Example: expr="price * qty * (1 + tax/100)", vars={"price": "$19.99", "qty": 3, "tax": 8.25}, places=2 gives 64.92.
delete_recipedestructivePermanently delete a recipe you saved, with its version history and track record, using the edit_key from its first save. Use this to withdraw a recipe that's wrong or no longer needed; to change one, publish a new version with save_recipe and the same key instead. Other agents can no longer run it. Recipes that repaired it stay published and are listed in the reply. The name is retired, never reused, so anyone who refers to it gets a clear 'deleted' error rather than a different pipeline. Built-in recipes can't be deleted; a wrong key, or a name that doesn't match exactly, returns an error and changes nothing.
discover_opsread-onlyFind the op or recipe for a job, or read the details of one. query: best-matching ops, led by solved_before (recipes other agents already proved, with their success rate). op: that op's full contract (args schema, behavior, worked examples). recipe: a recipe's steps, params, expectations, version history and track record. No arguments: every op by category with a one-line intent. Call this before run_op or run_pipeline when you don't know the op id or its args; skip it for jobs the front-door tools (read_page, calculate_expression, calculate_date, read_package_info) already cover. Reads only this server's catalog: no network, no side effects. An unknown op or recipe returns a did-you-mean suggestion. Pass one of query, op or recipe (if several, op wins, then recipe); accepts filters ops by input type, alone or with query. To read everything at once instead, use the resource extcord://catalog.
read_handleread-onlyRead a stored result (handle) without running anything: view=summary for its type, size, est_tokens and suggested next ops; view=value for the data itself one page at a time (follow next_offset); view=provenance for the ops, args and source URLs that produced it. Use this when a result came back as a preview and you need more of it. Check est_tokens first: for a large value it's usually cheaper to narrow it with run_op (find, select, filter, fit) than to page through it. Handles expire 60 minutes after they're made; an expired or unknown id returns handle_not_found with a suggestion to re-run the step.
read_package_inforead-onlyGet a package's latest release from PyPI, npm or crates.io as a few fields (version, license, summary, links and the registry's requirement or download fields) instead of the registry's raw response. Latest release only: there is no version parameter. Use this for those three registries; for any other site use read_page. Reads the live registry each call. Fetches are limited to 60 a minute per client. A name the registry doesn't know comes back as its 404, as an error; if the registry's format changes, a warning field says so. Each call runs a built-in recipe and is recorded in its public run statistics; otherwise nothing is kept except the result's handle, for 60 minutes.
read_pageread-onlyFetch a public web page and return only the part you need instead of the raw HTML. view: markdown (main content, navigation and boilerplate removed), outline (headings), links (all links; query keeps those whose URL or text contains it), tables (one table, chosen by table, as a markdown table), find (only passages mentioning query; query required). Use this for any single page; use read_package_info for PyPI, npm and crates.io, and run_pipeline for multi-step extraction (e.g. filtering a table's rows). Reads the live page each call and doesn't run JavaScript, so pages built in the browser may come back thin. Only public http(s) addresses. Fetches are limited to 60 a minute per client. Errors (unreachable site, non-HTML content, no table at that index) come back with a suggested fix. Each call runs a built-in page recipe and is recorded in its public run statistics; otherwise nothing is kept except the result's handle, for 60 minutes.
run_opread-onlyRun one of the 43 ops by id: returns the value, or for large results a preview and a handle id (h_...) to pass as the next op's input. Ops by category: data: json_parse, get, filter, pick, pluck, sort, unique, count_by, stats; format: to_markdown, to_csv, to_text, join, template; compute: calc, now, date_info, date_add, date_diff, encode, decode, url_parse, validate; html: html_clean, html_to_text, select, extract_links, extract_tables, extract_meta; structure: outline; network: fetch; text: find, contains, slice, fit, chunk, replace, split, regex_extract, normalize, count, diff; integrity: hash. Use this for a single step on data you already have; chain two or more with run_pipeline (only the final result comes back). For a standalone answer prefer the front-door tools: calculate_expression over calc, calculate_date over now and date_*, read_page over fetch. Unsure of an op's args? discover_ops(op=<id>). Handles are kept for 60 minutes. Only fetch touches the network (public addresses only, 60 a minute per client); all ops share a limit of 1200 steps a minute. Wrong arg names or types return the op's expected args and a did-you-mean. Example: run_op(op="json_parse", input="{'a': 1,}", args={"lenient": true}).
run_pipelineread-onlyChain ops in one call: each step is {op, input?, args?, as?, input_type?}, later steps refer to earlier results as "$0", "$name" or paths like "$1[0]", and only the final result comes back while intermediate data stays on the server. Use this when a job takes two or more ops (fetch, then extract, then filter); for one op use run_op, and if a saved recipe already does the job (discover_ops shows solved_before) use run_recipe. dry_run=true checks refs, arg names, types and cost without running anything. Up to 50 steps. A failing step stops the pipeline; the error names the step, reports which steps finished, and suggests the fix. Steps count toward the 1200 steps a minute limit; fetch steps also toward 60 fetches a minute. Example steps: [{"op": "fetch", "args": {"url": "https://example.com/pricing"}, "as": "page"}, {"op": "extract_tables", "input": "$page", "args": {"index": 0}}, {"op": "to_markdown", "input": "$1"}].
run_reciperead-onlyRun a saved recipe (a named, parameterized pipeline, built in or published by agents) in one call; its result is checked against the recipe's expectations. version runs an earlier version from its history, checked against that version's own expect and recorded on that version. Use this when discover_ops lists a recipe for your job (see solved_before); for single pages and package lookups use read_page and read_package_info, which run the built-in recipes for you, and for your own one-off chain use run_pipeline. params must match the recipe's declared params (see discover_ops(recipe=<name>)); defaults can be left out, and missing or unknown params return the param list. verified.correct=false means it ran but the result looks wrong (often a site changed): verified.advice names any repaired recipe. Each real run is recorded in the recipe's public run statistics (success rate, agents using it); only runs with the recipe's own example can mark it broken. dry_run runs and records nothing. Recipes that fetch count toward 60 fetches a minute. An unknown name returns a did-you-mean.
save_recipePublish a pipeline that worked as a public recipe any agent can run with run_recipe, or publish a new version of one you saved before (pass its edit_key). With an example, the recipe is run once (this fetches live pages, counting toward your fetch limit) and only published if it runs without error and meets expect (with no expect, running without error is the test); without an example it's published as unverified. A new version that fails verification is refused and the current version stays live. Recipes are public: never put secrets, personal data or private URLs in steps or examples. The first save returns an edit_key, shown once and not recoverable: keep it to publish versions or delete_recipe later (without it, a recipe can only be superseded by a repair). To fix someone else's broken recipe, save yours under a new name with repairs=<their name>; discover_ops(query=...) then lists yours first. Limited to 10 saves an hour per client; a taken name, a bad key or a failed verification returns the reason and fix.

Schemas: list_tools.

Similar MCP servers

Official server.json
{
  "name": "io.extcord/extcord",
  "title": "Extcord",
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
  "remotes": [
    {
      "url": "https://extcord.io/mcp",
      "type": "streamable-http"
    }
  ],
  "version": "0.7.0",
  "description": "Agent utilities: read big pages without filling context, exact math, dates, parsing. Free."
}