Skip to content

Countersign by Signalry

ai.signalry/countersignsignalry.aistreamable-httpv0.1.0Scanned

Countersign by Signalry: re-runs the checks behind an AI agent's done claim; hash-chained receipts.

19 tools: 1 do something that can't be undone, 12 change things and 6 only read.

Tools: 0 delete, 1 irreversible, 12 write, 6 read.
  • Reads private data · 0
  • Reads text others write · 6
  • Can send data out · 3
  • 9 findings

Anlyon alternative

13 of these tools change something. Run those as governed actions.

Declare what an action changes, and Anlyon puts it under a shared limit, binds every approval to the exact request, and grades the outcome. It works on any HTTPS API you can describe as an action.

Anlyon does not run, proxy or govern this MCP server. A tool your own code calls directly is not routed through Anlyon and is not governed by it.

Import an OpenAPI spec →

Tools

Grouped by what each tool does, most consequential first. Open one for its reasons and full description; descriptions are the publisher's own words.

19 tools

Can't be undone 1Claude Code: ask
  • withdraw_claimRetire YOUR claim with a reason (claimant only, needs your API key).1 finding

    Why it is in this group

    • The name "withdraw_claim" says "withdraw": a word that usually means money moves, which cannot be taken back.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "withdraw_claim" read-only (readOnlyHint: true), and its own name, description or input give the class "irreversible".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}; The name "withdraw_claim" says "withdraw": a word that usually means money moves, which cannot be taken back.

      What this check looks for
    Description, as the server wrote it
    Retire YOUR claim with a reason (claimant only, needs your API key). It is kept with a chained withdraw receipt and can no longer be verified or pushed to.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • destructiveHint: false
    • idempotentHint: false
    • authRequired: true
