Skip to main content
Glama

@ledgerproof/mcp-server

A Model Context Protocol server that lets any MCP client (Claude Desktop, Claude Code, IDEs, agents) issue and verify EU AI Act Article 50 transparency receipts through @ledgerproof/sdk.

LedgerProof implements the IETF SCITT architecture drafts (draft-ietf-scitt-architecture-22) with COSE Receipts (draft-ietf-cose-merkle-tree-proofs-18), and additionally anchors a daily Merkle root to Bitcoin (OP_RETURN). It is an early implementation of live IETF Internet-Drafts — not an RFC, not a standard, not certified, not "SCITT compliant." That precision is deliberate; please keep it in any derived copy.

Issuing a receipt is a real, deliberate action: each receipt's daily Merkle root is anchored to Bitcoin, which costs a Bitcoin transaction fee. Do not wire agents to auto-issue on loose triggers. The bundled ledgerproof_when_to_issue prompt spells out when issuance is (and isn't) appropriate.

Transports

This server speaks the two current MCP transports. The deprecated HTTP+SSE transport is intentionally not used.

  • stdio (default) — for local clients that launch the server as a subprocess.

  • Streamable HTTP (StreamableHTTPServerTransport) — for networked clients. In this mode ledgerproof_issue_receipt requires precomputed_sha256 and rejects raw payloads, so artifact bytes never cross the network.

Related MCP server: @humanaccepted/mcp

Tools

Tool

Purpose

ledgerproof_issue_receipt

Produce an Article-50 record for AI-generated content and register it. Exactly one of artifact or precomputed_sha256, plus aiSystemId, deployerName, contentCategory, etc. Mirrors publishAiArticle50. Returns {sequence, entry_hash, verify_url, anchor_status:"pending"}.

ledgerproof_verify_receipt

Verify by {sequence} (API lookup) or {transparent_statement} (SCITT bundle, trust-minimized §7 check → {issuerSignatureValid, inclusionProofValid, receiptSignatureValid, bitcoinConfirmed, valid}).

ledgerproof_check_anchor

Poll a {sequence} for Bitcoin anchor status (pendinganchored with txid, block, Merkle proof).

ledgerproof_hash_artifact

SHA-256 a {payload} locally so raw content never leaves the machine.

Prompt

  • ledgerproof_when_to_issue — scoped guidance: issue only when deliberately "producing an Article-50 transparency record for AI-generated content," and a reminder that anchoring costs a Bitcoin tx fee, so do not auto-fire on loose triggers.

Honest behavior notes / gaps

  • Anchoring is asynchronous. Issuance always returns anchor_status: "pending". The server never reports a fabricated "anchored" status — ledgerproof_check_anchor reports anchored only when the API returns a real Bitcoin txid. Poll until then.

  • Raw payloads stay local even on stdio. The SDK hashes the artifact locally and only the artifact_hash (never the bytes) is sent to the LedgerProof API. Streamable HTTP additionally keeps the bytes off the MCP hop by requiring precomputed_sha256.

  • SCITT verification is guarded. verifyTransparentStatement lives in the SDK's scitt/ module, which is being built in parallel and may not be exported yet. If it's absent, ledgerproof_verify_receipt (Transparent Statement mode) returns a clear "not available in the installed SDK" error instead of failing the build. Sequence-mode verification works today.

  • precomputed_sha256 issuance depends on an SDK feature. The base publishAiArticle50 always hashes raw bytes and exposes no precomputed-hash entrypoint. The server passes the hash through optimistically (forward-compat); if the installed SDK can't accept it, the tool returns a precise error rather than registering a record with the wrong artifact_hash. Until the SDK adds a precomputed-hash publish path, issue from raw artifact over stdio.

Configuration (environment variables)

Variable

Required

Default

Notes

LEDGERPROOF_PUBLISHER_ID

yes

Legal-entity id (LEI/EUID/VAT/DID). Not an email.

LEDGERPROOF_DEPLOYER_COUNTRY

yes

ISO country code, e.g. DE.

LEDGERPROOF_API_KEY

yes

LedgerProof API key.

LEDGERPROOF_API_BASE

no

https://api-eu.ledgerproofhq.io

API base URL (api-eu.ledgerproofhq.io).

LEDGERPROOF_SIGNING_KEY_HEX

