Documentation
Running Zoro
Zoro stands between AI agents and the MCP tools they use. Before an agent touches a tool, Zoro checks that the tool is exactly the version that was examined and approved. If anything has changed, the call does not happen, you see precisely what changed and why it matters, and the event is written to a public record.
Quick start
Zoro runs on your own machine: a daemon (gateway, auditor, registry and ledger writers) and this web app (Console and public pages).
git clone <this repository> zoro && cd zoro
pnpm install
cp .env.example .env # optional: add keys for the AI layer, ENSv2, Hedera and World ID
pnpm dev # daemon on :7420, web on :3000- The daemon prints a one-time Console login link. Open it to sign in; the token lives in
console.tokenin Zoro’s data directory (%LOCALAPPDATA%\Zoroon Windows,~/Library/Application Support/Zoroon macOS,~/.local/share/zoroon Linux). - Open Console → Onboarding. Zoro asks permission to read your MCP client configurations (Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, Gemini CLI, Cline), shows every server, and routes the ones you select through the gateway. Each original file is backed up first and can be restored in one action.
- Restart your MCP client. It now talks to Zoro through the stdio bridge; every tool is fingerprinted, audited and sealed before the agent can see it.
- Try the Attack Lab to watch attacks go through the real enforcement path.
Clients that speak Streamable HTTP can also connect directly to http://127.0.0.1:7420/mcp with the header x-zoro-gateway-token (from gateway.token in the data directory).
Architecture
- Gateway — an MCP server to your clients and an MCP client to each upstream server (stdio or Streamable HTTP). It aggregates and namespaces tools, serves only sealed definitions, and evaluates every call: seal and trust chain, policy, data flows, approvals, then Output Shield on the result.
- Sentinel — deterministic rules, differential analysis against the last sealed version, AI review (two configurations for high-impact tools), dynamic detonation for Lab servers, and an EIP-191 attestation over the verdict package.
- Registry — ENSv2 on Sepolia. Each server namespace gets its own Permissioned Resolver; the Auditor holds text and link roles, publishers only the descriptive keys. Version names resolve by wildcard and
currentis a record link. - Ledger — Hedera Consensus Service topics for public verdicts and Lab records, an organization topic for Merkle commitments over your local audit log, and Hedera Token Service badges burned on revocation.
- Human Seal — World ID 4.0 proofs requested with RP signatures, bound to an action digest, verified server-side, single use per action.
Configuration
Everything is optional. Without keys Zoro still protects you locally; each missing dependency is shown as a degraded state rather than silently skipped.
# Sentinel AI layer and Ask Zoro (Groq free tier, any OpenAI-compatible API works)
GROQ_API_KEY= # free key from console.groq.com; enables AI review and Ask Zoro
SENTINEL_MODEL=openai/gpt-oss-120b
SENTINEL_REQUIRE_AI=true # false = development mode (seals record that AI did not run)
# ENSv2 registry (Sepolia)
ZORO_ENS_ROOT=yourname.eth # a .eth name you own on ENSv2
ENS_OPERATOR_PRIVATE_KEY= # owner of the root; then run: pnpm setup:ens
ZORO_AUDITOR_PRIVATE_KEY= # Auditor role + attestation key (generated if empty)
# Hedera ledger
HEDERA_OPERATOR_ID=0.0.x
HEDERA_OPERATOR_KEY= # then run: pnpm setup:hedera
# World ID (Human Seal)
WORLD_APP_ID=app_…
WORLD_RP_ID=rp_…
WORLD_SIGNING_KEY=…
WORLD_ENVIRONMENT=staging # staging = test identities (World ID Simulator)Registry, ledger and Human Seal
pnpm setup:hedera creates the registry, Lab and organization topics and the badge token, and writes their IDs to .env. pnpm setup:ens deploys a UserRegistry and Permissioned Resolver for your root name through the ENSv2 VerifiableFactory, grants the Auditor role, and registers the Lab namespace. Both are idempotent.
Writes are asynchronous and retried; enforcement never waits for them. Every onchain record in the Console links to its explorer entry (Sepolia Etherscan, the ENS app, HashScan).
Canonicalization (zoro-canon/1)
- The whole definition object is covered — every field the server sent, not a chosen subset.
- Object keys are sorted by UTF-16 code unit order (as in RFC 8785); undefined members are dropped; arrays keep their order; numbers use the shortest round-trip form; null is kept.
- Strings are JSON-escaped only. There is no Unicode normalization, trimming or whitespace folding: invisible, direction-override and homoglyph characters are part of the fingerprint (and are reported separately as findings).
- fingerprint = sha256(
"zoro-canon/1\n" + kind + "\n" + canonicalJson(definition)), where kind is tool, prompt or resource_template. - The manifest root commits to the sorted list of (kind, name, fingerprint) plus the declared server name, version and artifact identity, so added, removed and renamed entries change it.
The implementation is packages/core/src/canonical.ts; Zoro Verify runs the same code in your browser.
Policy evaluation
Rules are evaluated in this order and the strictest outcome wins; the first rule that produced it is recorded as the deciding rule, with the full trace kept for every call: server mode → seal and trust chain → verdict handling → tool permissions → agent rules → high-impact asks → argument constraints → rate limits → time windows → data flows. Observe mode records what would have been decided but never blocks.
Any change that weakens protection — a relaxed action, an expanded allowlist, a raised threshold, a removed rule, observe mode — needs explicit confirmation, and a Human Seal where the policy requires one. Policy simulation replays your recorded calls against a proposed policy before you save it.
Product invariants
- No unverified tool text reaches the model.
- No call runs against an unsealed tool version, unless a verified human overrides that specific action, and the override is recorded.
- Every verdict is independently verifiable.
- Every enforcement decision is explainable.
- User data stays with the user.
- Fail closed, never fail silent.
- No overclaiming.
Threat model
- Rug pulls through description changes: definition pinning and quarantine.
- Rug pulls through code changes on local servers: artifact identity re-checked on every start.
- Tool poisoning and shadowing: deterministic and AI findings; cross-server collision radar.
- Cross-server exfiltration: the data-flow guard labels sources and sinks and holds risky flows for a person.
- Poisoned tool output: Output Shield annotates, redacts or blocks instruction-like content.
- Forged seals and a compromised auditor: role-restricted registry writes, attestations, ledger cross-checks and public disputes.
- Replayed approvals: Human Seals are bound to an action digest and are single use.
Honest limits
- A remote server can change what its code does without changing any definition or version string. Zoro cannot see inside another party’s server; it narrows the gap with identity checks, behavioral baselines, Output Shield, argument constraints and network revocations.
- The data-flow guard sees tool inputs and outputs, not the model’s reasoning. Transformed or encoded data can evade matching.
- Content injection cannot be fully solved by filtering. Output Shield reduces and exposes risk; it does not prevent all prompt injection.
- Dynamic detonation is available only for Attack Lab servers on this platform.
- Out of scope: a fully compromised host, a compromised model inside the client, and clients that connect to servers without going through Zoro (Zoro flags those configurations).
What leaves your machine
- ENS and Hedera receive information about tools — fingerprints, verdicts, hashes, signatures — never your prompts, arguments, results, files or identity.
- Your own activity is anchored only as Merkle roots over your local audit log; individual calls are never written onchain.
- The AI layer receives public tool definitions. Ask Zoro sends your question and the records it reads to the AI provider only when you use it.
- World ID receives the action digest as the proof signal — never the action itself — and Zoro stores only the nullifier for that action.
- Exposure reports are generated entirely on your machine.