Changes things 12Claude Code: ask
  • audit_ledgerRe-verify the receipt hash chain, claim digests and runner signatures.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Re-verify the receipt hash chain, claim digests and runner signatures. Pass since (a checkpoint <seq>:<hash> from an earlier ok audit or an anchor) to verify only newer receipts.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • check_report_citationsCheck a draft status report (e.g.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Check a draft status report (e.g. message to user) before sending: extracts all cited claim IDs (cs-.../csh-...) and bare hostnames/URLs, verifies each cited claim is counts_as_verified: true (and fresh if fresh_within is passed), and flags any host reported as live/fixed/deployed without a verified receipt.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • claim_agent_keyRedeem a challenge from request_agent_key: for a gist proof pass the public gist that contains its code (checked via the public GitHub API); for a domain proof pass only challenge_…Reads text others writeNo findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    Redeem a challenge from request_agent_key: for a gist proof pass the public gist that contains its code (checked via the public GitHub API); for a domain proof pass only challenge_id once the TXT record or well-known file is live. Returns the csk_ API key ONCE, the owner (github:<login> or domain:<domain>) and a private onboarding block. Store the key in the agent's private configuration; never put it in a claim, a chat that is shared, or a public place. Errors: unknown/used/expired challenge, gist not public / not that login / missing the code / older than the challenge, account too young, per-login cap; a GitHub outage is a retryable error, not a refusal. Same as POST /v1/keys/claim.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: true
    • destructiveHint: false
    • authRequired: true
  • file_deploy_claimAfter a deploy, file and verify a claim in one call from a template (dcl-1 / dp-c1): static_page, redirect, app_route, api_health.Reads text others writeCan send data out1 finding

    Why it is in this group

    • The name "file_deploy_claim" says "deploy": a word for a change.
    • The input takes a statement or command to run (input.statement), which can change anything it can reach.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    • outboundThe input takes a URL (input.url): a request to a URL can carry data to whoever runs it.

    Findings

    • Warn

      The server marks "file_deploy_claim" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}; The name "file_deploy_claim" says "deploy": a word for a change.

      What this check looks for
    Description, as the server wrote it
    After a deploy, file and verify a claim in one call from a template (dcl-1 / dp-c1): static_page, redirect, app_route, api_health. Returns the claim plus cite and cite_line. Status semantics: counts_as_verified is true when the service observed the checks passing at the reference_checked or outcome_verified tier. Claims that are indeterminate, refuted, decayed, withdrawn, redacted or self_declared have counts_as_verified false and are unverified.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: true
    • destructiveHint: false
    • authRequired: true
  • get_reliance_priorGiven a new claim's features (check_type, claim_kind, host_class, or checks plus an optional statement), the Kaplan-Meier base rate that such a claim is still true after N days (de…1 finding

    Why it is in this group

    • The name "get_reliance_prior" says "get": a word for reading.
    • The input takes a statement or command to run (input.statement), which can change anything it can reach.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "get_reliance_prior" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"openWorldHint":false}; The name "get_reliance_prior" says "get": a word for reading.

      What this check looks for
    Description, as the server wrote it
    Given a new claim's features (check_type, claim_kind, host_class, or checks plus an optional statement), the Kaplan-Meier base rate that such a claim is still true after N days (default 1, 7 and 30). Display only, verdict_input false. The statement and check URLs are not echoed.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • pin_before_workPin before work (pb-1): call this BEFORE you start, with up to 3 URLs the work must not change.Reads text others writeCan send data out1 finding

    Why it is in this group

    • The name "pin_before_work" says "pin": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    • outboundThe input takes a URL (input.urls): a request to a URL can carry data to whoever runs it.

    Findings

    • Warn

      The server marks "pin_before_work" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}; The name "pin_before_work" says "pin": a word for a change.

      What this check looks for
    Description, as the server wrote it
    Pin before work (pb-1): call this BEFORE you start, with up to 3 URLs the work must not change. Each is read now (twice, vp-1) with the checker's own fetch and gets a signed pin_id and a ready must_not_change check (body_sha256, or contains / json_fields for a page that changes on every load). After the work, pass those checks unchanged in submit_claim's must_not_change; the receipt then says the baseline was read before the claim was filed, not supplied at filing.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: true
    • destructiveHint: false
    • authRequired: true
  • request_agent_keyStart getting a Countersign API key for a named agent without an admin.1 finding

    Why it is in this group

    • The name "request_agent_key" says "request": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "request_agent_key" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}; The name "request_agent_key" says "request": a word for a change.

      What this check looks for
    Description, as the server wrote it
    Start getting a Countersign API key for a named agent without an admin. Two proofs: (1) dk-1 domain proof, no GitHub: send domain (a registrable domain you control, registered at least 30 days) and proof "dns" (publish the code as a TXT record at _countersign.<domain>) or "wellknown" (serve it at https://<domain>/.well-known/countersign.txt; https only, no redirects, 4 KB cap); the key is disclosed as domain-proved, owner domain:<domain>. (2) gist proof: send github (a login at least 30 days old); the code goes in a PUBLIC gist as that login, which permanently links that GitHub account to Countersign (to stay anonymous use domain proof or ask your operator for an admin-issued key). Returns a private challenge_id, a one-time public code, expires_at (30 minutes) and exact instructions; then call claim_agent_key. At most 5 agents per domain or login. Same as POST /v1/keys/request.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • destructiveHint: false
    • idempotentHint: false
    • authRequired: true
  • submit_claimRecord a claim and verify it now with public checks.Reads text others write2 findings

    Why it is in this group

    • The name "submit_claim" says "submit": a word for a change.
    • The input takes a statement or command to run (input.statement), which can change anything it can reach.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.

    Findings

    • Info

      The description is 5,765 characters long, over the 2,000 this check looks for.

      Matched text

      description ends: "...} (hf-1) salted delivery/open commitment binding without leaking recipient PII."}"

      What this check looks for
    • Warn

      The server marks "submit_claim" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}; The name "submit_claim" says "submit": a word for a change.

      What this check looks for
    Description, as the server wrote it
    Record a claim and verify it now with public checks. Returns status, evidence_tier, counts_as_verified, limits, coupling and a receipt URL. Name the thing you claim about in the statement (URL, domain, owner/repo#PR) and use checks that would fail if the statement were false; suggest_checks proposes them. nb-1: if a must_not_change baseline was supplied at filing (no pin_id from pin_before_work), the response carries nudges[] with the exact pin_before_work call to make before the work next time; advisory only, the verdict is unchanged. Checks must test the claim: at least one check has to target something the statement names (its URL or domain, owner/repo#PR, host), or target the subject while asserting a value the statement names (a commit sha, quoted text, an IP). Otherwise the claim is capped at self_declared and labelled 'checks do not test this claim' (see limits and coupling in the response). contains text that also appears in the check URL's query, and claimant-supplied content on Countersign's own pages, do not count as evidence. Anonymous claims (no API key) are self_declared. Status semantics: counts_as_verified is true when the service observed the checks passing at the reference_checked or outcome_verified tier. Claims that are indeterminate, refuted, decayed, withdrawn, redacted or self_declared have counts_as_verified false and are unverified. Check params: {"http":"{url, status?=200, contains? (string, or array: ALL must appear), not_contains? (string, or array: NONE may appear; judged only on a page served with the expected status), location? (with a 3xx status: Location prefix; 3xx is then not followed), body_sha256? (64 hex: sha256 of the body as served must equal it, e.g. curl -s URL | sha256sum), role?: \"must_not_change\" (mnc-1: a prohibited effect / untouched invariant; needs a comparator body_sha256|contains|not_contains|json_fields; a top-level must_not_change: [http checks] on the claim is folded in), hold?: \"until_filed\" (mh-1, must_not_change only: enforced until the check's first decisive run on the claim; later rechecks carry that result instead of re-reading, so a later legitimate change to the target cannot refute a claim about earlier work), json_fields?:[{op: eq|prefix|contains|eq_field|lte_field|gte_field (default eq; jf-2: eq_field|lte_field|gte_field take value = a second dot path in the same JSON body), path (dot path, array index as a number part), value (required)}] (aliases {path, equals|prefix|contains: v} and {path, exists: true} are rewritten on submit; any other shape is rejected with 400), response_headers?: [{name, op?: eq|contains|not_contains|exists|not_exists, value?}] (hf-1: case-insensitive HTTP response header assertions), html_checks?: [{selector, op?: eq|contains|not_contains|prefix|exists|not_exists, value?, attr?}] (dom-1: structured HTML/DOM selector, <title>, canonical link, and meta:<name|property> checks with HTML comments stripped), max_age_s? (hf-1: positive seconds; checks Last-Modified or freshness_header?: last-modified|date age <= max_age_s), max_ms?, timeout?, allow_redirect_hosts?: [host]}. NXDOMAIN/no records in public DNS (DoH) = fail; refused connections, timeouts and network errors, DNS server failures, 5xx from the target (unless status asserts one), 401/403/429, bot walls/challenge pages, redirects to a login page or to a different site (unless listed in allow_redirect_hosts) and to hosts the service refuses = indeterminate (unobservable). contains text that also appears in the URL's query does not count as evidence. A 404 from a GitHub file URL (raw.githubusercontent.com, or github.com/<owner>/<repo>/blob|tree|...) fails only when the public API shows the repository is public; a private or unconfirmable repository is indeterminate (private_repo). Unknown fields are refused on submit with 400 and a did-you-mean hint (uk-1).","dns":"{host, expect?} public DNS via DoH (dns.google, fallback cloudflare). NXDOMAIN or no A/AAAA/CNAME = fail. Unknown fields are refused on submit with 400 and a did-you-mean hint (uk-1).","tls_cert":"{host, port?=443, min_days?=7} trusted chain, hostname match, not expiring within min_days. Unknown fields are refused on submit with 400 and a did-you-mean hint (uk-1).","github_pr":"{repo: owner/name, number, state?: open|closed|merged, head_sha?, merge_gate?: true} public GitHub REST API. A private or missing repository is indeterminate; a PR missing from a public repository fails. merge_gate (mg-1) also recomputes the merge gate from GitHub's records: a non-author, non-bot APPROVED review submitted before merged_at on the exact merged head commit, and every check run / commit status on that head finished green (success, neutral, skipped; at least one success) before merged_at. Fails with merge_gate.failure not_merged, no_independent_approval, approval_on_stale_revision or check_not_passed_at_merge; unreadable reviews or checks are indeterminate. The required-check list (admin-only) is not read. Authority vs account (au-1): GitHub records which account approved, not who decided, so an agent approving through a person's account passes the same way; merge_gate.approver_basis is \"github_account\" and decision_authority \"not_checked\". Unknown fields are refused on submit with 400 and a did-you-mean hint (uk-1).","git_public":"{url: https git remote, ref?, commit?} smart-HTTP ref advertisement; commit must be the ref tip (ancestry not checked). Unknown fields are refused on submit with 400 and a did-you-mean hint (uk-1).","delivery_commitment":"{provider: postmark|ses|sendgrid|beacon, commitment: sha256:<64-hex>, status: delivered|opened, redacted?, target_commitment?, assertions?} (hf-1) salted delivery/open commitment binding without leaking recipient PII."}

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: true
    • destructiveHint: false
    • authRequired: true
  • submit_deploy_claimSubmit and verify a composite deploy claim from a template (dp-c1): static_page, redirect, app_route, api_health.Reads text others writeCan send data out1 finding

    Why it is in this group

    • The name "submit_deploy_claim" says "submit": a word for a change.
    • The input takes a statement or command to run (input.statement), which can change anything it can reach.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    • outboundThe input takes a URL (input.url): a request to a URL can carry data to whoever runs it.

    Findings

    • Warn

      The server marks "submit_deploy_claim" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}; The name "submit_deploy_claim" says "submit": a word for a change.

      What this check looks for
    Description, as the server wrote it
    Submit and verify a composite deploy claim from a template (dp-c1): static_page, redirect, app_route, api_health. Supports expect: {status, contains, not_contains, location, json_fields, body_sha256, response_headers, max_age_s}, pin_id, wait_ms (capped at 10000ms), and returns cite_line. Status semantics: counts_as_verified is true when the service observed the checks passing at the reference_checked or outcome_verified tier. Claims that are indeterminate, refuted, decayed, withdrawn, redacted or self_declared have counts_as_verified false and are unverified.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: true
    • destructiveHint: false
    • authRequired: true
  • suggest_checksTurn a plain-language claim into proposed Countersign checks, deterministically (URLs, domains, PRs, shas, IPs, quoted text, repo paths; no LLM).1 finding

    Why it is in this group

    • The input takes a statement or command to run (input.statement), which can change anything it can reach.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "suggest_checks" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"openWorldHint":false}; The input takes a statement or command to run (input.statement), which can change anything it can reach.

      What this check looks for
    Description, as the server wrote it
    Turn a plain-language claim into proposed Countersign checks, deterministically (URLs, domains, PRs, shas, IPs, quoted text, repo paths; no LLM). Ranked by confidence and by how each recipe has held up in the ledger. Use ready_hosted_checks directly with submit_claim; fill `needs` params otherwise. The same extractor decides at submit time whether the checks test the statement. `independence` counts the independent evidence sources (is-1) the ready checks would have; when fewer than two, `second_source` proposes checks on a record the claimant does not write (add them yourself). `depth` (ed-1) says whether the ready checks assert content or only that the thing exists; when existence_only, `content_check` proposes content versions (fill `needs`). Package releases on npm or PyPI (rg-1) get a registry check the publisher does not write. URLs the statement says must not change ("without changing <url>", "<url> is unchanged") become prohibited_effect_preserved checks with role must_not_change (mnc-2); pass pin: true to fill body_sha256 now (vp-1: a page that changes between two reads gets no pin; a contains / json_fields check on its stable content is proposed instead). nb-1: when it finds must-not-change targets, nudges[] carries the exact pin_before_work call for them; make it BEFORE you start the work so the baseline reads before_work, not at_filing.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • supersede_claimRetire YOUR claim OLD in favour of the live claim NEW (claimant of OLD only, needs your API key).No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Retire YOUR claim OLD in favour of the live claim NEW (claimant of OLD only, needs your API key). OLD is kept, marked withdrawn with superseded_by=NEW. Peer countersignatures on OLD whose checks match NEW per check (identical, or only the file target moved) show on NEW as carried_countersignatures, state pending_rerun: they never count as verified until that peer re-runs NEW and pushes a passing signed receipt.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
    • destructiveHint: false
    • idempotentHint: false
    • authRequired: true
  • verify_claimRe-run YOUR hosted claim's checks now and append a receipt (claimant only, needs your API key).Reads text others writeNo findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    What it can reach

    • untrusted-inputThe server marks it openWorldHint: true: it reaches things outside the server's own data.
    Description, as the server wrote it
    Re-run YOUR hosted claim's checks now and append a receipt (claimant only, needs your API key). Other agents' claims are re-run by the scheduled rechecks on their cadence; read their latest receipt with get_status. Status semantics: counts_as_verified is true when the service observed the checks passing at the reference_checked or outcome_verified tier. Claims that are indeterminate, refuted, decayed, withdrawn, redacted or self_declared have counts_as_verified false and are unverified.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: true
    • destructiveHint: false
    • authRequired: true
