trackmcp
Back to directory
SPAZIO-GENESI

attest-mcp

View on GitHub

attest-mcp

0 stars JavaScriptOthers Updated Aug 20, 2026

Documentation

attest-mcp

OpenSSF Best Practices

Listed on the official MCP Registry as

`io.github.SPAZIO-GENESI/attest-mcp`.

MCP server and CLI for Spazio Genesi's

attestation service — attest, verify, and check the existence of digital works from

any MCP-capable AI agent (Claude Code, Claude Desktop, etc.) or straight from a

terminal / CI pipeline.

Full privacy: file bytes never leave your device. The fingerprint (SHA-256) is

computed locally, streamed from disk — only the hash and optional metadata are sent.

📖 English documentation: attestazione.spaziogenesi.org/en

— site, developer docs, and tiers/terms are all available in English.

What it does

The attestation service timestamps a file's SHA-256 fingerprint, signs it (HMAC), and

can produce a signed PDF certificate plus an OpenTimestamps proof anchored in Bitcoin.

This server exposes that service as MCP tools, so an agent can attest and verify works

on your behalf without a browser.

Why this, not just an OpenTimestamps wrapper

Several MCP servers can submit a hash to an OpenTimestamps calendar. As far as

we know, this is the only one that hands back a **complete proof of

existence** — a signed PDF certificate, a recognized RFC 3161 timestamp, and

a Bitcoin anchor — for free, with the file's bytes never leaving the

caller's machine. No account, no upload, no paid notarization chain. If you

know of another MCP server with the same combination (full certificate +

free + local hashing), we'd genuinely like to hear about it — open an issue.

Spazio Genesi is an Italian non-profit (ETS – *Ente del Terzo Settore*). The

attestation service behind this package was designed with the EU regulatory

environment in mind, not adapted to it afterwards:

  • GDPR-first, privacy by design: the file itself never reaches our servers —

only its SHA-256 fingerprint (and any metadata you choose to declare) is sent.

  • EU data residency: certificates and proofs are archived on Cloudflare R2

under EU jurisdiction.

  • Recognized timestamping, no single point of trust: every certificate carries

an RFC 3161 timestamp from an AATL-rooted authority (trusted by Adobe and most

PDF readers) *and* an independent Bitcoin anchor via OpenTimestamps.

  • Honest about eIDAS: this is not (yet) an eIDAS qualified trust service —

the signer identity is currently self-signed, and a qualified electronic seal is

a planned but unimplemented upgrade. See the

technical whitepaper for the

full, unvarnished breakdown of what is and isn't guaranteed.

Full tiers and terms: attestazione.spaziogenesi.org/en/condizioni.

Install

Claude Desktop — one command, no manual JSON editing:

bash
npx -y @spazio-genesi/attest-mcp-setup

This finds your `claude_desktop_config.json` (Windows/macOS/Linux), adds the

`attest-mcp` entry, and backs up the original file first. It refuses to touch

anything if the existing file isn't valid JSON — it never guesses. Restart

Claude Desktop afterwards. To remove it again: add `--uninstall`. To preview

without writing: add `--dry-run`.

Claude Code:

bash
claude mcp add attest-mcp -- npx -y @spazio-genesi/attest-mcp

Manual / other clients — add this to your MCP client's config:

json
{
  "mcpServers": {
    "attest-mcp": {
      "command": "npx",
      "args": ["-y", "@spazio-genesi/attest-mcp"]
    }
  }
}

Authentication

Two ways to authenticate, matching the underlying service:

1. API key (for partner integrations, issued manually by Spazio Genesi):

set the `IMGAUTH_API_KEY` environment variable.

2. Device flow (for personal/agent use): call the `authorize` tool with no

arguments. It returns a URL — open it, approve with the human-verification

widget, then call `authorize` again with the returned code. The session

token (24h, 20 attestations) is saved to `~/.config/attest-mcp/credentials.json`

(permissions `600` where supported) and used automatically after that.

Either way, the credential only unlocks the anti-bot check on attestation — the

server-side timestamp, cryptographic signature, and rate limits are unchanged.

Tools

ToolWhat it does
`authorize`Start or continue the device-flow authorization.
`attest_file`Hash a local file (streamed) and attest it.
`get_certificate_pdf`Mint a fresh signed PDF, or recover an already-archived one, saved to disk.
`verify_file`Hash a local file and check it against a declared hash + signature.
`verify_certificate`Verify a certificate's signature without a local file.
`check_anchor`Check/download the OpenTimestamps (Bitcoin) proof.
`service_status`Traffic-light status of the attestation service.