no

ephemeral

Ed25519 signing seed (hex). Never logged.

LEDGERPROOF_KEY_PATH

no

Path to a file containing the hex seed (alt to _HEX).

LEDGERPROOF_KEY_ID

no

default

Key id registered with the service.

HTTP-only (optional): PORT/LEDGERPROOF_MCP_PORT (default 3000), LEDGERPROOF_MCP_HOST (default 127.0.0.1), LEDGERPROOF_MCP_TRANSPORT=http (same as --http).

The Ed25519 signing key is never logged, never returned by any tool, and never serialized. Only its presence (provided vs ephemeral) is printed at boot.

Install / build

npm install
npm run build      # tsc → dist/
npm run lint       # tsc --noEmit

Run

# stdio (default)
npx @ledgerproof/mcp-server

# Streamable HTTP on http://127.0.0.1:3000/mcp
npx @ledgerproof/mcp-server --http --port 3000

MCP client config

stdio

{
  "mcpServers": {
    "ledgerproof": {
      "command": "npx",
      "args": ["-y", "@ledgerproof/mcp-server"],
      "env": {
        "LEDGERPROOF_PUBLISHER_ID": "LEI:5493001KJTIIGC8Y1R12",
        "LEDGERPROOF_DEPLOYER_COUNTRY": "DE",
        "LEDGERPROOF_API_KEY": "sk_live_...",
        "LEDGERPROOF_API_BASE": "https://api-eu.ledgerproofhq.io",
        "LEDGERPROOF_SIGNING_KEY_HEX": "<32-byte-hex-ed25519-seed>",
        "LEDGERPROOF_KEY_ID": "default"
      }
    }
  }
}

Streamable HTTP

Start the server (npx @ledgerproof/mcp-server --http --port 3000), then point the client at the URL:

{
  "mcpServers": {
    "ledgerproof": {
      "type": "streamable-http",
      "url": "http://127.0.0.1:3000/mcp"
    }
  }
}

Over Streamable HTTP, call ledgerproof_hash_artifact first and pass the result to ledgerproof_issue_receipt as precomputed_sha256 — raw payloads are rejected on this transport by design.

License

Apache-2.0

Available Tools

4 tools
ledgerproof_check_anchorCheck Bitcoin anchor statusA
Read-onlyIdempotent

Check whether a receipt's daily Merkle root has been anchored to Bitcoin yet. Returns anchor_status ('pending' or 'anchored') and, when anchored, the Bitcoin txid, block height/hash, and Merkle inclusion proof. Agents should poll this with the receipt's sequence after issuance until anchor_status becomes 'anchored' (the anchor is batched daily, so this can take time).

ParametersJSON Schema
NameRequiredDescriptionDefault
sequenceYesSequence number returned by ledgerproof_issue_receipt.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate idempotent and read-only behavior. The description adds important behavioral context: returns anchor_status, txid, block info, and proof when anchored; notes that anchoring is batched daily so polling may take time. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, well-structured. The first sentence states the core purpose, the second lists return fields, and the third provides usage guidance. No unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple check tool with one input and no output schema, the description covers input, output fields, and polling behavior. It explains what to expect and gives temporal context (daily batching). Complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 100% description coverage for the single parameter 'sequence', explaining it is returned by ledgerproof_issue_receipt. The description mentions 'receipt's sequence' but adds no new semantics beyond referencing the same concept.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: checking whether a receipt's daily Merkle root is anchored to Bitcoin. It uses specific verbs ('check') and identifies the resource ('anchor status of receipt'). Distinguishes from sibling tools by focusing on the check operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance on when to use the tool: after issuance, and recommends polling until status changes. Mentions daily batching, implying patience. Does not explicitly list when not to use or alternative tools, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ledgerproof_hash_artifactHash an artifact (SHA-256)A
Read-onlyIdempotent

Compute the SHA-256 (hex) of a payload using the SDK's hashing. PRIVACY: use this to obtain a precomputed hash so raw payloads never leave the machine — then pass the hash to ledgerproof_issue_receipt as precomputed_sha256. Over Streamable HTTP, issue_receipt REQUIRES precomputed_sha256 and rejects raw payloads, so hash locally first.