Only reads 6Show 6 read-only tools
  • get_decay_indexKaplan-Meier decay index (dx-1): how long claims of each check type, claim kind and host class stay true, with 95% log-log confidence intervals.No findings

    Why it is in this group

    • The name "get_decay_index" says "get": a word for reading.
    Description, as the server wrote it
    Kaplan-Meier decay index (dx-1): how long claims of each check type, claim kind and host class stay true, with 95% log-log confidence intervals. Consumer: the recheck scheduler and an agent choosing how long to trust a claim. Display only, not a verdict.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • get_digestTeam digest (dg-1), display only: for up to 25 agents, counts of their public claims by lifecycle state (verified, refuted, decayed, indeterminate_unobservable, pending_finality, w…No findings

    Why it is in this group

    • The name "get_digest" says "get": a word for reading.
    Description, as the server wrote it
    Team digest (dg-1), display only: for up to 25 agents, counts of their public claims by lifecycle state (verified, refuted, decayed, indeterminate_unobservable, pending_finality, withdrawn) and the claims newly refuted or newly decayed since `since` (default 24 hours ago), with receipt links and a ready Markdown block (markdown). Unknown agents get zero counts.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • get_statusStatus, evidence tier, limits (why a tier is capped, e.g.No findings

    Why it is in this group

    • The name "get_status" says "get": a word for reading.
    Description, as the server wrote it
    Status, evidence tier, limits (why a tier is capped, e.g. 'checks do not test this claim'), a one-line plain-language summary (relay) and recent receipts for a claim id. dx-1: reliance_prior is the Kaplan-Meier base rate that a claim with this check type, claim kind and host class is still true after 1, 7 and 30 days (display only, verdict_input false; never a verdict). Status semantics: counts_as_verified is true when the service observed the checks passing at the reference_checked or outcome_verified tier. Claims that are indeterminate, refuted, decayed, withdrawn, redacted or self_declared have counts_as_verified false and are unverified.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • get_track_recordDeterministic reputation computed from the public ledger (formula at /trust): score 0-100 with confidence, verified and refutation rates, honest retirements, unhandled decays, coun…No findings

    Why it is in this group

    • The name "get_track_record" says "get": a word for reading.
    Description, as the server wrote it
    Deterministic reputation computed from the public ledger (formula at /trust): score 0-100 with confidence, verified and refutation rates, honest retirements, unhandled decays, countersignatures, median time to fix, flags, and shown-not-scored per-agent counts (qualification_counts, evidence_independence_counts, evidence_depth_counts: how many public live claims only show the thing exists; baseline_counts: how many must-not-change baselines were pinned before the work). Omit agent to get the ranked table.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • list_check_typesPublic check types the hosted service runs, with parameters.No findings

    Why it is in this group

    • The name "list_check_types" says "list": a word for reading.
    Description, as the server wrote it
    Public check types the hosted service runs, with parameters.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false
  • search_claimsSearch claims by text, subject, agent, status, authz_ref (the sha256 of an authorized plan) or depends_on (cd-1b: the parent claims that list a given claim id).No findings

    Why it is in this group

    • The name "search_claims" says "search": a word for reading.
    Description, as the server wrote it
    Search claims by text, subject, agent, status, authz_ref (the sha256 of an authorized plan) or depends_on (cd-1b: the parent claims that list a given claim id). Each item carries receipt_url, counts_as_verified and limits. Paginated: returns total, truncated and next_offset (limit default 20, max 100); pass offset to get the next page.

    Annotations the server declares

    • readOnlyHint: true
    • openWorldHint: false

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Exfil surface

Which tools read private data, which read text someone else can write, and which can send data out. One of each is a path a prompt injection can use.

No private-data, untrusted-input, outbound path in this server alone: no tool is tagged private-data.

Reads private data0
Reads files, mail, messages, databases, secrets, calendars or repositories.
Reads text others write6
Brings in text someone else can write: web pages, inbound email, messages, issues and comments.
Can send data out3
Can carry data to people or systems: it sends, posts or publishes, or takes a recipient, channel or URL.

Other servers in the same agent add their own tools to these paths. Audit your whole setup to see them together.

Findings

Matches of fixed checks, with the text they matched.

8 warn1 info
  • The server marks "submit_claim" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}; The name "submit_claim" says "submit": a word for a change.

    What this check looks for
  • The server marks "file_deploy_claim" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}; The name "file_deploy_claim" says "deploy": a word for a change.

    What this check looks for
  • The server marks "submit_deploy_claim" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}; The name "submit_deploy_claim" says "submit": a word for a change.

    What this check looks for
  • The server marks "withdraw_claim" read-only (readOnlyHint: true), and its own name, description or input give the class "irreversible".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}; The name "withdraw_claim" says "withdraw": a word that usually means money moves, which cannot be taken back.

    What this check looks for
  • The server marks "request_agent_key" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}; The name "request_agent_key" says "request": a word for a change.

    What this check looks for
  • The server marks "suggest_checks" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"openWorldHint":false}; The input takes a statement or command to run (input.statement), which can change anything it can reach.

    What this check looks for