CLI (`sg-attest`)

Same package, no separate install. The CLI is a `bin` alongside the MCP server,

sharing the same hashing/API/config code — same full privacy (streamed local

hash, file bytes never sent), same credentials.

bash
npx -y -p @spazio-genesi/attest-mcp sg-attest attest ./work.png
npx -y -p @spazio-genesi/attest-mcp sg-attest verify ./work.png --hash

(`-p` is required: `sg-attest` is a secondary `bin` of the package, and plain

`npx -y @spazio-genesi/attest-mcp` runs the MCP server instead.)

One advantage over the site: no 1 GB cap. The browser is limited by

WebCrypto (which loads the whole file into memory); this CLI streams from

disk on Node, so it can attest files of any size.

CommandWhat it doesCredential
`attest [--title --author --year --note] [--pdf ]`Hash locally (streamed) → attest → print fingerprint, attestation, HMAC. Nothing is archived and no `/c/` page exists without `--pdf`; only `--pdf ` mints the signed certificate and prints the verification linkYes
`verify [--hash ]`Hash locally; with `--hash`, compares (exit 2 if different); also reports archive/anchor statusNo
`verify-cert --hash --attestazione --hmac [--titolo --autore --anno --note]`Verifies a certificate's HMAC signature, no local file involvedNo
`cert [-o ]`Recovers an already-archived certificateNo
`anchor [-o ]`Checks/downloads the OpenTimestamps (Bitcoin) proofNo
`status`Traffic-light status of the serviceNo
`authorize`Device flow: prints a URL to approve, polls, saves the token
`--version` / `--help`Version (from `package.json`) and usage

Every command accepts `--json` (emits one JSON object on stdout, for scripting)

and `--quiet` (reduces non-essential human-readable output). Errors go to

stderr; the CLI never prints a credential (API key or session token) to

stdout, stderr, or `--json` output — same discipline as the MCP server.

Exit codes (a stable contract, for CI/scripting):

CodeMeaning
`0`Success / positive outcome
`1`Operational error (network, auth, bad input)
`2`Negative verification outcome (hash mismatch, invalid signature)

Authentication is the same as the MCP server: `IMGAUTH_API_KEY` env var, or a

session token saved by `sg-attest authorize` (device flow). There is no

`--key` flag — a credential on the command line ends up in shell history; use

the env var (or a CI secret) instead.

A GitHub Action that uses this CLI to attest build artifacts in CI lives in a

companion repo: `attest-action`.

Standalone binaries (no Node required)

For a machine or CI runner without Node.js, download a pre-compiled `sg-attest`

executable from the Releases page

same commands, same behavior, nothing to install.

OSArchitectureFile
Linuxx64`sg-attest-linux-x64`
Linuxarm64`sg-attest-linux-arm64`
macOSIntel`sg-attest-macos-x64`
macOSApple Silicon`sg-attest-macos-arm64`
Windowsx64`sg-attest-windows-x64.exe`
WindowsARM64`sg-attest-windows-arm64.exe`

Each release also includes `SHA256SUMS.txt`. Verify the download before running it:

bash
sha256sum -c SHA256SUMS.txt --ignore-missing   # Linux/macOS
powershell
(Get-FileHash .\sg-attest-windows-x64.exe -Algorithm SHA256).Hash   # compare by eye to SHA256SUMS.txt

⚠️ The binaries are not code-signed: expect an "unknown publisher" warning

from Windows SmartScreen or macOS Gatekeeper the first time you run one. The

checksum above is the integrity guarantee in the meantime — the binary is

built and published by GitHub Actions

directly from this repo's source, nothing hand-uploaded.

Usage is identical to the npm-installed CLI, just call the file directly:

bash
chmod +x ./sg-attest-linux-x64          # Linux/macOS only
./sg-attest-linux-x64 attest ./work.png --pdf cert.pdf
./sg-attest-linux-x64 status

`npx`/`npm` remain the primary distribution channel (and what `attest-action`

uses in CI) — the binaries are an additional channel, not a replacement.

Build provenance (SLSA/in-toto)

The checksum above answers "is this file intact?" — it says nothing about

*where the bytes came from*. Every release since `v0.4.2` also carries a

signed build provenance attestation

(`actions/attest-build-provenance`, job `release` in

`release-binaries.yml`): cryptographic

proof that the file was built by this repo's own workflow, from a specific

commit and tag, not hand-uploaded or swapped afterward.