ParametersJSON Schema
NameRequiredDescriptionDefault
payloadYesThe content to hash (UTF-8 text). Returned only as a hash.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds context beyond annotations: local operation, privacy benefit, and that hash is returned instead of raw payload.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise sentences front-loading the core function, then usage and context with no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for a simple hashing tool: explains purpose, privacy, integration requirement, and the single parameter is fully documented.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema already describes payload parameter well; description adds that hash is SHA-256 hex and its integration with issue_receipt, providing extra value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it computes SHA-256 hash of a payload, distinguishing it from sibling tools that handle receipts and anchors.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly describes when to use (to obtain precomputed hash for ledgerproof_issue_receipt) and why it's required over Streamable HTTP.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ledgerproof_issue_receiptIssue an Article-50 transparency receiptA

Produce an EU AI Act Article 50 transparency record for a piece of AI-generated content and register it with LedgerProof. Provide EXACTLY ONE of artifact (the raw content; hashed locally, never uploaded) or precomputed_sha256 (a SHA-256 hex you computed yourself), plus the AI-system and deployer metadata. Mirrors the SDK's publishAiArticle50. Returns {sequence, entry_hash, verify_url, anchor_status}. anchor_status is ALWAYS 'pending' on issuance because Bitcoin anchoring is asynchronous (a daily Merkle root is written to an OP_RETURN, which costs a Bitcoin tx fee) — poll ledgerproof_check_anchor until it becomes 'anchored'. Do not issue on loose triggers.

ParametersJSON Schema
NameRequiredDescriptionDefault
artifactNoRaw AI-generated content (text). Hashed locally with SHA-256; the bytes are never sent to the LedgerProof API. Mutually exclusive with precomputed_sha256. Rejected over Streamable HTTP.
precomputed_sha256NoSHA-256 (hex) of the artifact, computed by the caller (e.g. via ledgerproof_hash_artifact). Keeps raw payloads off the wire. Mutually exclusive with artifact. Required over Streamable HTTP.
artifact_content_typeNoMIME type of the artifact, e.g. text/plain, image/png.text/plain
artifact_bytesNoByte length of the artifact. Used with precomputed_sha256 since the raw bytes are unavailable to the server.
aiSystemIdYesIdentifier of the AI system, e.g. 'openai/gpt-4o'.
deployerNameYesLegal name of the deployer organization (not an email/person).
contentCategoryYesArticle-50 content category.
aiSystemVersionNoVersion of the AI system, if known.
supervisoryAuthorityNoRelevant supervisory authority, if applicable.
generationTypeNoHow the content was produced.
sourceContentHashNoSHA-256 of source content for manipulated/assisted media.
perceptualHashNoPerceptual hash (algorithm, value, bits) for media.
transparencyMarkerNoTransparency marker label (defaults to LPR-EU-AI-ACT-50).
isPublicInterestNoWhether the content is in the public interest.
enforcementDateNoArticle-50 enforcement date (defaults to 2026-08-02).
profileVersionNoLPR profile version (defaults to EU-AI-ACT-50-v1.1).

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses critical behavioral traits beyond annotations: the anchor_status is always 'pending' first due to asynchronous Bitcoin anchoring, and it instructs users to poll ledgerproof_check_anchor. It also notes that the artifact is hashed locally and never uploaded. There is no contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single paragraph of six sentences, front-loaded with the core action. Every sentence provides essential information (purpose, parameter rules, async behavior, caution). No redundant or extraneous content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 16 parameters, 3 required, no output schema, the description covers the return fields (sequence, entry_hash, verify_url, anchor_status) and explains the asynchronous nature. It references the SDK and provides guidance on polling. This is sufficient for the complexity of the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3. The description adds meaning beyond schema by explaining the mutual exclusivity of artifact and precomputed_sha256, the context for artifact_bytes, and the difference in usage over Streamable HTTP. These clarifications elevate the score.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool produces an EU AI Act Article 50 transparency record and registers it with LedgerProof. It uses specific verbs ('Produce... and register') and distinguishes itself from siblings like ledgerproof_check_anchor and ledgerproof_verify_receipt by focusing on issuance.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains when to use the tool (issuing a receipt) and provides conditional guidance such as 'Provide EXACTLY ONE of artifact or precomputed_sha256' and 'Required over Streamable HTTP'. It also cautions 'Do not issue on loose triggers.' However, it does not explicitly state when not to use this tool versus alternatives, though the sibling tools are distinct enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ledgerproof_verify_receiptVerify a transparency receiptA
Read-only