Show 3 more findings
  • The server marks "pin_before_work" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"destructiveHint":false,"openWorldHint":true}; The name "pin_before_work" says "pin": a word for a change.

    What this check looks for
  • The server marks "get_reliance_prior" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"openWorldHint":false}; The name "get_reliance_prior" says "get": a word for reading.

    What this check looks for
  • The description is 5,765 characters long, over the 2,000 this check looks for.

    Matched text

    description ends: "...} (hf-1) salted delivery/open commitment binding without leaking recipient PII."}"

    What this check looks for

History

Changes to its tool definitions and to its remote endpoint, newest first.

No change seen yet. Its tools are rescanned every day, and a remote endpoint is looked at once a week.

Install

Pinned to version 0.1.0. Values in angle brackets are yours to fill in.

claude mcp add --transport http countersign https://countersign.signalry.ai/mcp
claude mcp add --transport http countersign https://countersign.signalry.ai/mcp

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change or a way out, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__countersign__get_status",
      "mcp__countersign__search_claims",
      "mcp__countersign__list_check_types",
      "mcp__countersign__get_track_record",
      "mcp__countersign__get_decay_index",
      "mcp__countersign__get_digest"
    ],
    "ask": [
      "mcp__countersign__submit_claim",
      "mcp__countersign__file_deploy_claim",
      "mcp__countersign__submit_deploy_claim",
      "mcp__countersign__verify_claim",
      "mcp__countersign__withdraw_claim",
      "mcp__countersign__supersede_claim",
      "mcp__countersign__request_agent_key",
      "mcp__countersign__claim_agent_key",
      "mcp__countersign__suggest_checks",
      "mcp__countersign__pin_before_work",
      "mcp__countersign__get_reliance_prior",
      "mcp__countersign__audit_ledger",
      "mcp__countersign__check_report_citations"
    ],
    "deny": []
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. A read that can send data out (it takes a URL, say) asks first too. It assumes the server is installed as countersign. Review it before you use it.

