Content
<p align="center">
<img src="https://raw.githubusercontent.com/evidiq/evidiq-vault-mcp/main/assets/evidiq-vault.png" width="200" alt="EVIDIQ Vault" />
</p>
<h1 align="center">EVIDIQ Vault</h1>
<p align="center"><strong>Governed, tamper-evident memory and audit trail for AI agents with 0G Merkle segment sealing.</strong></p>
<p align="center">
Record · Chain · Seal · Audit · Redact — append-only, hash-chained memory logging for autonomous AI agents with SHA-256 prevHash linkage, 0G Merkle segment sealing, retention payload redaction, and secret detection.
</p>
<p align="center">
<a href="https://evidiq.dev">evidiq.dev</a> ·
<a href="https://evidiq.dev/docs/vault">Vault Docs</a> ·
<a href="https://mcp.evidiq.dev/vault/skill.md">Agent Skill</a> ·
<a href="https://github.com/evidiq/evidiq">EVIDIQ Main</a> ·
<a href="https://github.com/evidiq/evidiq-vault-mcp">Vault MCP</a>
</p>
<p align="center">
<a href="https://mcp.evidiq.dev/vault/mcp"><img src="https://img.shields.io/badge/MCP%20Server-Live-6E56CF?style=flat-square" alt="MCP Server live" /></a> <a href="https://0g.ai"><img src="https://img.shields.io/badge/Storage-0G%20Merkle%20Sealing-0284C7?style=flat-square" alt="0G Merkle Sealing" /></a> <a href="https://www.oklink.com/xlayer"><img src="https://img.shields.io/badge/X%20Layer-USDT0-3CCF4E?style=flat-square" alt="X Layer USDT0" /></a> <a href="https://mcp.evidiq.dev/vault/x402"><img src="https://img.shields.io/badge/x402-0.005%E2%80%930.03%20USDT0-2563EB?style=flat-square" alt="x402: 0.005 to 0.03 USDT0" /></a> <a href="https://web3.okx.com/onchainos/dev-docs/payments/service-seller-sdk"><img src="https://img.shields.io/badge/Payments-Official%20OKX%20SDK-121212?style=flat-square&logo=okx&logoColor=white" alt="Official OKX Payment SDK" /></a> <a href="https://www.oklink.com/xlayer/tx/0x7e96398e1f2bae0637af884b55b35cbc82099b8241858a1fdde3ab67c94db4b6"><img src="https://img.shields.io/badge/Settlement-Proven%20on%20X%20Layer-3CCF4E?style=flat-square" alt="Settlement proven on X Layer" /></a> <a href="https://www.okx.ai/agents/9622"><img src="https://img.shields.io/badge/OKX.AI-Agent%20%239622%20Listed-121212?style=flat-square&logo=okx&logoColor=white" alt="OKX.AI Agent 9622 listed" /></a> <a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-3DA639?style=flat-square" alt="License: MIT" /></a>
</p>
---
Autonomous AI agents make decisions, run tools, execute transactions, and update internal memory. Verifying *what* an agent did, in *what* order, under *whose* authority, and proving that logs were not altered after the fact is essential for agent governance.
**EVIDIQ Vault is the governed, tamper-evident memory and audit trail layer for the agent economy.**
It records agent actions in append-only namespaces with SHA-256 hash chaining (`prevHash` linkage), seals range segments to 0G Storage via binary SHA-256 Merkle roots, enforces retention policies through tombstoning payload redaction, intercepts credential leaks, and issues signed audit reports.
> **Launch status: live endpoint, paid calls proven on-chain.** The MCP server is deployed at
> `https://mcp.evidiq.dev/vault/mcp` and paid calls settle through the official OKX
> Payment SDK — see [Proven on-chain](#proven-on-chain). No OKX.AI listing has been
> submitted yet.
## What it does
- **Append-Only Hash Chaining** — Every record is monotonically sequenced and cryptographically linked (`prevHash` points to prior `recordHash`).
- **0G Merkle Segment Sealing** — Compute binary SHA-256 Merkle roots over record ranges and seal to 0G Storage.
- **Retention & Tombstoning** — Redact raw payload contents while preserving `contentDigest` and `recordHash`, ensuring chain continuity checks pass (`INTACT`).
- **Credential & Secret Interception** — Automatic pattern detection rejects private keys, mnemonics, and bearer tokens before they enter the vault.
- **Continuity Audits** — Evaluates namespace logs for `INTACT`, `GAP`, or `BREAK` verdicts with detailed policy violation tracking.
- **Merkle Inclusion Proofs** — Generate and verify Merkle inclusion proofs for individual records within sealed segments.
- **Verifiable Reports** — EIP-191 signed SHA-256 report digests.
- **Pay Per Operation** — Five paid tools cost `0.005–0.03 USDT0`; five discovery and validation tools are free.
## Route to Vault when
Use Vault when an agent needs to **record actions or decisions in governed memory**, **audit namespace continuity**, **seal record segments to 0G Storage**, **enforce payload retention**, **verify Merkle inclusion proofs**, or **generate signed audit reports**.
Do **not** route dependency or package provenance to Vault (use **EVIDIQ Lineage**), and do not route endpoint or Agent Skill security scanning here (use **EVIDIQ Sentinel**). Vault records and proves *what an agent did*; it does not judge the safety of what it is about to use.
## Use it from any agent
```bash
# Read the public Skill document
curl -s https://mcp.evidiq.dev/vault/skill.md
# Inspect current x402 pricing discovery
curl -s https://mcp.evidiq.dev/vault/x402
# Connect the remote MCP server (Claude Code)
claude mcp add --transport http evidiq-vault https://mcp.evidiq.dev/vault/mcp
```
Public endpoints:
| Endpoint | Purpose |
|----------|---------|
| `https://mcp.evidiq.dev/vault/mcp` | Remote MCP transport |
| `https://mcp.evidiq.dev/vault/skill.md` | Agent-readable usage and safety guide |
| `https://mcp.evidiq.dev/vault/x402` | x402 v2 pricing and payment discovery |
| `https://mcp.evidiq.dev/vault/health` | Service health |
| `https://evidiq.dev/docs/vault` | Technical documentation |
## MCP tools
### Paid memory & audit operations
| Tool | Cost | Atomic | Description |
|------|------|-------:|-------------|
| `append_record` | `0.005 USDT0` | `5000` | Append an action or decision record to a governed namespace, hash-chained and secret-scanned |
| `query_records` | `0.01 USDT0` | `10000` | Query bounded records by actor, authority, action, tags, or window, with Merkle inclusion proofs |
| `seal_segment` | `0.015 USDT0` | `15000` | Compute a binary SHA-256 Merkle root across a record range and seal it to 0G Storage |
| `audit_report` | `0.02 USDT0` | `20000` | Audit namespace continuity (`INTACT` / `GAP` / `BREAK`) and report policy violations |
| `enforce_retention` | `0.03 USDT0` | `30000` | Tombstone raw payloads while preserving `contentDigest` and `recordHash` linkage |
### Free preflight and verification
| Tool | Cost | Description |
|------|------|-------------|
| `vault_capabilities` | Free | Engine parameters, namespace limits, secret-scanning rules, and full tool pricing |
| `validate_record` | Free | Validate a record's schema and scan it for secrets **without appending or paying** |
| `estimate_cost` | Free | Return the exact atomic and human-readable price for any paid tool |
| `verify_chain` | Free | Verify hash-chain continuity and genesis linkage across a set of records |
| `get_receipt` | Free | Retrieve a stored record, receipt, or Merkle proof by namespace and sequence |
## Recommended workflow
Settlement happens **before** a paid tool runs, so a malformed argument is still a paid
call. Preflight for free first:
1. `vault_capabilities` — current limits, secret-scanning rules, and prices.
2. `validate_record` — confirm the record's schema and that it carries no secrets. Note
`contentDigest` must be **bare 64-char SHA-256 hex**; a `0x` prefix is rejected.
3. `estimate_cost` — the exact price of the operation you intend to run.
4. One paid call per request.
5. `get_receipt` / `verify_chain` — free re-read and independent verification afterwards.
## Engine limits
| Parameter | Value |
|-----------|-------|
| `maxPayloadBytes` | `65536` |
| `maxTagsPerRecord` | `16` |
| `maxQueryLimit` | `500` |
| `namespacePattern` | `^[a-z0-9][a-z0-9._/-]{2,63}$` |
| Chain format | `v1` — SHA-256 `prevHash` linkage, genesis `prevHash` is all zeros |
## How a Vault append works
1. The record input is validated against the schema and scanned for secrets; a detected credential is rejected before storage.
2. A paid tool clears the x402 v2 payment gate before execution begins.
3. The namespace's current head is read to obtain the previous `recordHash`.
4. The record is canonicalized and hashed; `prevHash` links it to its predecessor.
5. The record is appended durably under a monotonically increasing `seq`.
6. A receipt envelope is returned with a SHA-256 integrity digest and an EIP-191 signature.
7. `seal_segment` can later fix a range of records under a Merkle root anchored to 0G Storage.
## Record and receipt integrity
A paid `append_record` response contains:
- `record` — `seq`, `namespace`, `actor`, `authority`, `action`, `tool`, `contentDigest`, `payload`, `tags`, `prevHash`, and `recordHash`.
- `recordId` — the content-addressed record hash.
- `integrity` — SHA-256 digest over the canonical envelope, plus the EIP-191 signature and signer.
```json
{
"engine": "EVIDIQ-Vault/1.0",
"chainFormatVersion": "v1",
"data": {
"record": {
"seq": 1,
"namespace": "evidiq-sdk-proof",
"actor": "0xd6B658dC6e53444bF9Cba598aFdd21Ede0A62Fb9",
"authority": "operator",
"action": "verify",
"contentDigest": "18b7a227d4c939603fb44112e78be92e434e46cd6abf0ecd92e56e45746cd28d",
"prevHash": "0000000000000000000000000000000000000000000000000000000000000000",
"recordHash": "e81012620100231edcc2488d0571dc0586322e1fc0f95be0cc795b8b5e8aa5ac"
}
},
"integrity": { "algorithm": "SHA-256", "digest": "…" }
}
```
`verify_chain` recomputes each `recordHash` and checks the `prevHash` linkage, so a tampered
or reordered log is detectable without trusting Vault. `enforce_retention` deliberately keeps
`contentDigest` and `recordHash` when it redacts a payload, which is why continuity still
verifies as `INTACT` after redaction.
## Pricing and x402
| Operation | Cost | Token | Network | Atomic |
|-----------|------|-------|---------|-------:|
| `append_record` | `0.005` | USDT0 | X Layer (`eip155:196`) | `5000` |
| `query_records` | `0.01` | USDT0 | X Layer (`eip155:196`) | `10000` |
| `seal_segment` | `0.015` | USDT0 | X Layer (`eip155:196`) | `15000` |
| `audit_report` | `0.02` | USDT0 | X Layer (`eip155:196`) | `20000` |
| `enforce_retention` | `0.03` | USDT0 | X Layer (`eip155:196`) | `30000` |
| `vault_capabilities` | Free | — | — | — |
| `validate_record` | Free | — | — | — |
| `estimate_cost` | Free | — | — | — |
| `verify_chain` | Free | — | — | — |
| `get_receipt` | Free | — | — | — |
Asset: USDT0 (6 decimals) on X Layer (`eip155:196`), contract `0x779ded0c9e1022225f8e0630b35a9b54be713736`.
### Official OKX Payment SDK
Payment verification and settlement run through the **official OKX Onchain OS Payment SDK**:
| Package | Role |
|---------|------|
| [`@okxweb3/x402-core`](https://www.npmjs.com/package/@okxweb3/x402-core) | `OKXFacilitatorClient` (HMAC-SHA256 OKX REST auth) and `x402ResourceServer` |
| [`@okxweb3/x402-evm`](https://www.npmjs.com/package/@okxweb3/x402-evm) | `ExactEvmScheme` — the EVM `exact` scheme server implementation |
The OKX facilitator verifies each authorization and settles it on X Layer; Vault keeps
ownership of the chain format, record signing, Merkle sealing, and retention policy. Each
immutable per-tool price reaches the SDK as an explicit USD₮0 **atomic asset amount**
rather than a USD string, so neither the fee nor its token can be substituted by currency
conversion.
When the facilitator's own confirmation wait elapses it answers `timeout` even though the
transaction it broadcast can still confirm moments later, so Vault resolves that state
through the facilitator's settlement-status lookup rather than discarding a paid call.
Success is only ever reported when the facilitator confirms it.
Integration guide: [OKX Onchain OS — integrate via SDK](https://web3.okx.com/onchainos/dev-docs/payments/service-seller-sdk).
## Proven on-chain
Live paid calls against the deployed endpoint completed the full x402 v2 round trip
through the official OKX facilitator:
| Tool | Amount | Settlement tx | Result |
|------|--------|---------------|--------|
| `append_record` | `0.005 USDT0` (`5000` atomic) | [`0x7e96398e…c94db4b6`](https://www.oklink.com/xlayer/tx/0x7e96398e1f2bae0637af884b55b35cbc82099b8241858a1fdde3ab67c94db4b6) · success | `seq 1`, `recordHash e81012…8aa5ac`, genesis `prevHash` all-zero |
| `audit_report` | `0.02 USDT0` (`20000` atomic) | [`0x2b67c210…525bbb6e`](https://www.oklink.com/xlayer/tx/0x2b67c2109fc799b9d167aa6ebd710b478a56c7ad9f026e07069febcd525bbb6e) · success | verdict `INTACT`, chain links verified, no policy violations |
Flow for both: unpaid call → HTTP 402 + `PAYMENT-REQUIRED` → EIP-3009 signature →
`PAYMENT-SIGNATURE` retry → HTTP 200 + `PAYMENT-RESPONSE` (`status: settled`).
Both receipts are `status 0x1` on X Layer, and both were **broadcast by an OKX facilitator
relayer** rather than by a Vault-held key — the on-chain evidence that settlement really
ran through the official SDK. The appended record was afterwards re-read with the free
`get_receipt`, so the paid write is durable and not merely acknowledged.
Free tools stay ungated and answer `200` without any payment header.
## Architecture
```mermaid
flowchart TB
agent["<b>AI agent</b><br/>MCP client"]
request{"Tool call<br/>free or paid?"}
agent -->|POST /vault/mcp| request
free["Free preflight<br/>capabilities · validate<br/>estimate · verify_chain · get_receipt"]
gate["x402 v2 gate<br/>EIP-3009 exact · pay per operation"]
xlayer[("X Layer<br/>USD₮0 · eip155:196")]
request -->|free helper| free
request -->|paid operation| gate
gate -. verify and settle .-> xlayer
subgraph vault["EVIDIQ Vault trust boundary"]
direction TB
guard["1. Schema + secret guard<br/>keys · mnemonics · bearer tokens"]
chain["2. Append-only chain<br/>SHA-256 prevHash linkage"]
store["3. Durable namespace store<br/>monotonic seq"]
seal["4. Merkle segment sealing<br/>binary SHA-256 root"]
receipt["5. Signed receipt<br/>SHA-256 digest · EIP-191"]
guard --> chain --> store --> seal --> receipt
end
zerog[("0G Storage<br/>sealed segment anchor")]
seal -. anchor .-> zerog
free --> guard
gate --> guard
response["<b>MCP response</b><br/>record + receipt + proofs"]
receipt --> response
classDef client fill:#312e81,stroke:#a78bfa,color:#ffffff,stroke-width:2px;
classDef payment fill:#052e16,stroke:#4ade80,color:#ffffff,stroke-width:2px;
classDef core fill:#0f172a,stroke:#38bdf8,color:#ffffff,stroke-width:2px;
classDef output fill:#4c1d95,stroke:#c4b5fd,color:#ffffff,stroke-width:2px;
class agent,request client;
class free,gate,xlayer payment;
class guard,chain,store,seal,receipt core;
class response,zerog output;
style vault fill:#0f172a,stroke:#38bdf8,color:#e0f2fe,stroke-width:2px;
```
## Security boundaries
- Vault stores caller-supplied records; it never executes caller code and makes no outbound calls on behalf of a record.
- Secret patterns (private keys, mnemonics, bearer tokens) are rejected before a record is written, so the ledger cannot become a credential store.
- Records are canonicalized before hashing, so integrity checks are reproducible across platforms.
- Retention redacts payloads without rewriting hashes, so redaction can never be used to hide a tampered chain.
- EIP-191 signatures prove authenticity and non-repudiation of the attester key.
- The ledger directory is a bind mount owned by the unprivileged container user; the deploy script enforces that ownership on every release.
## Self-host
Requirements: Node.js `22+` and npm.
```bash
npm install
npm run build
npm start
```
Or run the container:
```bash
docker build -t evidiq-vault .
docker run -d --name evidiq-vault -p 3000:3000 \
--env-file .env -v evidiq-vault-data:/app/data/vault evidiq-vault
```
Local routes: `POST /mcp` · `GET /skill.md` · `GET /x402` · `GET /health`
The ledger lives under `VAULT_DATA_DIR` (`/app/data/vault` by default). It must be writable
by the container's `vault` user (uid `10001`) — `deploy/run.sh` does this for you. A
root-owned bind mount fails with `EACCES` on the first append.
### Configuration
Copy `.env.example` to `.env` and set parameters:
```bash
# Server
PORT=3000
HOSTNAME=0.0.0.0
PUBLIC_BASE_URL=https://mcp.evidiq.dev/vault
# Official OKX Payment SDK — all three credentials are required together
OKX_API_KEY=...
OKX_SECRET_KEY=...
OKX_PASSPHRASE=...
OKX_BASE_URL=https://web3.okx.com
# x402 v2 — X Layer mainnet / USDT0 (prices are fixed per tool; no X402_PRICE)
X402_CHAIN=eip155:196
X402_ASSET=0x779ded0c9e1022225f8e0630b35a9b54be713736
X402_PAY_TO=0x2a8efe3093278bb4bd3b2d9c7b5ba992ca4fc9b0
X402_DOMAIN_NAME=USD₮0
X402_DOMAIN_VERSION=1
X402_RPC=https://rpc.xlayer.tech
# Record + segment signing (EIP-191)
VAULT_SIGNER_PRIVATE_KEY=...
VAULT_SIGNER_ADDRESS=0x...
# Durable chain storage
VAULT_DATA_DIR=/app/data/vault
# 0G Storage anchoring for sealed segments
OG_PRIVATE_KEY=...
OG_STORAGE_RPC=https://evmrpc.0g.ai
OG_STORAGE_INDEXER=https://indexer-storage-turbo.0g.ai
```
## Development
```bash
npm install # install dependencies
npm run build # compile TypeScript to dist/
npm test # run the 25-test suite (7 files)
npm run dev # start local watch server
```
## Links
- **Website** — https://evidiq.dev
- **Vault documentation** — https://evidiq.dev/docs/vault
- **Live MCP endpoint** — https://mcp.evidiq.dev/vault/mcp
- **Agent Skill** — https://mcp.evidiq.dev/vault/skill.md
- **x402 discovery** — https://mcp.evidiq.dev/vault/x402
- **Service health** — https://mcp.evidiq.dev/vault/health
- **OKX Payment SDK guide** — https://web3.okx.com/onchainos/dev-docs/payments/service-seller-sdk
- **Settlement proof** — https://www.oklink.com/xlayer/tx/0x7e96398e1f2bae0637af884b55b35cbc82099b8241858a1fdde3ab67c94db4b6
- **EVIDIQ main repository** — https://github.com/evidiq/evidiq
- **x402 Protocol** — https://x402.org
## TypeScript SDK
A typed client for the live endpoint lives in [`sdk/index.ts`](sdk/index.ts) — 10 tools (5 free, 5 paid). Free tools answer a bare call; paid tools run the x402 flow automatically (402 challenge → `pay` hook → replay with the `x-payment` header). No key lives in the file.
```ts
import { VaultClient } from "./sdk/index.js";
const client = new VaultClient(); // endpoint defaults to https://mcp.evidiq.dev/vault/mcp
// free
const caps = await client.callTool("vault_capabilities", {});
// paid — settle the 402 challenge via the constructor's pay hook, or omit it
// to receive a PaymentRequiredError carrying the full x402 v2 challenge
const result = await client.callTool("some_paid_tool", { arg: "value" });
```
The `pay` hook receives the decoded x402 v2 challenge (`{ x402Version, resource, accepts[] }` — payTo, asset, amount) and returns the value for the `x-payment` header, e.g. an EIP-3009 `transferWithAuthorization` settled via the official OKX SDK. Without a hook, paid calls throw `PaymentRequiredError` so the caller can settle however it wants.
## License
MIT © 2026 EVIDIQ — see [LICENSE](./LICENSE). Part of the [EVIDIQ](https://github.com/evidiq/evidiq) trust and execution layer for the AI agent economy.
Connection Info
You Might Also Like
ai-native-pm-os
The exhaustive guide to mastering Claude for Product Managers. Build your...
Train-in-Silence
The first Task-Aware MCP server and automated VRAM calculator for LLM...
stacklit
108,000 lines of code. 4,000 tokens of index. One command makes any repo...
AppClaw
AI-powered mobile automation agent — describe what you want in plain...
pdf-mcp
Production-ready MCP server for PDF processing with intelligent caching....
kotadb
Local-only code intelligence API for AI developer workflows (Bun +...