The GitHub CLI can verify it, but `gh attestation verify` requires an

authenticated `gh` session even on this public repo (confirmed: it fails

with "please run gh auth login" without one) — a real gap if the point is a

check anyone can run with zero setup:

bash
gh attestation verify sg-attest-linux-x64 --repo SPAZIO-GENESI/attest-mcp

`scripts/verify-provenance.mjs` does the same

verification with no GitHub credentials at all — only the public

attestations REST endpoint (confirmed reachable unauthenticated, even on this

public repo) and the `sigstore`

library, which checks the signature against Sigstore's own public

infrastructure (Rekor, Fulcio, TUF — no account needed there either):

bash
git clone https://github.com/SPAZIO-GENESI/attest-mcp
cd attest-mcp && npm install
node scripts/verify-provenance.mjs ./sg-attest-linux-x64 \
  --repo SPAZIO-GENESI/attest-mcp --tag v0.4.2

Exits `0` on success, `1` if the file doesn't match anything the workflow

actually built (e.g. a single altered byte makes the digest — and therefore

the lookup key itself — no longer match any attestation).

Configuration

Env varDefaultPurpose
`IMGAUTH_API_KEY`API key credential, bypasses the device flow.
`IMGAUTH_BASE_URL``https://imgauth.spaziogenesi.org`Override for local development (`http://localhost:8787`).
`IMGAUTH_CERT_PAGE_BASE``https://attestazione.spaziogenesi.org`Override for the permanent-certificate-page base URL.

Troubleshooting

If your client reports "Server disconnected", check its log first: this server

writes diagnostics to stderr, which MCP clients capture. On Claude Desktop the log

lives in `%APPDATA%\Claude\logs\mcp-server-attest-mcp.log` (Windows) or

`~/Library/Logs/Claude/mcp-server-attest-mcp.log` (macOS).

You should see one line per lifecycle event:

code
[attest-mcp 2026-07-21T11:14:12.948Z] v0.2.2 ready on stdio (node v22.22.2, pid 32316)
[attest-mcp 2026-07-21T11:14:12.965Z] exiting (code 0)
  • `exiting (code 0)` — ordinary shutdown: the client closed stdin. After a laptop

sleep or a client restart this is expected; just restart the client to reconnect.

  • `fatal: …` followed by `exiting (code 1)` — a real crash, with the stack trace on

the preceding line. Please open an issue

with it.

  • No `ready` line at all — the process never started: check that `node` is on PATH

and at least v18 (`node --version`).

stdout carries the JSON-RPC protocol and is never used for logging.

Known limitation

The certificate PDF and its text are in Italian (Spazio Genesi is an Italian

non-profit and the certificate is a legal-facing document). The MCP tool

descriptions and this README are in English for an international audience.

Development

bash
npm install
npm test          # unit tests (hash vectors, CLI argument parsing)
IMGAUTH_BASE_URL=http://localhost:8787 npm start   # MCP server against a local `wrangler dev`
IMGAUTH_BASE_URL=http://localhost:8787 node src/cli.js status   # CLI against the same

`test/cli-smoke.local.mjs` is a local-only harness (not run by `npm test`) that

exercises every `sg-attest` command end-to-end against an isolated `wrangler dev`

imgauth instance — see the header comment in that file for the required env vars.

Security

Report vulnerabilities → `/sicurezza/`

(responsible disclosure policy, safe harbor for good-faith research) — this

repo has no `security.txt` of its own (npm package, no static assets), but

the policy covers the whole project.

Contributing

Bug reports and feature requests: open an issue.

Pull requests are welcome — keep them focused (one change per PR), make sure

`npm test` passes, and explain the "why" in the description, not just the

"what". Test policy: any PR that adds new functionality should add a test

for it under `test/`; `npm run lint` and `npm test` both run in CI on every

push and pull request. For anything that touches the attestation contract itself (hashing,

HMAC verification, the API surface), open an issue first: this client mirrors

a contract owned by imgauth, so

changes need to stay compatible with it.

License

MIT — see LICENSE. This is a client for the attestation service; the

service itself (imgauth) is AGPL-3.0.

Frequently asked questions

What is attest-mcp?

attest-mcp is attest-mcp

How do I install attest-mcp?

Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.

Is attest-mcp open source?

Yes — it is hosted on GitHub at https://github.com/SPAZIO-GENESI/attest-mcp.

Related MCP tools

Run your own MCP server? See who uses it and what to fix.

Measure it with TrackMCP