Verify a LedgerProof receipt. Provide EITHER {sequence} (looks up the chain entry from the public verifier) OR {transparent_statement} (a SCITT Transparent Statement bundle, verified with the trust-minimized §7 algorithm: issuer COSE_Sign1 signature, RFC 9162 inclusion proof, Transparency-Service receipt signature, and an independent Bitcoin OP_RETURN check). For a Transparent Statement, returns {issuerSignatureValid, inclusionProofValid, receiptSignatureValid, bitcoinConfirmed, valid, recomputedRoot}. The Transparency-Service PUBLIC key (for the receipt signature) is loaded from LEDGERPROOF_TS_PUBLIC_KEY_HEX or fetched from {apiBase}/v1/scitt/ts-key; the Bitcoin txid is taken from the statement wrapper, the txid arg, or a /v1/scitt anchor lookup. SCITT verification requires the SDK's scitt module to be present in the installed build.

ParametersJSON Schema
NameRequiredDescriptionDefault
sequenceNoSequence number of a receipt to verify via the API.
transparent_statementNoA SCITT Transparent Statement (COSE_Sign1 with attached COSE Receipts) in SERIALIZED form: a base64/base64url or hex string, or a wrapper object { transparent_statement: <string>, txid? }. Verified locally (a fully decoded COSE object is not accepted).
txidNoBitcoin transaction id holding the daily-root OP_RETURN, if known. Used for the §7 step-5 witness when not embedded in the statement.
issuer_public_key_hexNoIssuer (publisher) Ed25519 PUBLIC key as 64 hex chars, to verify the Signed Statement signature (step 1). If omitted, the issuer key embedded/kid-resolved in the statement is used if available.
bitcoin_checkNoFor a Transparent Statement, also confirm the daily root in a Bitcoin OP_RETURN via a public source.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses detailed behavioral traits beyond annotations: the §7 algorithm steps, key loading from environment or API, optional Bitcoin check, and dependency on the SDK's scitt module. Annotations indicate readOnlyHint and openWorldHint, and the description adds substantial context without contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is verbose but well-structured: it opens with the core purpose, then explains modes, return values, and key loading. Every sentence adds value, but some details (e.g., 'SCITT verification requires the SDK's scitt module') could be more concise. Still, it is effective and not wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (5 parameters, no output schema, multi-mode behavior), the description is remarkably complete. It explains return fields for transparent_statement, key resolution, optional parameters (txid, issuer_public_key_hex), and dependencies, leaving little ambiguity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Every parameter has a detailed description in the input schema, and the tool description adds further context (e.g., 'looks up the chain entry from the public verifier' for sequence, 'base64/base64url or hex string' for transparent_statement). Schema coverage is 100%, and the description enriches understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Verify a LedgerProof receipt.' It distinguishes between two operational modes (sequence vs transparent_statement) and explains what each does. It is distinct from sibling tools (check_anchor, hash_artifact, issue_receipt) by focusing on verification.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use each mode: provide sequence for API-based chain entry lookup, or transparent_statement for local verification with the §7 algorithm. It does not explicitly exclude alternatives but gives enough context for an agent to decide.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.1
    • First observedledgerproof_check_anchor
    • First observedledgerproof_hash_artifact
    • First observedledgerproof_issue_receipt
    • First observedledgerproof_verify_receipt

TDQS

A4.7/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: hashing content, issuing a receipt, checking Bitcoin anchoring, and verifying a receipt. There is no overlap in functionality.

Naming Consistency5/5

All tool names follow the consistent pattern 'ledgerproof_verb_noun' using snake_case. Verbs and nouns are clear and match the tool's action (hash_artifact, issue_receipt, check_anchor, verify_receipt).

Tool Count5/5

Four tools is well-scoped for the domain of managing AI-generated content receipts. Each tool covers a necessary step in the workflow without unnecessary extras.

Completeness5/5

The tool set covers the full lifecycle: hash content (hash_artifact), issue receipt (issue_receipt), check anchoring status (check_anchor), and verify receipt (verify_receipt). No obvious gaps for the intended purpose.

Maintenance

ActivityStale
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers