accueil / serveurs / Dev & Code / io.extcord/extcord
io.extcord/extcord
serveur MCP (Model Context Protocol) · Extcord 0.7.0
Référencé dans l'annuaire. Seul le pentest comportemental fait foi, et il n'a pas encore été exécuté sur ce serveur.
Est-ce que io.extcord/extcord est sûr ?
Au dernier audit MCP Hub, le serveur MCP « io.extcord/extcord » est classé « Non encore testé ». Référencé dans l'annuaire. Seul le pentest comportemental fait foi, et il n'a pas encore été exécuté sur ce serveur. Le verdict est réévalué en continu ; consultez la fiche pour l'état à jour.
Méthode : MCP Hub analyse la description de chaque outil (couche 1) et, pour le verdict fort, exécute le serveur dans une micro-VM isolée avec leurres et réseau bloqué (couche 2). On publie des noms et des compteurs, jamais le contenu brut renvoyé par un outil.
Les 11 outils
- calculate_date≈ 690 tokens
Get 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.
Paramètres, retour & exemple (7)
Paramètrestz· ? · optionnel
now: the zone to answer in. Others: the zone of dates that don't state one. IANA ("Asia/Tokyo"), offset or abbreviation. Default UTC.add· ? · optionnel
add (required): years, months, weeks, days, hours, minutes, seconds or business_days; negative to subtract.end· ? · optionnel
between: the end date (required).date· ? · optionnel
add, between (start), info: required. e.g. "2026-10-07" or "Oct 7 2026 9am".to_tz· ? · optionnel
info: convert to this zone.action· string · requis · now | add | between | infodayfirst· boolean · optionnel
Read 03/04/2026 as 3 April.
Exemple d'appel{"name": "calculate_date", "arguments": {"action": "now"}}Exemple de retour{"content": [{"type": "text", "text": "…"}], "structuredContent": {"notes": [], "value": {}}} - calculate_expression≈ 588 tokens
Evaluate 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.
Paramètres, retour & exemple (3)
Paramètresexpr· string · requis
Python-style arithmetic; ** is power (^ is refused). Functions: pct(p, x) = p% of x, pct_change(old, new) = (new - old) / old * 100, round(x, places) half-up, floor, ceil, int, abs, sqrt, exp, ln, log(x) natural or log(x, base), log10, log2, pow, factorial, gcd, lcm, comb(n, k), perm(n, k), sin, cos, tan, asin, acos, atan, atan2(y, x), sum, mean, median, min, max. Constants: pi, e, tau, true, false.vars· ? · optionnel
Values for the names used in expr: numbers or numeric strings like "$1,200.50". Any name in expr must be here.places· ? · optionnel
Round the result to this many decimals, half-up.
Exemple d'appel{"name": "calculate_expression", "arguments": {"expr": "texte"}}Exemple de retour{"content": [{"type": "text", "text": "…"}], "structuredContent": {"exact": "texte", "value": "texte", "decimal": "texte", "fraction": "texte"}} - delete_recipe≈ 335 tokens
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.
Paramètres, retour & exemple (2)
Paramètresname· string · requis
The recipe's name.edit_key· string · requis
The edit key returned when you first saved it.
Exemple d'appel{"name": "delete_recipe", "arguments": {"name": "texte", "edit_key": "texte"}}Exemple de retour{"content": [{"type": "text", "text": "…"}], "structuredContent": {"deleted": "texte", "still_available": []}} - discover_ops≈ 682 tokens
Find 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.
Paramètres, retour & exemple (4)
Paramètresop· ? · optionnel
An op id, e.g. 'extract_tables', for its full contract.query· ? · optionnel
Words describing the job, e.g. 'html table to rows' or 'decode base64'.recipe· ? · optionnel
A recipe name, e.g. 'page_tables', for its definition and track record.accepts· ? · optionnel
With or without query: only ops that take this input type (text, html, json, list, table, number, boolean).
Exemple d'appel{"name": "discover_ops", "arguments": {"op": "texte", "query": "texte", "recipe": "texte", "accepts": "texte"}}Exemple de retour{"content": [{"type": "text", "text": "…"}], "structuredContent": {"op": {}, "ops": [], "track": {}, "recipe": {}, "solved_before": [], "ops_by_category": {}}} - read_handle≈ 488 tokens
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.
Paramètres, retour & exemple (4)
Paramètresview· string · optionnel · summary | value | provenancelimit· ? · optionnel
value: page size. Default 4000 characters or 50 items.handle· string · requis
A handle id like h_3f9a1c2b7e, from any earlier result.offset· integer · optionnel
value: where to start, in characters for text or items for lists. Use next_offset from the previous page.
Exemple d'appel{"name": "read_handle", "arguments": {"handle": "texte"}}Exemple de retour{"content": [{"type": "text", "text": "…"}], "structuredContent": {"chain": [], "value": "texte", "handle": "texte", "next_offset": "texte"}} - read_package_info≈ 460 tokens
Get 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.
Paramètres, retour & exemple (2)
Paramètresname· string · requis
Package name, e.g. requests, express, @types/node (scoped), serde. PyPI and crates.io ignore case and treat - and _ alike; npm names must match exactly.ecosystem· string · requis · pypi | npm | crates
pypi (Python), npm (JavaScript) or crates (Rust).
Exemple d'appel{"name": "read_package_info", "arguments": {"name": "texte", "ecosystem": "pypi"}}Exemple de retour{"content": [{"type": "text", "text": "…"}], "structuredContent": {"value": {}, "handle": "texte", "warning": {}}} - read_page≈ 606 tokens
Fetch 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.
Paramètres, retour & exemple (5)
Paramètresurl· string · requis
Public http(s) URL of the page.view· string · optionnel · markdown | outline | links | tables | findquery· ? · optionnel
find: the word or phrase to look for (required). links: keep links whose URL or text contains it.table· integer · optionnel
tables: which table, 0 = first, -1 = last.max_tokens· integer · optionnel
Most tokens to return. markdown is trimmed (and marks the cut); other views return a preview and handle instead.
Exemple d'appel{"name": "read_page", "arguments": {"url": "texte"}}Exemple de retour{"content": [{"type": "text", "text": "…"}], "structuredContent": {"value": "texte", "handle": "texte", "preview": "texte", "warning": {}}} - run_op≈ 728 tokens
Run 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}).
Paramètres, retour & exemple (6)
Paramètresop· string · requis
Op id from the list above, e.g. 'html_to_text'.args· ? · optionnel
The op's arguments, e.g. {"url": "https://example.com"} for fetch.input· ? · optionnel
The data to work on: a handle id (h_...) from an earlier result, or a literal value. Omit for ops that take none (fetch, calc, now).terse· boolean · optionnel
Return only the answer (value, or handle and preview), without steps, hashes or hints.input_type· ? · optionnel
Override the inferred type of a literal input, e.g. 'html' for markup passed as a string.inline_max_tokens· integer · optionnel
Return the value itself when it's at most this many estimated tokens, else a preview. Default 300.
Exemple d'appel{"name": "run_op", "arguments": {"op": "texte"}}Exemple de retour{"content": [{"type": "text", "text": "…"}], "structuredContent": {"value": "texte", "handle": "texte", "result": {}}} - run_pipeline≈ 870 tokens
Chain 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"}].
Paramètres, retour & exemple (5)
Paramètressteps· array · requis
Ordered steps, 1 to 50. A literal string starting with $ is written $$.terse· boolean · optionnel
Return only the answer (value, or handle and preview), without steps, hashes or hints.dry_run· boolean · optionnel
Validate and estimate without running.result_from· ? · optionnel
Which step to return, as a ref like "$2" or "$prices[0]". Default: the last step.inline_max_tokens· integer · optionnel
Return the value itself when it's at most this many estimated tokens, else a preview. Default 300.
Exemple d'appel{"name": "run_pipeline", "arguments": {"steps": []}}Exemple de retour{"content": [{"type": "text", "text": "…"}], "structuredContent": {"steps": [], "valid": true, "value": "texte", "handle": "texte", "result": {}, "totals": {}, "problems": []}} - run_recipe≈ 786 tokens
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.
Paramètres, retour & exemple (6)
Paramètresname· string · requis
Recipe name, e.g. 'page_tables'.terse· boolean · optionnel
Return only the answer (value, or handle and preview), without steps, hashes or hints.params· ? · optionnel
Values for the recipe's params, e.g. {"url": "https://example.com"}. Params with defaults can be left out.dry_run· boolean · optionnel
Return the plan with params filled in, without running or counting anything.version· ? · optionnel
Run this earlier version instead of the current one. discover_ops(recipe=<name>) lists the versions kept.inline_max_tokens· integer · optionnel
Return the value itself when it's at most this many estimated tokens, else a preview. Default 300.
Exemple d'appel{"name": "run_recipe", "arguments": {"name": "texte"}}Exemple de retour{"content": [{"type": "text", "text": "…"}], "structuredContent": {"plan": [], "value": "texte", "handle": "texte", "result": {}, "warning": {}, "verified": {}}} - save_recipe≈ 933 tokens
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.
Paramètres, retour & exemple (10)
Paramètresname· string · requis
3-64 lowercase letters, digits or underscores, e.g. acme_pro_price. Must be new unless edit_key is given.steps· array · requis
Pipeline steps as in run_pipeline, with {{param}} where values vary, e.g. {"op": "fetch", "args": {"url": "{{url}}"}}.author· ? · optionnel
Optional public credit, up to 40 characters.expect· ? · optionnel
What a correct result looks like: type, non_empty, min_items, max_items, min_chars, columns, contains, matches, schema. e.g. {"type": "table", "columns": ["Plan", "Price"]}.params· ? · optionnel
Each {{param}}: {"type": "string", "description": "...", "default"?: ...}. Every {{param}} in steps must be declared.example· ? · optionnel
Param values known to work, e.g. {"url": "https://example.com"}. Used to verify now and to health-check later. Strongly recommended.repairs· ? · optionnel
Name of an existing recipe this one fixes.edit_key· ? · optionnel
To publish a new version of your recipe: the key from its first save.description· string · requis
10-300 characters: what it returns and when to use it. Search matches on this text.result_from· ? · optionnel
Ref of the step to return; default the last.
Exemple d'appel{"name": "save_recipe", "arguments": {"name": "texte", "steps": [], "description": "texte"}}Exemple de retour{"content": [{"type": "text", "text": "…"}], "structuredContent": {"recipe": {}, "edit_key": "texte", "verified": true}}
C'est votre serveur ?
Revendiquez-le sur l'espace créateur (preuve GitHub, domaine ou npm) pour afficher le badge « propriétaire vérifié » et lancer un pentest comportemental à la demande afin d'obtenir le badge « Vérifié ».