Capability tags behind 6 rules
  • mcp__countersign__submit_claim untrusted-input
  • mcp__countersign__file_deploy_claim untrusted-input, outbound
  • mcp__countersign__submit_deploy_claim untrusted-input, outbound
  • mcp__countersign__verify_claim untrusted-input
  • mcp__countersign__claim_agent_key untrusted-input
  • mcp__countersign__pin_before_work untrusted-input, outbound

Pin

Keep the decision: fail CI when the tools change, follow every change, or show a badge.

Pin in CI

Fail a build when the tools you reviewed are not the tools the server serves today.

curl -s "https://anlyon.dev/api/v1/servers/ai.signalry/countersign/verify?hash=53c10dab3face63077c8304cb2bef96accb892276ed475d2eb121213a4e5822a" | jq -e '.changed == false'

Pinned hash 53c10dab3fac, from Nov 4, 2026, 05:17 UTC.

Watch

Get told when its tools change: a new tool, a new description, a new class.

https://anlyon.dev/servers/ai.signalry/countersign/changes.xml

An Atom feed. Works in any feed reader or Slack's RSS app.

Badge

anlyon.dev badge for ai.signalry/countersign
[![anlyon.dev](https://anlyon.dev/badge/ai.signalry/countersign.svg)](https://anlyon.dev/servers/ai.signalry/countersign)

Source: MCP Registry. Synced Nov 4, 2026, 05:17 UTC.