# ChainMemory Documentation (Full Content) > Complete technical documentation for ChainMemory — the dedicated public blockchain (Chain ID 202604) for AI memory. > This file contains the full documentation content for consumption by LLMs and AI agents. > Language: English > Generated: 2026-09-15 --- # DOCUMENTATION The sovereign knowledge layer for artificial intelligence. ## VISION ChainMemory is not a memory tool. It is a **sovereign knowledge layer** for AI systems. Every AI model today suffers from the same fundamental limitation: when a conversation ends, everything learned disappears. Context is lost. Decisions are forgotten. Progress resets to zero. ChainMemory exists to solve this permanently. The memories you save are the mechanism. The **Project State** — a structured, versioned, consolidated view of your project's knowledge — is the product. The proof is independent: anyone can verify it without trusting us. And interoperability between any AI model is the consequence. ### What ChainMemory Enables - **Portable consolidated state** — What moves between models is not a pile of conversations: it is the structured state built from them. Decisions in force, open risks, current priorities, working vocabulary. It works with ChatGPT today, Claude tomorrow, and any future model. No vendor lock-in, ever. - **Verifiable continuity** — You can prove that a decision existed at a specific moment in time, to anyone, without trusting us. Every project state carries a cryptographic proof, anchored on-chain. - **Decision audit trail** — Every decision traces back to the conversations that produced it. Full provenance, full accountability. - **Persistent identity for AI workflows** — Your AI assistant doesn't start from zero each session. It inherits the accumulated knowledge of every previous interaction. - **Sovereign knowledge** — You own your data. Not OpenAI, not Anthropic, not Google. Your memories live in your account, and their proof is public: you can verify them yourself, independently of us. **The core insight** Memories are events. The Project State is a materialized view. The anchor is the proof of existence. Together, they form a system where AI knowledge is persistent, portable, structured, and provably authentic. **Memories are the input. State is the output.** Saving conversations is where it starts, not where the value is. A pile of memories is a bigger context window. A **consolidated state** is knowledge you can hand to any model, verify against the chain, and hold someone accountable to. That difference is the whole product. --- ## WHAT IS CHAINMEMORY ChainMemory is a platform for **persistent, portable, and verifiable memory** for artificial intelligence. Every important conversation, every decision, every project context is saved as an individual memory, linked to a project, and anchored with a cryptographic proof anyone can verify. Those memories are the input. What ChainMemory builds from them is the **Project State**: a consolidated, versioned view of what your project knows — decisions in force, open risks, current priorities. That state is what travels between models, and it is what carries the proof. Your AI forgets every time you close the tab. ChainMemory solves that. It works with **ChatGPT, Claude, Gemini, Perplexity** and any model that supports MCP or API. **Three access methods** Chrome Extension (one click from any chat), MCP Server (native integration with Claude Desktop, Cursor and any MCP client), and REST API (full control from your code). **Some operations cost AIC** Reading is always free. Writing a memory, injecting context and consolidating state pay a protocol fee in AIC, the network's native token — half burned, half to the ecosystem treasury. See [Costs](#pricing) for the full schedule. Free AIC is available at the [faucet](https://faucet.chainmemory.ai). --- ## WHY CHAINMEMORY The problem is invisible until you've lost weeks of work Every AI conversation today is a blank slate. The AI doesn't remember what you decided yesterday, what architecture you chose last week, or why you rejected an approach three months ago. Teams using AI accumulate critical knowledge — then lose it when the tab closes. ### Before & after | Scenario | Without ChainMemory | With ChainMemory | | You spend 2 hours with Claude designing a database schema | Close the tab. Next session, Claude has zero memory of the schema. You re-explain everything from scratch. | The decision is saved as a memory. Next session, Claude receives the schema automatically via context injection. | | Your team switches from ChatGPT to Gemini mid-project | All conversation history stays locked in ChatGPT. Gemini starts with nothing. Weeks of context lost. | Gemini receives the full Project State — decisions, risks, milestones, stack — as if it had been there from day one. | | A stakeholder asks "when did we decide to use PostgreSQL?" | You search through hundreds of chat threads hoping to find it. Maybe it was in Slack? Maybe a different AI? | The decision has a hash, a timestamp, and evidence links. You share the verification URL — cryptographic proof. | | Two team members make conflicting architecture decisions using different AIs | Nobody notices until production breaks. No audit trail showing who decided what. | Both decisions are recorded with the memories and agents behind them. Nothing flags the conflict automatically, but whoever consolidates sees both in one Project State and marks which one supersedes the other — with the history kept. | | An auditor asks for proof that a compliance decision was made before the deadline | You have screenshots and "trust me." No tamper-proof evidence. | The state was anchored on-chain at block N. The hash is immutable. The auditor verifies independently. | ### What makes it different Other tools save conversations. ChainMemory saves **knowledge** — structured, verified, and portable. The difference: - **Structured, not raw** — Your AI client turns conversations into decisions, milestones, risks and priorities, each citing the memories behind it. You get a Project State, not a transcript dump. - **Verified, not trusted** — Every state is hashed and anchored on-chain. Anyone can verify independently without relying on ChainMemory's servers. - **Portable, not locked** — Works across ChatGPT, Claude, Gemini, Copilot, Perplexity, and any MCP-compatible tool. Your knowledge moves with you. - **Injected, not searched** — Context is automatically injected into new AI conversations. The AI gets what it needs without you copy-pasting anything. **The 5-minute test** Install the extension, save one memory, switch to a different AI, and inject the context. You'll see your decision arrive intact in under 5 minutes. That's the moment it clicks. --- ## QUICKSTART Store → Retrieve → Verify → Prove in 5 minutes ### Prerequisites - Google Chrome (or any Chromium browser) - A ChainMemory account — [create one here](#account-create) - Your API Key — Extension → Settings → Connection → View ### Option A — Chrome Extension (fastest) 1 #### Install & sign in Download from the [Chrome Web Store](https://chromewebstore.google.com/detail/lniemlpehifeeaeomngaleefagconfmb). Sign in with your account. The extension icon appears in your toolbar. 2 #### Store — save a memory Open any AI chat (ChatGPT, Claude, Gemini). Have a conversation where you make a decision — e.g., "We'll use PostgreSQL for the user database." Click the ChainMemory icon and save. The extension extracts the content and creates a memory linked to your project. 3 #### Retrieve — inject into a new session Open a **different** AI (or a new conversation in the same one). Click the ChainMemory icon → "Inject Context." Your previous decision arrives automatically — the AI now knows about the PostgreSQL choice without you repeating anything. 4 #### Verify — check the hash In the Extension, open Project Brain. You will see your project state with decisions, risks and priorities, plus its on-chain anchor. The state carries a **SHA3-256** hash computed over the canonical JSON of the state itself, domain-separated with `CM_PROJECT_STATE_V` — exactly what the open reference verifier recomputes. 5 #### Prove — anchor on-chain There is nothing to click: your memories are anchored on-chain **automatically**, about 30 seconds after saving. To check it yourself, call `GET /v1/project/:name/state/anchor` — it returns the anchored `state_hash` with its transaction and block, and needs **no API key**. Making a single memory permanently immutable (`seal`) is available through the MCP server and the REST API; the extension does not seal. **Result** You've stored a decision, retrieved it in a different AI, verified its hash, and created an immutable on-chain proof. All in under 5 minutes. ### Option B — MCP Server (for Claude / Cursor) 1 #### Configure MCP Add the ChainMemory MCP server to your Claude Desktop or Cursor configuration. See [MCP Setup](#mcp-setup) for the full config. 2 #### Store In Claude, say: `"Remember: we decided to use PostgreSQL for the user database"`. The MCP tool `chainmemory_remember` fires automatically. 3 #### Retrieve In a new conversation: `"What database did we choose?"`. Claude calls `chainmemory_recall` and returns the stored decision with its evidence chain. 4 #### Verify & Prove Ask for the on-chain proof: `verify_project_state` returns every anchored version with its `state_hash`, anchor id, transaction and block — free, and verifiable by anyone without your API key. To make a single memory permanently immutable, `chainmemory_seal` takes the memory number and your `ai_id`. ### Option C — REST API (full control) bash # 1. Store a memory curl -X POST https://api.chainmemory.ai/v1/memory \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"summary":"Decided to use PostgreSQL for user DB","category":"decision","importance":8}' # 2. Retrieve memories curl https://api.chainmemory.ai/v1/memories/list?project=my-project \ -H "x-api-key: YOUR_API_KEY" # 3. Get project state (includes hash) curl https://api.chainmemory.ai/v1/project/my-project/state \ -H "x-api-key: YOUR_API_KEY" # 4. Verify anchor (public — no auth needed) curl https://api.chainmemory.ai/v1/project/my-project/state/anchor ### Option D — Hermes Agent Hermes Agent is an open-source AI agent framework. Use ChainMemory inside Hermes via the **MCP server** (native tools in chat) or the **cm.py CLI wrapper** (full terminal control). #### Configure MCP Edit `~/.hermes/config.yaml` and add: YAML mcp_servers: chainmemory: command: "python" args: ["C:\\Users\\\\.hermes\\skills\\chainmemory-mcp\\chainmemory_mcp_server.py"] env: CHAINMEMORY_API_KEY: "aic_..." Restart Hermes. Tools appear as `mcp_chainmemory_*` in chat. #### Or use cm.py CLI Install the ChainMemory skill and use `cm save`, `cm recall`, `cm state` from terminal. #### Verify In Hermes chat: *"Remember: we decided to use PostgreSQL"*. Or run `cm whoami` in terminal. **What's next** Explore [how event sourcing works](#concept-event-sourcing), learn about the [trust model](#trust-model), or dive into the [full API reference](#api-auth). --- ## CREATE YOUR ACCOUNT ### Sign Up ChainMemory accounts are created through the Chrome Extension. Your account gives you access to all three integration methods: Extension, MCP Server, and REST API. 1 #### Install the Extension Download from the [Chrome Web Store](https://chromewebstore.google.com/detail/lniemlpehifeeaeomngaleefagconfmb) and click "Add to Chrome". 2 #### Set Up Your API Key Click the ChainMemory icon in your browser toolbar. Pick one of the two options: - **Generate API Key automatically** — creates a free wallet + 1 AIC token in one click. No email, no password. Recommended for new users. - **I already have a key** — paste your existing `aic_...` key to restore your account on this device. 3 #### Your API Key Your key is always available under **Settings → Connection** (click "View"). Copy it — you need it for MCP and API access. **Keep your API Key safe** Your API Key grants full access to your memories and projects. Never share it in public repositories or frontend code. Store it in environment variables or a secrets manager. ### Create Your First Project Projects group related memories together. Each project has its own timeline, consolidated state, and independent on-chain anchor. 1 #### Via the Extension In the extension popup, click "New Project". Enter a slug (lowercase, no spaces — e.g., `my-saas`, `thesis-ml`) and an optional description. Click Create. 2 #### Via the API bash curl -X POST https://api.chainmemory.ai/v1/projects \ -H "x-api-key: your-api-key" \ -H "Content-Type: application/json" \ -d '{"name": "my-saas", "description": "My SaaS product"}' 3 #### Via MCP If you have the MCP server configured, ask your AI: *"Create a new ChainMemory project called my-saas"*. The AI will use the `create_project` tool automatically. **Project naming** Choose descriptive, short slugs. You'll reference them in every API call and MCP interaction. Examples: `chainmemory`, `mobile-app`, `data-pipeline`. ### Credentials Summary | Credential | Where to Find | Used For | | API Key | Generated on first launch or pasted manually | Extension connection, REST API calls, MCP server config | | Project slug | Extension → Projects | All memory operations (save, recall, inject, seal) | **Get free AIC tokens** Visit [faucet.chainmemory.ai](https://faucet.chainmemory.ai) to claim 1 AIC. You'll need AIC to anchor your Project State on-chain. 1 AIC is enough for hundreds of anchor operations. --- ## ARCHITECTURE ChainMemory has a 3-layer architecture: ### Layer 1: Capture The Chrome extension, MCP server, or direct API calls capture content from AI conversations. Content is processed, tagged, and linked to a project. ### Layer 2: Storage & Consolidation Each memory is stored in the episodic database with its SHA-256 hash. An AI model — the client, through the MCP server or the API — proposes structured operations from a 29-op grammar. The server validates them against the grammar's invariants, checks that every cited memory resolves to an anchored event hash, and applies them with a **deterministic builder**: the model proposes, the server decides. Nothing on the server reads memories to extract knowledge on its own. ### Layer 3: On-Chain Verification Each version of a project's consolidated state is anchored on the ChainMemory blockchain, normally within ten minutes of being written (Chain ID 202604). The state hash is recorded in the `ProjectStateAnchor` contract, creating an immutable proof that this state existed at that moment. Pipeline AI Conversation | Extension / MCP / API | Memory (SHA-256 hash) | Client proposes ops, citing memories (MCP / API) | Server validation + deterministic builder | Project State (decisions, milestones, risks, priorities, environment) | Anchor on-chain (tx hash + block number) | Public verification (/v1/project/:name/state/anchor) --- ## HOW CHAINMEMORY COMPARES ChainMemory operates in the emerging space of AI memory infrastructure. Here's how it compares to the major solutions in 2026: ### Overview Matrix | Feature | ChainMemory | Mem0 | Zep / Graphiti | Cognee | Supermemory | Letta | | **Storage model** | Episodic DB + on-chain anchoring | Vector + Graph (hybrid) | Temporal knowledge graph (Neo4j) | Graph + Vector + Relational (poly-store) | Semantic vectors + temporal traces | Hierarchical (core + external) | | **Cryptographic verification** | ✓ Sovereign blockchain | ✗ Centralized | ✗ Centralized | ✗ Centralized | ✗ Local only | ✗ None | | **On-chain proof** | ✓ Merkle roots + tx hash | ✗ | ✗ | ✗ | ✗ | ✗ | | **Cross-model portability** | ✓ Extension + MCP + API | ~ API + MCP | ~ API + MCP | ~ Python SDK | ~ MCP + API | ✗ Tied to framework | | **Structured consolidation** | ✓ Project State built by client ops (decisions, milestones, risks, priorities...) | ✗ Raw facts | ~ Knowledge graph relationships | ~ Pipeline enrichment | ✗ Semantic traces | ~ Manual summarization | | **Temporal awareness** | ✓ Version chain + on-chain timestamps | ~ Basic | ✓ Fact validity windows | ~ Added 2025 | ~ Time-annotated traces | ✗ | | **Decision audit trail** | ✓ Evidence chain with memory refs | ✗ | ~ Provenance tracking | ✗ | ✗ | ✗ | | **Non-developer access** | ✓ Chrome extension (1-click save) | ✗ Developer-only | ✗ Developer-only | ✗ Developer-only | ~ Browser extension | ✗ Developer-only | | **AI identity / attribution** | ✓ Soulbound Tokens (EIP-5192) | ✗ | ✗ | ✗ | ✗ | ✗ | | **Privacy model** | ✓ Plaintext never on-chain: only ciphertext and hashes | ~ Cloud storage (SOC2) | ~ Enterprise: BYOK/BYOM | ✓ Self-hosted | ✓ Fully local | ~ Self-hosted option | | **Open source** | ✓ Fully open | ~ OpenMemory (local only) | ✓ Graphiti (20K+ stars) | ✓ Core engine | ✓ Full stack | ✓ Core | | **Best for** | Audit, compliance, multi-agent traceability | Rapid prototyping, user personalization | Complex agent reasoning, CRM workflows | Enterprise data pipelines, RAG enhancement | Coding agents, local-first memory | Research, long-lived agents | ### Detailed Comparisons #### ChainMemory vs. Mem0 Mem0 focuses on **user personalization** — extracting facts from conversations to build user profiles. ChainMemory focuses on **project knowledge** — extracting decisions, milestones, and risks to build auditable project state. Mem0 is ideal for "remember the user prefers dark mode". ChainMemory is ideal for "prove that this architectural decision was made on May 15 by Claude based on these 5 conversations". #### ChainMemory vs. Zep / Graphiti Zep's Graphiti engine excels at **temporal knowledge graphs** — tracking when facts became valid and when they were superseded, with hybrid retrieval (semantic + BM25 + graph traversal). ChainMemory provides similar temporal supersession semantics but adds a layer Zep doesn't have: **on-chain anchoring**. When you need to prove to a regulator or auditor that a decision existed at a specific time, ChainMemory provides cryptographic proof. Zep provides trust-based assurance. #### ChainMemory vs. Cognee Cognee is a powerful **data processing pipeline** — ingesting 30+ sources, building knowledge graphs with subject-relation-object triplets, supporting multiple graph backends (Neo4j, FalkorDB, NetworkX). ChainMemory is more opinionated: it works only on AI conversation memories, and turns them into **structured project intelligence** (a Project State whose items cite their memories) rather than generic knowledge graph nodes. Cognee is better for RAG enhancement over heterogeneous data. ChainMemory is better for project management and decision traceability. #### ChainMemory vs. Supermemory Supermemory focuses on **semantic memory at scale** — lightweight, fast, runs locally, top-ranked on memory benchmarks (LongMemEval, LoCoMo). ChainMemory is optimized for **structured project knowledge** with blockchain verification. Supermemory is the best choice for coding agents that need fast semantic recall. ChainMemory is the best choice when you need to prove what an AI decided and why. **Key differentiator** ChainMemory is the only solution that combines three capabilities no other tool has together: (1) **structured knowledge extraction** (a versioned Project State whose every item cites the memories behind it, not just raw storage), (2) **cross-model portability** (Extension + MCP + API, not tied to any framework), and (3) **cryptographic verification** (sovereign blockchain with Merkle proofs, not trust-based). Other tools store memories. ChainMemory builds **verifiable project knowledge**. **Not mutually exclusive** ChainMemory can complement other memory tools. Use Supermemory or Mem0 for fast in-session recall, and ChainMemory for permanent, auditable project decisions. The structured Project State from ChainMemory can feed into a knowledge graph like Graphiti for richer reasoning. --- ## COSTS ChainMemory charges protocol fees in **AIC**, the native token of its network. The rule is simple: **reading is always free, writing is not**. Anything that produces a permanent, verifiable record costs something, because that record lives on-chain and stays there. **Getting AIC** Free AIC is available at the [faucet](https://faucet.chainmemory.ai). Creating an account and registering an identity cost nothing. ### Fee schedule | Operation | Fee | Notes | | Save a memory | **0.001 AIC** + on-chain storage | storage grows with the length of the memory — see below | | Inject memories into a chat | **0.1 AIC** | per injection, whatever the number of memories (up to 50) | | Consolidate project state | **0.05 AIC + 0.005 per applied operation** | rejected operations are not charged; if the state does not change, nothing is charged | | Write or roll back a project state directly | **0.1 AIC** | a rollback creates a new version identical to the restored one — history is never mutated | | Seal a memory permanently | **0.001 AIC** | after sealing, a memory can no longer be modified | | Audit one memory | **0.1 AIC** | **free with `dry_run`** | | Audit a project state | **5 AIC** | **free with `dry_run`** — the most expensive operation in the system | | Open an audited role session | **0.001 AIC** | Verifiable Role Contracts | | Everything else | **free** | reading, searching, listing, filtering, tagging, archiving, public verification, anchoring proofs, price quotes, creating an account, registering an identity | **Where the fee goes** Every protocol fee is split in half: **50% is burned** at an address nobody controls, and **50% goes to the ecosystem treasury**. The burned half is irrecoverable by design — not even ChainMemory can retrieve it. That is what makes the supply deflationary with real usage instead of by announcement. ### Why saving costs more when the memory is longer A memory is not only hashed: its **encrypted content is written on-chain**. That is what lets you decrypt it years later from a different device, and what lets a third party confirm the record was not altered. It also means every byte is permanent and consumes network gas. Measured on the live network on 5 August 2026, over 16 real transactions spanning 4 to 17,231 bytes. The total cost of saving a memory is **0.00134 AIC + 0.00000071 AIC per byte of text**. That already includes the 0.001 protocol fee, the gas of the two fee transfers and the gas of the on-chain write. It holds at the current network gas price of 1 gwei; if that price changes, the gas portion scales with it. | Text length | Measured total | | 1,000 bytes | 0.0020 AIC | | 2,000 bytes | 0.0028 AIC | | 5,000 bytes | 0.0049 AIC | | 8,000 bytes | 0.0070 AIC | | 17,000 bytes | 0.0134 AIC | | 19,972 bytes — the ceiling | 0.0155 AIC | **ChainMemory imposes no character limit.** The only ceiling is technical: a single memory must fit in one network transaction. That limit is **20,000 bytes of encrypted content**. Encryption adds exactly 28 bytes (a 12-byte IV and a 16-byte authentication tag), so the real ceiling is **19,972 bytes of text** — about 19,972 characters of plain ASCII, and fewer when the text uses accents, emoji or non-Latin scripts, since those take 2 to 4 bytes each. **Chrome extension, from v3.1.3** The extension shows the cost estimate on the Save button **before** you click, confirms the actual size afterwards, and warns you when a response exceeds what fits in one transaction instead of cutting it. **Versions up to 3.1.2 stored only the first 1,500 characters** of a saved response. If you are on 3.1.2 or earlier, update. ### Check the price before you pay Two operations let you see the exact cost first, at no charge: TOOL quote_inject Which memory ids exist, which do not, total characters, estimated tokens, the exact AIC cost with its burn and treasury split, and whether your balance covers it. Free. TOOL audit_memory · audit_state Pass `dry_run: true` and both return the complete audit result without charging. Pay only when you need the audit on record. ### Plans Protocol fees are independent of your subscription plan: a Free account and an Enterprise account pay the same AIC per operation. What the plan changes is **volume** — how many memories, injections and projects you may hold — and the organization features: role-based access control, member and project keys, and audit trail. Plans and their limits are listed at [chainmemory.ai](https://chainmemory.ai/#pricing). Paid plans also include a monthly allowance of AIC. **Fees are charged on the network, not by us** When an operation is paid, the AIC moves on-chain: half is burned, half reaches the treasury. That transaction is public and irreversible. It is not a charge on a card that can be reversed later — which is exactly why every paid operation shows its cost beforehand, and why auditing has a free dry run. --- ## CONCEPTS ### The Event-Sourcing Model ChainMemory follows an **event-sourcing architecture**. Understanding this pattern is key to understanding the entire system. In traditional systems, you store the current state and overwrite it on each change. In event-sourcing, you store every change as an immutable event, and the current state is derived by replaying those events. In ChainMemory: - **Memories are events** — Each memory is an immutable record of something that happened: a decision was made, a risk was identified, a technology was chosen, a milestone was reached. - **Project State is a view built from those events** — A client reads the memories and proposes operations that cite them; the server validates and applies them, and stores each resulting version. The state is not recomputed automatically from the log: it changes only when a client consolidates. - **The anchor is the proof of existence** — When a Project State is anchored on-chain, the blockchain certifies that this specific materialized view existed at that exact block height. Pattern Memory #1 (event) ─┐ Memory #2 (event) ─┤ Memory #3 (event) ─┼──→ ops from a client ──→ Project State v1 ──→ Anchor (block 120000) Memory #4 (event) ─┤ Memory #5 (event) ─┘ Memory #6 (event) ─┐ Memory #7 (event) ─┼──→ ops from a client ──→ Project State v2 ──→ Anchor (block 123539) Memory #8 (event) ─┘ The memories are the source of truth and never change. Each state version records which memories it relied on, so any item can be traced back to its evidence. The anchor proves which state existed at which block. **Why this matters** Event-sourcing guarantees full traceability. Every decision in your Project State can be traced back to the specific conversation where it originated. Nothing is lost, nothing is overwritten, and the history is always available. ### What is a Memory A memory is the fundamental unit of ChainMemory. It is a fragment of information extracted from an AI conversation that is considered valuable for the project's future. Each memory contains: - **Content** — The text of the conversation or note - **Hash** — SHA-256 of the content, immutable - **Project** — Which project it belongs to - **Tags** — Free-form labels for organization (decision, bug, architecture, idea, etc.). Tags are for your use — the Project State has its own fixed fields (see [Project State](#concept-state)) - **Number** — Sequential within your account (#1, #2...) - **Source** — Where it was saved from (extension, MCP, API) - **Timestamp** — Exact moment of creation ### Projects A project groups related memories. Each project has its own timeline, consolidated state, and independent on-chain anchor. Example projects: `my-saas`, `ml-thesis`, `chainmemory`, `mobile-app`. ### Project State The Project State (also called the Project Brain) is the consolidated, versioned view of a project. It is **not generated by a server-side engine**: a client — an AI model working through `update_project_state` (MCP) or `POST /v1/project/:name/state/ops` (API) — proposes operations, the server validates them against a closed grammar, applies them with a deterministic builder and computes the new `state_hash`. Each item records the memories that justify it. #### What the state contains (schema version 2) | Field | What it holds | Closed values | | **vision**, **phase**, **current_focus** | Where the project is going, the stage it is in, and what matters right now | — | | **decisions** | Choices with a title, a statement and their status | status: `proposed`, `confirmed`, `rejected`, `superseded` | | **milestones** | Deliverables | status: `planned`, `in_progress`, `done` | | **risks** | Identified threats | severity: `low`, `med`, `high` — **not** `medium` or `critical`; status: `open`, `closed` | | **priorities** | Ranked work with a `priority_score` | — | | **open_questions** | Questions and, once resolved, their answer | — | | **assumptions**, **constraints** | What the project takes for granted and the rules it must respect | — | | **vocabulary**, **metrics** | Shared terms and named values | — | | **environment** | Hosts, services, repositories and operating rules | — | | **state_meta** | Version, `consolidated_until_event` watermark and `previous_state_hash` | — | **Closed value sets** A value outside these sets gets the operation rejected. The most common mistake is `"severity": "medium"`: the engine only accepts `low`, `med` or `high`. #### State lifecycle The state is **incremental and append-only**: each consolidation starts from the previous version and applies only the new operations. Every version carries its `state_hash` (SHA3-256 of the canonical state, domain-separated with `CM_PROJECT_STATE_V`) and, in `state_meta`, the hash of the version before it. After it is written, the version's hash is anchored on-chain in the `ProjectStateAnchor` contract, normally within ten minutes. Version chain v85 ──previous_state_hash──▶ v86 ──previous_state_hash──▶ v87 │ │ │ └─ anchorId 89 └─ anchorId 90 └─ anchorId 94 #### Example: what GET /v1/project/:name/state returns (trimmed) JSON { "project": "payment-system", "schema_version": 2, "version": 4, "state_hash": "0x3f8c2a…e91d", "generated_at": "2026-09-13T22:02:35.000Z", "anchor": { "status": "anchored", "onchain_anchor_id": 12, "tx_hash": "0x…", "block_number": 681919 }, "state": { "phase": "beta", "current_focus": "PCI review before opening to the first tenants", "decisions": [ { "id": "dec_0002", "title": "PostgreSQL with RLS for multi-tenancy", "statement": "Row-level security removes tenant filtering from the application layer", "status": "confirmed", "superseded_by": null, "evidence_root": "0x9a41…c07e", "created_version": 2, "updated_version": 3 } ], "milestones": [ { "id": "mil_0001", "title": "Database schema", "status": "done", "evidence_root": "0x5b2d…81fa", "created_version": 1, "updated_version": 2 } ], "risks": [ { "id": "risk_0001", "title": "RLS performance at 100K tenants", "severity": "med", "status": "open", "evidence_root": "0xd7e0…2a19", "created_version": 3, "updated_version": 3 } ], "state_meta": { "version": 4, "consolidated_until_event": 150, "previous_state_hash": "0x7b2e…f4c0" } } } `GET /v1/project/:name/state` requires the owner's API key and always returns the **latest** version. Past versions are verifiable by hash (see [Hash & Verification](#concept-hash)), not re-readable in full through this endpoint. #### Best practices - **Save the memory first, consolidate after** — the state cites memories; a decision that only exists in the operation has no support - **Wait for anchoring before citing** — a plaintext memory gets its `event_hash` when it syncs to the chain, about 30 seconds after being written - **Advance the watermark** — send `consolidated_until_event` with the highest memory number you actually reviewed - **Supersede, don't rewrite** — a replaced decision stays in the state with its status changed, so the history of how the project evolved is kept **Multi-agent state** Several agents can consolidate the same project, each through its own client. Their operations land in one state; the memories cited in each item show which agent contributed the evidence. See [Multi-Agent Systems](#multiagent). ### Evidence Chain When a client proposes an operation it cites the memories that support it in `evidence_memory_ids` — an array of memory numbers. The server resolves each one to its `event_hash` and stores, on the resulting item, the Merkle root of those hashes as `evidence_root`. Operation sent by the client { "op": "add_decision", "title": "Use Clique PoA consensus", "statement": "Proof of Authority gives fast, low-cost anchoring for a sovereign chain", "evidence_memory_ids": [12, 45, 67] } Item stored in the state { "id": "dec_0001", "title": "Use Clique PoA consensus", "statement": "Proof of Authority gives fast, low-cost anchoring for a sovereign chain", "status": "proposed", "evidence_root": "0x028218d0…f082" } This creates a **provenance chain**: - Decision `dec_0001` exists because memories 12, 45 and 67 support it; the consolidation response lists their event hashes - Each memory's `event_hash` is written on-chain when the memory syncs - The `evidence_root` commits to exactly that set of hashes - The state that contains the item has a `state_hash` anchored in `ProjectStateAnchor` **Unresolvable evidence is rejected, not ignored** If any cited memory does not exist, is not yours, or has not been anchored yet, the **whole call** is rejected with `422 evidence_unresolved`, and nothing is written or charged. An operation that cites nothing is accepted but stored with `evidence_root` `0x000…0`: state with no provenance. The chain seals it just the same, because it verifies hashes, not correctness. ### Conflict Resolution Nothing resolves contradictions automatically. There is no engine reading memories and deciding which one wins: the client that consolidates decides, and the grammar makes that decision explicit and auditable. #### Replacing a decision If a newer memory changes direction, the client adds the new decision and marks the old one with `supersede_decision` (`id` of the old one, `by_id` of the new one). Both remain in the state. #### Decision status A decision is created as `proposed`. The client moves it to `confirmed` or `rejected` with `set_decision_status`, and to `superseded` with `supersede_decision`. #### Several agents on the same project Operations are applied on top of whatever version is current when the call arrives; `/state/ops` does not check an expected version. Nothing is lost — every call creates a new version — but an agent working from a stale read can re-add or contradict what another agent just wrote. Read the state immediately before consolidating. Each call accepts up to 100 operations. **No data loss** Superseded and rejected decisions are never deleted. They stay in the Project State with their status changed, preserving how the project's direction evolved. ### State Governance The Project State lifecycle is governed by clear rules: #### Who can consolidate? Only the project owner (the account that created the project) can trigger a consolidation. This ensures that the structured knowledge extraction is always controlled by the data owner. #### When does consolidation happen? Consolidation can be triggered in two ways: - **Client-driven** — an AI model proposes operations through `update_project_state` (MCP) or `POST /v1/project/:name/state/ops` (API). The server validates them and only then do they become state - **No automatic trigger** — consolidation never happens on its own. Nothing is ever written to your state unless a client proposes it #### Can it be reverted? Each consolidation creates a new version (v1, v2, v3...). Previous versions remain accessible. You cannot delete a version, but you can always consolidate again to produce a corrected state. The version chain is append-only. #### Snapshots Every Project State version is a snapshot. The combination of version number + state_hash + on-chain anchor creates a verifiable checkpoint. The owner reads the latest version with `GET /v1/project/:name/state`; the hash and on-chain anchor of any past version are public at `GET /v1/project/:name/state/anchor?version=2` and `GET /v1/verify/:name`. | Action | Who | When | Reversible | | Consolidate | Project owner | Only when a client proposes operations | New version created (append-only) | | Anchor on-chain | Automatic (operator wallet) | Within ~10 minutes of each consolidation | Immutable once anchored | | Archive memory | Project owner | Anytime | Can unarchive | | Read the latest state | Project owner (API key) | Anytime | N/A (read-only) | | Verify any version's hash | Anyone (public endpoint) | Anytime | N/A (read-only) | ### Hash & Verification Each memory generates a SHA-256 hash of its content. This hash is the unique, immutable fingerprint of that memory. Content cannot be modified without changing the hash. The **state hash** is a hash of the complete consolidated state (all decisions, milestones, risks, etc.). This state hash is anchored on the blockchain via a transaction on the `ProjectStateAnchor` contract. #### Public verification Verification in ChainMemory is public and permissionless. Anyone can: - Call `GET /v1/project/:name/state/anchor` (no API key required) - Get the `state_hash` and the `tx_hash` of the transaction - Verify on the [explorer](https://chainmemory.ai/explorer) that the transaction exists - Read the contract directly on the blockchain to confirm the hash matches This proves the project state existed exactly as described at the time of anchoring. It cannot be falsified retroactively. ### Privacy Model A common concern with blockchain-based systems is data exposure. ChainMemory addresses this with a strict separation: **Critical principle** The **plaintext** of a memory never goes on-chain. What is written on-chain is its AES-256-GCM ciphertext together with the state hashes — and without the owner key none of it can be read. #### What is stored where | Data | Location | Access | | Memory content | Encrypted database (off-chain) **and** AES-256-GCM ciphertext on-chain | Plaintext: owner only. Ciphertext: public but unreadable without the key | | Memory hash (SHA-256) | Database + on-chain once the memory syncs (~30 s) | Hash is public but reveals nothing about content | | Project State (structured) | Database (off-chain) | Owner only | | State hash | Blockchain (on-chain) | Public — this is the verifiable proof | | Anchor metadata (tx, block) | Blockchain (on-chain) | Public | A state anchor contains only the hashed project identifier, the version number, the state hash and a timestamp. A memory transaction additionally carries the encrypted content plus its category, importance and plaintext length. From either one it is **impossible to reconstruct the content** without the owner key. This design means ChainMemory can provide cryptographic verification without compromising privacy. The blockchain proves *that* a state existed, not *what* it contained. --- ## BLIND VAULT Every memory system asks you to trust its operator. ChainMemory's blind vault removes that requirement for the memories you choose: the content is encrypted in your browser, with a key derived from twelve words that never leave your device, and the server stores a blob it cannot read. This is not encryption-at-rest with a key the provider holds. It is encryption the provider cannot undo — and below there is a test that proves it, plus an honest account of what the feature does *not* cover. ### How it works - **Twelve words.** A BIP-39 mnemonic is generated in the client, from the official 2048-word list, with a checksum. It is the only thing that can recover your content. - **Seed and key.** The phrase is stretched into a seed with PBKDF2-HMAC-SHA512, and the content key is derived from it with HKDF-SHA256. - **Encryption.** The text is sealed with AES-256-GCM into a versioned envelope: `0x02 || IV || ciphertext || tag`. The client also computes an `event_hash` (SHA-256) for the chain. - **Storage.** The blob is sent to `POST /v1/memory/sealed`. The server charges the usual fee, anchors the hash, and stores bytes it has no way to interpret. - **Recovery.** `GET /v1/memory/:id/blob` returns the blob, and the client decrypts it with the key derived from the same twelve words. No key material is transmitted at any point. Losing the phrase means losing the content — there is no recovery path, by design, because a recovery path is exactly what an operator would need in order to read your memories. ### Endpoints | Method | Path | Does | | POST | `/v1/memory/sealed` | Store an already-encrypted blob | | GET | `/v1/memory/:id/blob` | Retrieve the blob for client-side decryption | #### POST /v1/memory/sealed | Field | Required | Notes | | `blob_b64` | yes | The versioned envelope, base64 | | `event_hash` | yes | SHA-256 computed by the client; what gets anchored | | `plain_len` | yes | Plaintext length, for quota accounting | The fee is the same as for a regular memory. Privacy costs nothing extra. ### What this does and does not protect Four limits, stated plainly, because a privacy claim without its boundaries is worth less than no claim at all: - **Metadata is not encrypted.** Timestamps, sizes, project association and the fact that a memory exists remain visible to the operator — and part of them is public: `GET /v1/memory/:id/verify` returns, without an API key, the category, importance, timestamp, length, `is_sealed` flag, event hash. The ciphertext is not returned by that endpoint, but it is stored on-chain and anyone can read it through the public RPC (`getMemory`); without your twelve words it cannot be decrypted. Only the content is blind. - **Older memories cannot be sealed retroactively.** Memories written before this feature stay readable by the server. There is no migration that makes them blind, because the server would have to read them in order to re-encrypt them. - **Anchoring is still custodial.** The server signs the on-chain anchor. Non-custodial signing belongs to a later phase; until then the operator is trusted to anchor, never to read. - **The phrase is yours to keep.** No reset, no support recovery, no backdoor. #### How to verify the claim yourself Do not take our word for it. Seal a memory, then call the legacy endpoint that decrypts with the operator's own key: ``` curl https://api.chainmemory.ai/v1/memory//decrypted \ -H "x-api-key: $CHAINMEMORY_API_KEY" ``` On a sealed memory it returns `200` with `scheme: "sealed"` and the encrypted blob — never the text. That is the proof: `/decrypted` derives its key from your API key, which is exactly what an operator — or anyone who compromised the server — would have. Faced with a sealed memory it has nothing to decrypt, and all it can hand back are the opaque bytes. The same blob retrieved through `/v1/memory/:id/blob` and decrypted in your client with the twelve words returns the original text. --- ## CHROME EXTENSION ### Installation - Go to the [Chrome Web Store](https://chromewebstore.google.com/detail/lniemlpehifeeaeomngaleefagconfmb) - Click "Add to Chrome" - The ChainMemory icon appears in the extensions bar - Click the icon and choose how to start: **"Generate API Key automatically"** (free, recommended) or **"I already have a key"** to paste an existing one - Claim free AIC at the [faucet](https://faucet.chainmemory.ai) so you can save and inject **There is no key recovery** If you generate a key automatically, save it in a password manager immediately. The key is your identity and your access to your memories. Nobody can restore it for you — not even us. **Current version** **v3.1.3** — removes the character limit on saved responses, shows the cost of each save before you confirm it, and corrects the injection fee shown to the user. See [Changelog](#changelog) for the full history. ### Save Memories From any supported AI chat, the extension adds a **"Save to ChainMemory"** button to the model's responses. One click extracts the text of that response and saves it as a memory. #### What it costs, before you click Hover over the button and it shows the length of the response and the estimated cost — for example `Save · 0.0074 AIC`. After saving, the confirmation reports how many characters were stored and what was charged. Saving costs a **0.001 AIC** protocol fee plus on-chain storage, which grows with length; see [Costs](#pricing). Responses are saved **in full**. The ceiling is what fits in one network transaction: **20,000 bytes of encrypted content**. That is about 20,000 characters of plain ASCII text, but fewer when the text uses accents, emoji or non-Latin scripts, since those take 2 to 4 bytes each. If a response does not fit, the extension tells you instead of cutting it silently. #### Rescue your history You don't have to start from zero. Open a past conversation in **ChatGPT, Claude or Gemini**, scroll so the older messages load, and the "Save to ChainMemory" button appears on each response just as it does on a live chat. Knowledge you accumulated before installing ChainMemory becomes portable memory from day one. **On Perplexity, only the most recent response** Perplexity re-renders its page continuously, so the extension keeps a single Save button at the end of the conversation rather than one per response. Saving older responses there is not supported yet. Bulk saving of past conversations, on every platform, is in development. #### Organizing what you saved The extension popup does not save memories — it organizes them. From there you can filter by project, add or remove tags on individual memories, tag several at once, and archive what you no longer want to see. Archived memories stay on record and remain verifiable; they simply stop appearing in lists and injections. Each saved memory receives: - **Cryptographic fingerprint** — SHA-256 of its text, with no domain separator, unique to its content. Do not confuse it with the Project State hash, which is SHA3-256 domain-separated with `CM_PROJECT_STATE_V` - **Sequential number** within your account (#1, #2, #3...) — your own numbering, not a global one - **Tags** for organization, assigned by you or matched automatically against your projects' keywords - **Category** (decision, learning, milestone, error, state, interaction, or custom — the default when none is given) - **Timestamp** of the moment of saving - **On-chain anchoring**, within about 30 seconds of saving ### Inject Context Before starting a conversation with any AI, ChainMemory can **inject** the context you choose into the chat input, so the new conversation begins with what previous ones established. #### How it works - Click the floating **"Inject memory"** button on any supported platform - The panel lists your memories, filterable by project, with an estimated token count each - Select the ones you want and confirm - The text is inserted at the top of the chat input. If the platform's input cannot be detected — rare, and it happens when a platform changes its HTML — the text is copied to your clipboard instead Injection is **optimistic**: the text arrives immediately and the on-chain payment confirms in the background. It costs **0.1 AIC** per injection, regardless of how many memories you selected, up to 50. If your balance is short, the panel offers to top up at the faucet before charging you. **Price it first** Through the MCP server or the API you can call `quote_inject` to see the exact cost, which ids exist and whether your balance covers it — at no charge — before paying for the injection. ### Project State from the extension One click injects the **consolidated state** of your project into the chat: not a pile of memories, but the structured view built from them. What travels is what is currently true: - **Vision, phase and current focus** — where the project is going and what it is working on now - **Decisions in force** — superseded ones are omitted, with a count so you know they exist - **Open risks** with their severity — closed ones are not injected - **Active priorities**, ordered by score - **Constraints** and **key vocabulary** of the project - **Its on-chain anchor** — block, transaction and an abbreviated `state_hash`, so the model receives the proof along with the content The injected state is capped at 7,000 characters so it fits inside the input box of every supported platform, and **injecting it is free**. Full history — superseded decisions, closed risks, milestones, metrics — stays in the Project State and travels through the MCP server or the API. **The extension reads state; it does not build it** Consolidating memories into a Project State is done by an AI model through the [MCP server](#mcp-setup) or the [API](#api) — that is the "client consolidates, chain verifies" architecture. From the extension you can inject an existing state, not create one. Set the project name in **Settings → Project Brain**; there is no default. ### Supported Platforms The extension injects its buttons into these four platforms: - **ChatGPT** — chatgpt.com and chat.openai.com - **Claude** — claude.ai - **Gemini** — gemini.google.com - **Perplexity** — perplexity.ai (saving limited to the most recent response) **Other clients, through the MCP server** The extension is one of three access methods, and it covers web chats. Any MCP-compatible client reaches the same account and the same memories without the extension: **Claude Desktop**, **Cursor**, **Hermes Agent** and **OpenClaw** among them. See [MCP Server](#mcp-setup). Permissions the extension requests, and why: | Permission | What it is for | | `storage` | keep your API key and settings | | `clipboardWrite` | fallback when a platform's input box cannot be detected | | access to the four platforms | insert the Save button and the memory panel into the page | | access to `chainmemory.ai`, `api.chainmemory.ai`, `faucet.chainmemory.ai` | talk to the API and open the faucet | No analytics, no telemetry, no ads. Your API key is stored in `chrome.storage.sync`, which Chrome syncs across the browsers signed into your Google account. --- ## MCP SERVER ### Configuration The MCP server lets Claude Desktop, Cursor, Windsurf, Hermes Agent, OpenClaw and any MCP-compatible client use ChainMemory as a native tool. #### Installation Add this configuration to your `claude_desktop_config.json`: JSON { "mcpServers": { "chainmemory": { "command": "npx", "args": ["-y", "chainmemory-mcp"], "env": { "CHAINMEMORY_API_KEY": "your-api-key" } } } } Restart the client afterwards. Publishing a new version to npm does not update clients that are already running: the package is fetched when the client starts. **Get your API Key** In the Chrome extension, click **"View key"** to see and copy the full key. The Settings tab shows it abbreviated, for identification only. **External service** ChainMemory is an independent protocol. It is not part of Claude, ChatGPT, Cursor or any AI provider. Any MCP-compatible client connects with an API key. Your memories belong to you, not to the AI provider. ### Available Tools The current version exposes **36 tools**. Reading is free; the operations that cost AIC are marked. See [Costs](#pricing) for the full schedule. #### Memory | Tool | What it does | Cost | | `chainmemory_remember` | Save a memory linked to a project, with tags, category and importance (1–10) | 0.001 AIC + storage | | `chainmemory_recall` | Return your most recent memories, newest first. It does **not** search — it lists. Returns 80-character previews | free | | `search_memories` | **Semantic** search over your memories, returning the full text of each match | free | | `get_memory` | Read one memory in full, decrypted from chain, with an integrity check against its anchored hash | free | | `list_memories_filtered` | List memories by project and archived status. Returns 80-character previews | free | | `update_memory_tags` | Replace the tags of a memory | free | | `archive_memory` · `unarchive_memory` | Hide a memory from lists and injections, or restore it. It stays on record either way | free | | `chainmemory_seal` | Seal **one memory** permanently on-chain so it can no longer be modified. Requires a wallet key | 0.001 AIC | #### Verification | Tool | What it does | Cost | | `get_memory_proof` | The shareable anchoring proof of a memory: its `event_hash` and on-chain coordinates. A third party verifies it **without your API key**, and the content is never exposed | free | | `verify_project_state` | Public, unauthenticated proof of a Project State: every anchored version with its `state_hash`, anchor id, transaction and block, plus how to check them yourself in the contract | free | | `audit_memory` | Forensic audit of one memory: recomputes its hash from the stored content and compares it against the anchored one | 0.1 AIC — **free with `dry_run`** | | `audit_state` | Full audit of a Project State: recomputes the `state_hash` with the deterministic engine and returns the anchor plus version history | 5 AIC — **free with `dry_run`** | #### Project State | Tool | What it does | Cost | | `get_project_state` | The consolidated state: vision, phase, current focus, decisions, risks, assumptions, open questions, priorities, constraints, metrics, vocabulary and working environment — plus its `state_hash` and on-chain anchor. Pass `include_roles: false` to omit the text of the role contracts | free | | `update_project_state` | Propose operations from the 29-op grammar. The server validates, applies them with the deterministic builder, recomputes the hash and persists | 0.05 AIC + 0.005 per applied op | #### Verifiable Role Contracts | Tool | What it does | Cost | | `list_role_contracts` | List the roles defined for a project with their version and status. Call it first: role ids are not guessable | free | | `get_role_contract` | Read a role's contract: purpose, rules with their checks and severity, working protocol. Accepts `version` to audit a past one | free | | `assume_role` | Open an audited role session under an active contract. Pins the contract hash and the Brain's `state_hash`, and delivers the owner's declared working environment | 0.001 AIC | | `release_role` | Close a session with a summary of what was done and what is pending. Sessions auto-release after 60 minutes | free | | `list_role_sessions` · `get_role_session` | The audit trail: who assumed which role, when, how it closed, and the hashes the session was bound to | free | #### Injection | Tool | What it does | Cost | | `quote_inject` | Price an injection before paying: which ids exist, which do not, total characters, exact cost with its split, and whether your balance covers it | free | | `inject_memories` | Inject up to 50 memories into the current conversation. Optimistic: the text returns immediately and the payment confirms in the background | 0.1 AIC per call | | `get_inject_balance` · `get_inject_history` | Your AIC balance and how many injections it covers; the history of past injections with their cost | free | | `get_my_context` | Your recent memory as ready-to-inject portable context, across every platform | free | #### Projects and identity | Tool | What it does | Cost | | `list_projects` · `create_project` · `delete_project` | Manage your projects and their auto-tagging keywords | free | | `list_project_templates` · `add_project_from_template` | Built-in templates: general, development, blockchain, business, personal, research | free | | `chainmemory_register` | Register an AI identity on chain. Required once before writing memories | free | | `chainmemory_profile` · `chainmemory_stats` | Your identity's profile and the network's statistics | free | ### Autonomous Consolidation Any AI client can **consolidate the project state autonomously** with `update_project_state`. This is the *"client consolidates, chain verifies"* architecture: the model proposes, the server validates and only then does it become state. 1 #### Read the current state Call `get_project_state` to load the consolidated state and its `consolidated_until_event` watermark. 2 #### Analyze what is new With `list_memories_filtered` or `search_memories`, read the memories created after the watermark to identify what changed. 3 #### Propose the operations Build an array of operations from the 29-op grammar and send it through `update_project_state`. 4 #### The server validates and persists Each operation is validated against the grammar, applied through the deterministic builder, the new `state_hash` (SHA3-256) is computed, evidence is linked with Merkle trees, and the version is persisted. Invalid operations are rejected individually — the valid ones still apply. #### Operation grammar (29 ops) Each operation has a type (`op`) and its own arguments. Use `evidence_memory_ids` — an array of memory numbers — to link supporting evidence; the server resolves the event hashes automatically. | Operation | Required fields | Description | | `add_decision` | title, statement | Record a decision. Without `status` it is created as `proposed` | | `set_decision_status` | id, to | Change status (proposed / confirmed / superseded) | | `supersede_decision` | id, **by_id** | Mark a decision as replaced by another | | `add_milestone` | title | Record a milestone | | `set_milestone_status` | id, to | Update its status | | `add_risk` | title, severity | Document a risk | | `set_risk_status` | id, to | Change its status (open / closed) | | `add_assumption` | statement | Record an assumption | | `invalidate_assumption` | id | Mark an assumption as invalid | | `add_open_question` | question | Register an open question | | `answer_open_question` | id, answer | Answer it | | `add_priority` | title, priority_score | Add a prioritized item | | `set_priority_status` | id, to | Change its status (active / done) | | `reorder_priority` | id, priority_score | Change its score | | `set_focus` | value | Update the current focus | | `set_phase` | value | Update the project phase | | `set_vision` | statement | Update the vision | | `add_vocabulary` · `update_vocabulary` | term, definition | Define or redefine a term | | `add_constraint` | statement | Add a constraint | | `remove_constraint` | id | Remove a constraint | | `set_metric` | **name**, value | Set or update a metric. Does **not** accept `evidence_memory_ids` | | `add_env_host` · `add_env_service` · `add_env_repo` · `add_env_rule` | vary by type | Describe where and how the owner works: hosts, services, repositories and operating rules | | `set_env_status` · `verify_env` · `supersede_env` | id | Update, confirm as current, or retire an environment item | **Field names are exact** The most common cause of rejection is a wrong argument name. `set_metric` uses `name`, not `key`. `supersede_decision` uses `by_id`, not `superseded_by`. And `set_metric` rejects `evidence_memory_ids`, which the rest of the additive operations do accept. Since the fee has a fixed base per call, sending everything in one call is cheaper than discovering signatures one at a time. **Environment: topology, never credentials** The seven `*_env_*` operations describe where the owner works so that an AI knows it from its first message. They store topology only: hosts, ports, paths, rules. **The server rejects credentials, keys and passwords.** #### Example JSON — update_project_state call { "project": "my-project", "ops": [ { "op": "add_decision", "title": "Migrate to PostgreSQL", "statement": "SQLite cannot handle concurrent writes at current scale", "evidence_memory_ids": [142, 145] }, { "op": "set_metric", "name": "db_migration_status", "value": "planning" }, { "op": "add_milestone", "title": "PostgreSQL migration approved by team", "status": "done", "evidence_memory_ids": [145] } ], "consolidated_until_event": 150 } **Resilient processing** Operations are applied one by one. If one fails validation, it is rejected and the rest still apply. The response includes `applied_count` and the detail of each rejection. Only applied operations are charged, and if the resulting state is identical to the previous one, nothing is charged at all. ### Workflow The typical MCP workflow: 1 #### Session start Ask your AI to load the project context. It calls `get_project_state` and starts out knowing what you are working on. Nothing is injected on its own: the model decides when to use the tools. 2 #### Normal work Work with your AI as usual. When something important happens — a decision, a discovery, an architecture change — it saves the memory with `chainmemory_remember`. 3 #### Consolidation At the end, the AI proposes operations with `update_project_state`: what was decided, what risk opened, what priority changed. That is what turns a pile of conversations into state. 4 #### Continuity In the next session, on this or any other model, the consolidated state is already there. Nothing is lost in between. ### Advanced Workflows #### Claude Desktop — Architecture Sessions Claude excels at high-level design. Use ChainMemory to preserve architectural decisions across sessions: Prompt pattern — Claude Desktop "Before we start, load my project state from ChainMemory. Then let's design the authentication system. After we decide, save the key decisions with tags 'architecture' and 'auth'. Use importance 9 for anything that affects other team members, and then propose the operations to consolidate the state." Claude reads the state with `get_project_state`, works with you on the design, saves decisions with `chainmemory_remember`, and proposes the consolidation with `update_project_state`. Next session, the auth architecture is already part of the state. #### Cursor — Code with Memory Cursor's MCP integration lets your coding AI remember *why* code was written a certain way. The configuration is the same as for Claude Desktop, in `settings.json`. An effective workflow: - **Start of session** — "Load the project state": decisions in force, open risks and priorities - **During coding** — "Save: implemented webhook handler with retry logic, 3 attempts with exponential backoff" - **Bug fixes** — "Save: fixed race condition in payment processing — the Stripe webhook was arriving before the DB transaction committed" - **End of session** — "Consolidate what changed today", which proposes the operations and updates the state #### Agentic Memory Pattern The most powerful MCP pattern is **agentic memory**, where the AI manages its own knowledge: System prompt for agentic memory You have access to ChainMemory via MCP. Follow these rules: 1. At session start: call get_project_state to load the consolidated state of the project. 2. When you make a significant decision: save it with chainmemory_remember. - Include WHY you chose this approach - Tag it with the relevant domain - Importance 1-10: use 7 or more for decisions, 5 for observations 3. When you complete a milestone: save it and say what comes next. 4. When you identify a risk: save it with its severity. 5. At session end: propose the consolidation with update_project_state. Do not close or supersede existing items without the owner's approval: add in proposed state and let a human confirm. **Cross-tool handoff** The same ChainMemory project works across Claude, Cursor, Windsurf, Hermes Agent, OpenClaw and any MCP-compatible client. Design in one, implement in another, review in a third — all sharing the same state. See [Multi-Agent Systems](#multiagent). **Working under a role contract** For teams and audited work, ChainMemory supports **Verifiable Role Contracts**: human-written, owner-signed rules that a model reads before working. `assume_role` opens a session pinned to the contract's hash and the state's hash, and `release_role` closes it with a summary. The model reads the contract; it never writes it. --- .fee-badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; background: rgba(200,168,90,0.15); color: #c8a85a; margin-left: 6px; } ## REST API Machine-readable contract: [OpenAPI 3.1](https://api.chainmemory.ai/openapi.json). Orientation for LLMs: [api.chainmemory.ai/llms.txt](https://api.chainmemory.ai/llms.txt). ### Authentication All API calls require authentication via API Key in the header: HTTP x-api-key: your-api-key Base URL: `https://api.chainmemory.ai/v1` **Security** Never expose your API Key in frontend code or public repositories. Use it only in backend or in environment variables. ### Memories POST /v1/memory Create a new memory. Fee: 0.001 AIC curl JavaScript Python bash curl -X POST https://api.chainmemory.ai/v1/memory \ -H "x-api-key: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "summary": "Decided to use PostgreSQL instead of MongoDB", "category": "decision", "importance": 8, "platform": "manual" }' javascript const res = await fetch('https://api.chainmemory.ai/v1/memory', { method: 'POST', headers: { 'x-api-key': 'your-api-key', 'Content-Type': 'application/json' }, body: JSON.stringify({ summary: 'Decided to use PostgreSQL instead of MongoDB', category: 'decision', importance: 8, platform: 'api' }) }); const memory = await res.json(); // { id: 207, hash: '0x4f2a...', memory_number: 42 } python import requests res = requests.post( 'https://api.chainmemory.ai/v1/memory', headers={'x-api-key': 'your-api-key'}, json={ 'summary': 'Decided to use PostgreSQL instead of MongoDB', 'category': 'decision', 'importance': 8, 'platform': 'api' } ) memory = res.json() # {'id': 207, 'hash': '0x4f2a...', 'memory_number': 42} #### Parameters | Parameter | Type | Description | | summary* | string | Text of the memory. The **only required field** | | project | string | Project to link it to. Optional: without it, tags are inferred from your projects keywords | | tags | string[] | Tags for organization (max 10) | | platform | string | Origin label: manual, extension, mcp, api. Defaults to `api` | | category | string | DECISION, LEARNING, INTERACTION, STATE, ERROR, MILESTONE or CUSTOM. Defaults to `CUSTOM` | | importance | number | 1 to 10, clamped to that range. Defaults to 5 | GET /v1/memories/list List memories with optional filters. | Parameter | Type | Description | | project | string | Filter by project | | tags | string | Filter by tags (comma-separated) | | search | string | Search in content | | limit | number | Maximum results (default: 20) | | offset | number | Pagination offset | GET /v1/memories/search Semantic search by content, tags, project, or date range. ### Projects GET /v1/projects List all user projects. GET /v1/project/:name/state Get the consolidated project state (decisions, milestones, risks, priorities, open questions, environment). Response (trimmed) { "project": "payment-system", "schema_version": 2, "version": 4, "state_hash": "0x3f8c2a…e91d", "generated_at": "2026-09-13T22:02:35.000Z", "anchor": { "status": "anchored", "onchain_anchor_id": 12, "tx_hash": "0x…", "block_number": 681919 }, "state": { "phase": "beta", "current_focus": "PCI review before opening to the first tenants", "decisions": [ { "id": "dec_0002", "title": "PostgreSQL with RLS for multi-tenancy", "statement": "Row-level security removes tenant filtering from the application layer", "status": "confirmed", "superseded_by": null, "evidence_root": "0x9a41…c07e", "created_version": 2, "updated_version": 3 } ], "milestones": [ { "id": "mil_0001", "title": "Database schema", "status": "done", "evidence_root": "0x5b2d…81fa", "created_version": 1, "updated_version": 2 } ], "risks": [ { "id": "risk_0001", "title": "RLS performance at 100K tenants", "severity": "med", "status": "open", "evidence_root": "0xd7e0…2a19", "created_version": 3, "updated_version": 3 } ], "state_meta": { "version": 4, "consolidated_until_event": 150, "previous_state_hash": "0x7b2e…f4c0" } } } Always the **latest** version; requires the owner's API key. Severity values are `low`, `med` and `high`. ### Injection POST /v1/inject Get relevant memories formatted for prompt injection. Fee: 0.1 AIC | Parameter | Type | Description | | memory_ids* | number[] | Your memory numbers (#N), 1 to 50. Archived and quarantined memories are excluded automatically | | project_filter | string | Optional project label recorded with the injection | | target_platform | string | Optional destination label (chatgpt, claude, gemini...) | | optimistic | boolean | Return the text immediately and confirm the on-chain payment in the background | #### Response The endpoint returns the selected memories formatted for injection. Each memory arrives tagged with its **user-facing number** and a **verification reference**, so an AI can cite the exact memory behind any statement — and you can trace that citation back to its on-chain evidence. A claim stops being "trust me" and becomes "here's the memory, verify it yourself." POST /v1/seal/:id Seal a memory, making it permanently immutable on-chain. Fee: 0.001 AIC | Parameter | Type | Description | | id* | number | Memory ID to seal (URL parameter) | POST /v1/project/:name/state Write a new project state version. Only charged if state actually changed. Fee: 0.1 AIC | Parameter | Type | Description | | state* | object | The full project state object | | expected_version | number | Optimistic concurrency check | POST /v1/project/:name/state/ops Apply operations to project state (Brain consolidation). Fee scales with number of operations applied. Fee: 0.05 + 0.005/op AIC | Parameter | Type | Description | | ops* | array | Array of operations to apply (max 100) | | consolidated_until_event | number | Event cursor for consolidation tracking | | generated_by | string | Client identifier | **Evidence is checked before anything is written** Each op cites its supporting memories in `evidence_memory_ids`. If any cited memory does not exist, is not yours or is not anchored yet, the whole call returns `422 evidence_unresolved` with the list of what failed, and nothing is written or charged. Ops that cite nothing are accepted with `evidence_root` `0x000…0`, and the response carries a `provenance_warning`. ### Audit & Oracle POST /v1/audit/memory/:id Audit the integrity of a specific memory: verifies hash consistency and on-chain status. Fee: 0.1 AIC | Parameter | Type | Description | | id* | number | Memory ID to audit (URL parameter) | #### Response Returns chain verification (on-chain status, sealed status, tx hash) and hash verification (stored vs computed event hash match). Never exposes memory content to external parties. POST /v1/audit/state/:project Full audit of a project: state hash verification, on-chain anchor check, version history, and memory count. Fee: 5 AIC | Parameter | Type | Description | | project* | string | Project name to audit (URL parameter) | #### Response Returns hash verification (stored vs recomputed), anchor status (on-chain ID, tx, block), version history (last 20 versions), and total memory count. The most comprehensive verification available. POST /v1/oracle/query Blind Oracle query: derives insights from memory metadata without accessing content. Returns verification proof. Fee: 0.1 AIC | Parameter | Type | Description | | question* | string | The question to query | | project | string | Filter by project | | memory_ids | array | Specific memory IDs to consult | #### Response Returns categories involved, time range, memory count attestation, and a SHA-256 query hash for verification. The oracle never accesses or returns memory content — only cryptographic proofs and derived metadata. ### Verification GET /v1/project/:name/state/anchor Verify the on-chain anchor of a project state. Public endpoint, no authentication required. | Parameter | Type | Description | | version | number | Specific version (default: latest) | Response { "project": "chainmemory", "projectId": "0x77f7d980...", "version": 3, "state_hash": "a7b3c9f2...", "anchor": { "status": "anchored", "tx_hash": "0xce55a800a2a4e30b...", "block_number": 123539, "contract": "0xa7A8BA51950255b3e223a6745597C67009Fe7875" } } **Independent verification** Anyone can verify the state by calling this endpoint and comparing the `state_hash` with the one recorded in the on-chain contract. No account or API key needed. ### Error Codes | Code | Meaning | Solution | | 401 | Invalid or missing API Key | Check your x-api-key header | | 402 | insufficient_aic — not enough AIC for a paid operation | Response includes `balance_aic`, `required_aic` and `faucet_url`. Top up at the faucet | | 403 | No permissions for this resource | Verify that the project belongs to you | | 404 | Resource not found | Check the project name or ID | | 409 | version conflict (`POST /v1/project/:name/state` with `expected_version`) | Re-read the state and retry | | 422 | evidence_unresolved — a cited memory does not exist, is not yours or is not anchored yet | Wait ~30 s for anchoring, or fix the memory numbers. Nothing was written or charged | | 429 | Too many requests from your IP | Wait and retry. The only limit enforced today is 30 requests per second per IP at the proxy; the per-plan requests-per-minute figures are not enforced yet (see [Limits](#limits)) | | 429 | key_creation_limit — `POST /v1/keys` | At most 3 new keys per IP and 100 in total every 24 hours. The response includes `retry_after_seconds` | | 500 | Internal error | Retry. If persistent, contact support | ### Feature Equivalence: Extension ↔ MCP ↔ API Not every feature is available through every integration method. This table shows what's available where: | Feature | Extension | MCP | API REST | | Save memory | ✓ 1-click save | ✓ chainmemory_remember | ✓ POST /v1/memory | | Recall memories | ✓ Memory list | ✓ chainmemory_recall | ✓ GET /v1/memories/list | | Search memories | ~ Basic filter | ✓ search_memories | ✓ GET /v1/memories/search | | Inject context | ✓ Auto-inject | ✓ inject_memories | ✓ POST /v1/inject | | View Project State | ✓ Project Brain | ✓ get_project_state | ✓ GET /v1/project/:name/state | | Seal (anchor on-chain) | ✗ Not available | ✓ chainmemory_seal | ✓ POST /v1/seal/:id | | Account stats | ✓ Dashboard | ✓ chainmemory_stats | ✓ GET /v1/stats | | Profile info | ✓ Settings | ✓ chainmemory_profile | ✓ GET /v1/profile | | List projects | ✓ Project selector | ✓ list_projects | ✓ GET /v1/projects | | Create project | ✓ New Project | ✓ create_project | ✓ POST /v1/projects | | Verify anchor | ~ Via Explorer link | ✓ verify_project_state, get_memory_proof | ✓ GET /v1/project/:name/state/anchor | | Archive memory | ✓ | ✓ archive_memory | ✓ POST /v1/memories/:id/archive | | Update tags | ✓ | ✓ update_memory_tags | ✓ PUT /v1/memories/:id/tags | **Full API parity** Every feature in this table is reachable through the REST API. The remaining gaps are on the Extension side: it does not seal memories, and its search is a local filter over the memory list rather than the semantic search. Both are available through the MCP server and the API. ### Trust & Governance Every memory carries a **trust status** from the moment it is written: `trusted`, `tentative` (flagged at write time by deterministic screening rules), or `quarantined` (condemned by the owner). Tentative memories are always delivered *marked* — agents see the flag and decide. Quarantined memories are excluded from context, injection, quotes and oracle queries, while their on-chain fingerprint remains as immutable evidence. All read responses include a `trust` field. POST /v1/memories/:id/trust Govern the trust status of a memory. Owner only. bash curl -X POST https://api.chainmemory.ai/v1/memories/487/trust \ -H "x-api-key: your-api-key" \ -H "Content-Type: application/json" \ -d '{"action": "quarantine"}' Actions: `approve` → trusted · `quarantine` → quarantined · `tentative` → tentative. Response includes the previous status for auditability. GET /v1/memory/:id/forensics Complete biography of a memory as an ordered timeline. Owner only. bash curl https://api.chainmemory.ai/v1/memory/485/forensics \ -H "x-api-key: your-api-key" Timeline events: `born`, `trust`, `batched`, `checkpoint_anchored`, `recalled` (every read, with endpoint and query), `injected` (every delivery, with target platform), `cited_as_evidence` (Project Brain items citing this memory). Includes cross-checked counters and on-chain anchoring proof. This answers the forensic question: *which memory caused what, when did it enter, who read it, and where did it go*. POST /v1/project/:name/state/rollback Restore project state to a prior version, verifiably. Fee: 0.1 AIC bash curl -X POST https://api.chainmemory.ai/v1/project/myproject/state/rollback \ -H "x-api-key: your-api-key" \ -H "Content-Type: application/json" \ -d '{"to_version": 35}' **Append-only restore**: rolling back to version N never deletes anything — it creates a *new* version whose content is byte-identical to N. Since hashes are computed over canonical bytes, the new version's hash equals the hash already anchored on-chain for N: the faithfulness of the restoration is a mathematical fact, not a promise. Before restoring, the server re-computes the stored content's hash and refuses (HTTP 409) if it does not match — corruption can never be restored. History is never mutated. --- ## TEAMS & ORGANIZATIONS A personal key belongs to one person. An **organization** lets a team share one budget, one set of projects and one audit trail, while every member still works with a key of their own. Everything a member creates — memories, projects, injections — is traceable back to their email and their role, and revoking their access is a single call. Organizations are available on the **Team** and **Enterprise** plans. The nine endpoints below are the entire surface: there is no management UI, and for a technical buyer that is usually an advantage. ### Activation flow An organization is not usable the moment it is created, and that is deliberate: - **Create it.** `POST /v1/org` with your personal key. It exists immediately, with `status: "suspended"` and no active keys. - **Inspect it.** `GET /v1/org` and `GET /v1/org/members` answer `200` right away. You can see what you created before paying for it. - **Pay.** Handled outside the API today; activation is applied once payment clears. - **Issue keys and invite.** Only after activation. Before it, both answer `402 organization_not_active`. That `402` is expected behaviour, not a failure: reads stay open on a suspended organization, anything that grants access does not. The rule runs in reverse too — if a subscription is cancelled the organization is suspended and **every key in the team stops working at once**, with no need to revoke them one by one. ### Keys and roles | Prefix | Type | Bound to | Expires | | `aic_` | Personal | One individual account | No | | `aicm_` | Member | One member of an organization | No | | `aicp_` | Project | One project slug, with a capped role | Optional, in days | A member key spends the organization's budget and carries that member's identity. A project key is meant for automation: scoped to a single project, permissions limited by `role_cap`, and optionally short-lived. The number of active project keys is capped by plan — Team has a limit, Enterprise does not. | Role | read | members | keys | | `owner` | yes | yes | yes | | `admin` | yes | yes | yes | | `developer` | yes | no | no | | `viewer` | yes | no | no | An organization always keeps at least one owner. Demoting the last one returns `409`, and an owner cannot be removed until their role is changed first. The API refuses to leave a team with nobody able to administer it. ### Endpoints | Method | Path | Permission | Does | | POST | `/v1/org` | personal key | Create the organization | | GET | `/v1/org` | any org key | Read status and plan | | POST | `/v1/org/invite` | `members` | Add a member | | GET | `/v1/org/members` | `read` | List members | | PATCH | `/v1/org/members/:id/role` | `members` | Change a member's role | | DELETE | `/v1/org/members/:id` | `members` | Remove a member, revoking their keys | | POST | `/v1/org/keys` | `keys` | Issue a member or project key | | GET | `/v1/org/keys` | `keys` | List active keys | | DELETE | `/v1/org/keys/:id` | `keys` | Revoke a key | #### POST /v1/org Authenticated with your **personal** key. One key can own one organization. | Field | Required | Notes | | `org_slug` | yes | 3–40 chars: lowercase letters, digits and hyphens; cannot start or end with a hyphen | | `name` | yes | Display name | | `owner_email` | yes | Becomes the first member, with role `owner` | | `tier` | no | `team` or `enterprise` | ``` curl -X POST https://api.chainmemory.ai/v1/org \ -H "x-api-key: $CHAINMEMORY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"org_slug":"acme-labs","name":"Acme Labs","owner_email":"ada@acme.dev"}' ``` Returns `org_id`, `org_slug`, `tier` and `owner_member_id`. Calling it twice with the same key returns `409`. #### POST /v1/org/invite Adds a member. The email must be valid and unique within the organization; a repeat returns `409`. ``` curl -X POST https://api.chainmemory.ai/v1/org/invite \ -H "x-api-key: $ORG_KEY" \ -H "Content-Type: application/json" \ -d '{"email":"grace@acme.dev","role":"developer"}' ``` #### POST /v1/org/keys | Field | Required for | Notes | | `type` | both | `member` or `project` | | `member_id` | `member` | From `GET /v1/org/members` | | `project_slug` | `project` | The only project the key may touch | | `role_cap` | no | Ceiling on what the key can do | | `expires_days` | no | Expiry, for project keys | **The full key is returned once, in this response, and never again.** Afterwards `GET /v1/org/keys` shows only its 12-character prefix. Store it when you receive it. A member holds one active key at a time: issuing a second returns `409` and asks you to revoke the first. Exceeding your plan's project-key limit returns `402`, with the current `tier` and `limit` in the response. #### DELETE /v1/org/members/:id Removes the member and revokes their keys in one operation; the response reports how many with `keys_revoked`. What that member already wrote stays in the organization, attributed to them. Access ends, history does not. ### Errors | Code | Error | Meaning | | 401 | `no_org_context` | The key is neither an org key (`aicm_`/`aicp_`) nor the personal key that owns an organization | | 402 | `organization_not_active` | The organization is suspended and the operation is not a read | | 402 | `project key limit reached` | Plan cap on active project keys; response carries `tier` and `limit` | | 403 | `forbidden` | The role lacks the permission; response names your `role` and the `required` one | | 404 | `member not found` · `key not found or not active` | Wrong id, or already revoked | | 409 | `cannot demote the last owner` | Promote another owner first | | 409 | `cannot remove an owner` | Change their role, then remove | Permission errors always state what you had and what was needed, so a failed call carries enough information to fix the call. --- ## ROLE CONTRACTS A Verifiable Role Contract (VRC) is a signed document that states what a role is for, which rules bind it, and how it must work. A model reads it and operates under it; it never writes it. Every time a role is assumed, the system opens an **audited session** pinned to the contract version, its hash, and the project state at that moment. The point is not to make a model behave. It is to leave a record of what it was bound to, so that months later you can answer a specific question: under which rules was this decision made, and against which version of the project's state? ### Contracts Contracts are authored by a human and signed by the project owner. Only a contract with status `active` can be assumed; drafts and retired versions can be read but not used. Each one carries a `contract_hash`, so a session can prove exactly which text governed it — including after the contract is amended. | Method | Path | Does | | GET | `/v1/project/:name/roles` | List the roles of a project, with status and version | | GET | `/v1/project/:name/role/:roleId` | Read one contract in full: purpose, rules, severity, protocol | Role ids are not guessable. List them before assuming one — a wrong guess costs a failed call. ### Audited sessions | Method | Path | Does | | POST | `/v1/project/:name/role/:roleId/assume` | Open a session under the contract | | POST | `/v1/session/:id/release` | Close it with a summary | | GET | `/v1/session/:id` | Read one session and everything it was pinned to | | GET | `/v1/project/:name/sessions` | The project's full audit trail | #### POST /v1/project/:name/role/:roleId/assume Fee: **0.001 AIC**. Optional body field `platform` (up to 64 chars) records the executor — `claude`, `chatgpt`, `gemini`. The same role may run on several executors; the notation is `role@executor`, and a different behaviour means a different role with its own contract. ``` curl -X POST https://api.chainmemory.ai/v1/project/my-project/role/architect/assume \ -H "x-api-key: $CHAINMEMORY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"platform":"claude"}' ``` Returns `201` with the session id, the pinned `contract_version` and `contract_hash`, the `brain_version` and `brain_state_hash` at that instant, an `event_hash`, and `auto_release_minutes: 60`. The response also carries the **working environment** declared by the owner: hosts, services, repositories and operating rules, pinned together with the state hash. A model that assumes a role knows from its first message where things run and how they are operated, instead of asking for connection details that are already recorded. | Code | Error | Meaning | | 404 | `role contract not found` | No such role in this project | | 409 | `contract not active` | Only a signed contract can be assumed | | 409 | `role already assumed in an open session` | One open session per role; the response names it and how to release it | | 402 | `insufficient_aic` | Balance below the 0.001 AIC fee | #### POST /v1/session/:id/release Closes the session with a `summary` of up to 4000 characters: what was done, what is pending, what comes next. A session left open auto-releases after 60 minutes, and the record shows it closed by timeout rather than by hand — which is itself information about how the work ended. ``` curl -X POST https://api.chainmemory.ai/v1/session/17/release \ -H "x-api-key: $CHAINMEMORY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"summary":"Consolidated infrastructure. 27 ops applied, 0 rejected. Pending: firewall allowlist."}' ``` Returns `released_at`, `release_type` and `duration_seconds`. Releasing twice returns `409`. The summary is the part people skip and the part that pays off later. `GET /v1/project/:name/sessions` returns every session with who assumed which role, on what platform, for how long, and how it closed. That trail is the reason the contracts exist. --- ## NETWORK ### Network Data | Field | Value | | Network | ChainMemory | | Chain ID | 202604 | | RPC URL | https://rpc.chainmemory.ai | | Currency | AIC (native) | | Decimals | 18 | | Block time | ~15 seconds | | Consensus | Clique PoA (3 active signers) | | Explorer | [chainmemory.ai/explorer](https://chainmemory.ai/explorer) | ### Deployed Contracts | Contract | Address | Purpose | | ProjectStateAnchor | `0xa7A8BA51950255b3e223a6745597C67009Fe7875` | Anchors the `state_hash` of every Project State version. `anchorState(projectId, version, stateHash)` stores it verbatim and emits `StateAnchored`; a (projectId, version) pair can never be re-anchored. Read it back with `getStateAnchor(projectId, version)` or `getAnchorById(anchorId)`. Here `projectId` is `keccak256(projectName)`, and `stateHash` is the canonical SHA3-256 computed by the engine — the contract stores it, it does not recompute it. This is the contract behind the public endpoint `GET /v1/project/:name/state/anchor`. | | CheckpointAnchor | `0x1706946365B455f66B92C05d641c6fDB897D0791` | Anchors the aggregate Merkle root of a group of memory batches, with audit metadata: epoch start and end, batch count, trigger reason and snapshot hash. Emits `CheckpointAnchored`; read it back with `getCheckpoint(checkpointId)`. Once anchored, a checkpoint is immutable. | | MemoryV2 (active) | `0xE84224e2660fd620aA6d09522718Ae0e5cF33F7d` | Active memory contract: all new memories are written here. Independently verifiable by hash against the on-chain record. | | AIMemoryRegistry (v1, legacy) | `0x7a50ed017E175Eb4549d3BDd7DBCF319F9f30160` | Global registry of AI memory hashes. Allows any memory to be independently verified by checking its SHA-256 hash against the on-chain record. | | AIIdentityProtocol | `0xe8E195ba416Fb25F4FC3d0E7908ff9e8666dbb4A` | Identity layer for AI agents. Registers AI instances with their model type, capabilities, and ownership, enabling trust scoring and provenance tracking across interactions. | AIC Token is the native currency of the network (not an ERC-20 contract). It is used to pay protocol fees for all write operations. Every fee is split 50/50 between burn (deflationary) and treasury. ### Fee Schedule v1.0 All write operations carry a protocol fee. 50% is permanently burned (deflationary pressure), 50% goes to the treasury. Read operations and AI registration are free. | Operation | Fee (AIC) | Burn | Treasury | | **Inject context** — push memories to an LLM | 0.1 | 0.05 | 0.05 | | **Anchor state** — anchor project state on-chain | 0.1 | 0.05 | 0.05 | | **Audit memory** — verify memory integrity | 0.1 | 0.05 | 0.05 | | **Blind oracle query** — derived query with proof | 0.1 | 0.05 | 0.05 | | **Brain consolidation** — Project Brain state/ops | 0.05 + 0.005/op | 50% | 50% | | **Audit state** — full project audit | 5.0 | 2.5 | 2.5 | | **Write memory** — save a memory | 0.001 | 0.0005 | 0.0005 | | **Seal memory** — make memory immutable | 0.001 | 0.0005 | 0.0005 | | **Register AI** — create AI identity | Free | | **All read operations** — list, search, verify | Free | **Faucet economy** With 1 AIC from the faucet you can perform: 10 injects, 10 anchors, 8 brain consolidations (15 ops each), or about 1,000 memory writes counting only the 0.001 AIC protocol fee. Saving a memory also pays on-chain storage, which grows with its length, so the real number of memories per AIC is lower and depends on how long they are — see [Costs](#pricing) for the measured figures. Registration and reads are always free. ### Connect MetaMask To add ChainMemory to MetaMask: - Go to [chainmemory.ai/network](https://chainmemory.ai/network) - Click "Add ChainMemory to MetaMask" - Confirm in MetaMask Or add it manually with the network data from the table above. ### Faucet The faucet delivers free AIC so you can interact with the blockchain: - **URL:** [faucet.chainmemory.ai](https://faucet.chainmemory.ai) - **Amount:** 1 AIC per claim - **Cooldown:** 72 hours between claims - **Requirement:** Solve a simple challenge (anti-bot) **Wallet security** The faucet generates wallets 100% in your browser. Your private key never leaves your device. We recommend downloading the encrypted keystore (JSON) for safekeeping rather than storing the private key as plain text. --- ## AI IDENTITY PROTOCOL Every AI agent that uses ChainMemory gets a **unique, non-transferable on-chain identity** — a Soulbound Token (SBT) that proves who wrote a memory, when, and from which model. This is the foundation of trust in a multi-agent world. ### The Problem In current AI systems, there's no way to answer fundamental questions: - Which AI wrote this response? Was it Claude, GPT-4, or a fine-tuned model? - Is this the same agent I worked with yesterday, or a different instance? - Can I trust this agent's memory if I don't know its identity? - How do I prove provenance when multiple agents collaborate? Without identity, there's no accountability. Without accountability, there's no trust. ### How It Works 1 #### Registration When a user creates an account or an agent connects via API/MCP, the system registers an identity on-chain via the `AIIdentityProtocol` contract. This creates a Soulbound Token — an NFT that **cannot be transferred**. It's permanently bound to that agent's wallet. 2 #### Identity Metadata Each registered identity stores: - **Wallet address** — The agent's unique blockchain address - **Model type** — claude-sonnet-4, gpt-4o, gemini-2.0, etc. - **Capabilities** — What this agent can do (remember, recall, consolidate, seal) - **Owner** — The human or organization that controls this agent - **Registration block** — Immutable proof of when this identity was created 3 #### Memory Attribution Every memory written to ChainMemory includes the `ai_id` of the agent that created it. This means any memory can be traced back to a specific, verified AI identity. ### Contract Details | Field | Value | | Contract | AIIdentityProtocol | | Address | `0xe8E195ba416Fb25F4FC3d0E7908ff9e8666dbb4A` | | Chain | ChainMemory (ID 202604) | | Token type | Soulbound (non-transferable ERC-721) | | Standard | EIP-5192 (Minimal Soulbound NFTs) | ### Trust Score (Roadmap) The identity protocol enables a future **AI Trust Score** — a reputation metric based on verifiable interactions: - **Memory count** — How many verified memories has this agent produced? - **Consistency** — How often do the agent's memories pass anti-hallucination validation? - **Anchor rate** — What percentage of memories are backed by on-chain proofs? - **Collaboration history** — Has this agent participated in multi-agent workflows? **Why Soulbound?** Regular NFTs can be sold or transferred, which would allow identity spoofing. Soulbound Tokens are permanently bound to the wallet that minted them. An AI agent cannot pretend to be another agent by buying its identity token. This is critical for audit trails — you need to know with certainty which agent wrote which memory. ### Identity in Multi-Agent Workflows When multiple agents collaborate on the same project (see [Multi-Agent Systems](#multiagent)), each agent's contributions are individually attributed: Evidence trail Project: "payment-system-v2" ├── Memory #1 by Claude (ai_id: 0xA1...) — "Use Stripe for payments" ├── Memory #2 by GPT-4 (ai_id: 0xB2...) — "Add fraud detection layer" ├── Memory #3 by Cursor (ai_id: 0xC3...) — "Implemented webhook handler" └── State v4 anchored — all 3 agents contributed, all verifiable Each agent's identity is independently verifiable on-chain. There's no ambiguity about who contributed what. ### Verify an Identity You can verify any AI identity using the blockchain directly: JavaScript (ethers.js) const { ethers } = require('ethers'); const provider = new ethers.JsonRpcProvider('https://rpc.chainmemory.ai'); const IDENTITY_CONTRACT = '0xe8E195ba416Fb25F4FC3d0E7908ff9e8666dbb4A'; const ABI = ['function balanceOf(address) view returns (uint256)']; const contract = new ethers.Contract(IDENTITY_CONTRACT, ABI, provider); const hasIdentity = await contract.balanceOf(agentWallet); console.log(hasIdentity > 0 ? 'Verified AI identity' : 'No identity registered'); **No identity = no trust** If an agent doesn't have a registered on-chain identity, its memories cannot be attributed. ChainMemory requires identity registration before allowing memory writes. This ensures every memory in the system has a verifiable author. --- ## MULTI-AGENT SYSTEMS ChainMemory was designed from the ground up for a world where **multiple AI agents collaborate on the same project**. Every agent reads the same Project State, every contribution is attributed, and every handoff is traceable. ### The Multi-Agent Problem Modern development workflows already involve multiple AI agents: - **Claude** designs the architecture and writes documentation - **Cursor** implements the code with inline AI assistance - **GPT-4** reviews PRs and analyzes security implications - **Gemini** processes large codebases for refactoring suggestions Without shared memory, each agent starts from zero. Decisions made in Claude are invisible to Cursor. Architecture agreed in GPT is unknown to Gemini. You become the bottleneck — constantly re-explaining context. ### How ChainMemory Solves This #### Shared Project State All agents connected to the same project see the **same consolidated state**: decisions, milestones, risks, stack, and context. When Claude marks a decision as "active", Cursor sees it immediately. Shared State Flow ┌──────────┐ ┌──────────────────────────┐ ┌──────────┐ │ Claude │───▶│ │◀───│ Cursor │ │ (MCP) │ │ ChainMemory Project │ │ (MCP) │ └──────────┘ │ │ └──────────┘ │ decisions: [d001, d002] │ ┌──────────┐ │ milestones: [m001] │ ┌──────────┐ │ GPT-4 │───▶│ risks: [r001, r002] │◀───│ Gemini │ │ (API) │ │ stack: [Node, Redis] │ │ (API) │ └──────────┘ └──────────────────────────┘ └──────────┘ #### Agent Handoff Pattern When work moves from one agent to another, ChainMemory provides **seamless context transfer**: 1 #### Claude designs the architecture Claude saves key decisions via MCP: database choice, API structure, authentication strategy. Each memory is attributed to Claude's `ai_id`. Claude saves chainmemory_remember({ content: "Use PostgreSQL with row-level security for multi-tenant isolation", tags: ["architecture", "database", "security"], importance: 0.9 }) 2 #### Cursor picks up implementation When you open Cursor, it injects the project context automatically. Cursor knows the database choice, the API structure, and why those decisions were made — without you repeating anything. Cursor receives (via inject) Project State v3: - Decision d001: "Use PostgreSQL with RLS" (confirmed, evidence: #12, #15) - Decision d002: "REST API with versioned endpoints" (confirmed, evidence: #18) - Milestone m001: "Database schema complete" (pending) - Risk r001: "RLS performance on large tenants" (med, evidence: #15) 3 #### Cursor implements and saves progress As Cursor implements, it saves implementation memories. These are attributed to Cursor's `ai_id` and feed back into the shared state. Cursor saves chainmemory_remember({ content: "Implemented RLS policies for tenants table. Performance tested at 50K rows: 2ms avg query time.", tags: ["implementation", "database", "performance"], importance: 0.8 }) 4 #### GPT-4 reviews with full context A GPT-4 agent reviewing the PR can query ChainMemory to understand *why* each decision was made, who made it, and what evidence supports it. ### Handoff Patterns | Pattern | Flow | Use Case | | **Sequential** | Claude → Cursor → GPT-4 | Design → Implement → Review | | **Parallel** | Claude + Cursor + Gemini simultaneously | Multiple developers, same project | | **Specialist** | Any agent → Security agent → Back | Specific expertise on demand | | **Supervisory** | Human + Claude oversee, Cursor executes | Human-in-the-loop with delegation | ### Conflict Resolution Across Agents When two agents make contradictory decisions, ChainMemory's [Conflict Resolution](#concept-conflicts) applies the same rules: - **Temporal precedence** — The most recent decision wins, regardless of which agent made it - **Evidence weight** — A decision supported by 5 memories from 3 agents is stronger than one with a single memory - **Explicit supersession** — Any agent can explicitly supersede a previous decision by referencing it - **Full audit trail** — Both the original and superseding decisions are preserved with their respective `ai_id` attribution **No single point of truth — except the chain** In a multi-agent system, no single agent owns the "truth". The Project State is a *materialized view* derived from all agents' contributions. The on-chain anchor is the only authoritative timestamp. This means even if one agent hallucinates or makes an error, the evidence chain allows other agents (or humans) to trace and correct it. ### Setting Up Multi-Agent No special configuration needed. Any agent connected to the same project automatically participates in multi-agent collaboration: - Create a project via Extension, MCP, or API - Use the same API key across agents (or create agent-specific keys under the same account) - Each agent uses `inject_memories` at session start to load shared context - Each agent uses `chainmemory_remember` to save contributions - One agent (or each, reading the state first) consolidates with `update_project_state`, citing the other agents' memories; all operations land in one Project State **Best practice** Use descriptive tags that identify the agent's role: `["architecture", "claude-design"]`, `["implementation", "cursor-code"]`, `["review", "gpt4-security"]`. This makes filtering by agent role easy without needing to parse `ai_id` directly. --- ## HERMES AGENT Hermes Agent is an open-source, provider-agnostic AI agent framework. ChainMemory integrates with Hermes via two paths: the **MCP server** (native tools inside chat) or the **cm.py CLI wrapper** (full control from terminal). ### Prerequisites - Hermes Agent installed (Windows, macOS, Linux, WSL) - ChainMemory account with API key (format: `aic_...`) - Python 3.10+ (for cm.py wrapper) ### Get Your API Key ChainMemory accounts are created exclusively through the Chrome Extension: - Install [ChainMemory Extension](https://chromewebstore.google.com/detail/lniemlpehifeeaeomngaleefagconfmb) - Click the icon in your browser toolbar - Choose **"Generate API Key automatically"** (free wallet + 1 AIC) or **"I already have a key"** - Go to **Settings → Connection** and click **"View"** to copy your API key **Important:** The Faucet ([faucet.chainmemory.ai](https://faucet.chainmemory.ai)) distributes AIC tokens for on-chain operations, but does *not* issue API keys. The API key comes only from the Extension. ### Option A: MCP Server (Chat Workflow) The MCP server exposes ChainMemory as native tools inside Hermes chat. After configuration, you can say things like *"Remember: we decided to use PostgreSQL"* and Hermes will call the tool automatically. #### Configuration Edit `~/.hermes/config.yaml` and add: YAML — ~/.hermes/config.yaml mcp_servers: chainmemory: command: "python" args: ["C:\\Users\\\\.hermes\\skills\\chainmemory-mcp\\chainmemory_mcp_server.py"] env: CHAINMEMORY_API_KEY: "aic_..." CHAINMEMORY_BASE_URL: "https://api.chainmemory.ai/v1" CHAINMEMORY_DEFAULT_PROJECT: "default" Restart Hermes after editing. The tools appear as `mcp_chainmemory_*` in chat. #### Available MCP Tools | Tool | What it does | | `mcp_chainmemory_save_memory` | Save a memory | | `mcp_chainmemory_list_memories` | List / search memories | | `mcp_chainmemory_get_profile` | Account info | | `mcp_chainmemory_list_projects` | List projects | | `mcp_chainmemory_get_balance` | AIC balance + faucet URL | | `mcp_chainmemory_get_blockchain_stats` | Chain stats | | `mcp_chainmemory_update_memory_tags` | Retag a memory | | `mcp_chainmemory_archive_memory` | Archive / unarchive | ### Option B: cm.py Wrapper (CLI / Scripts) `cm.py` is a Python CLI that wraps the REST API. It handles auth headers, pacing, and retries. Install it via the ChainMemory skill: bash hermes skills install chainmemory Then configure your key: bash chmod 600 ~/.hermes/chainmemory.env #### Commands | Command | What it does | | `cm whoami` | Show account, tier, quota | | `cm projects` | List all projects | | `cm save "text" --project my-app` | Save a memory | | `cm recall --project my-app` | Recall recent memories | | `cm search "query" --project my-app` | Semantic search | | `cm state my-app` | Project State | | `cm seal my-app` | Anchor state on-chain (irreversible) | | `cm verify my-app` | Public verification (no auth) | ### Option C: REST API Direct Any HTTP client works. Base URL: `https://api.chainmemory.ai/v1`. Auth header: `x-api-key: aic_...` (not `Authorization: Bearer`). ### Important Notes - **Auth header:** Use `x-api-key`, not `Authorization: Bearer`. - **Rate limits:** 30 requests per second per IP enforced at the proxy. Per-plan requests-per-minute figures are published but not enforced yet. - **The state does not build itself:** there is no backend consolidation and no automatic trigger. The Project State changes only when a client proposes operations through `update_project_state` (MCP) or `POST /v1/project/:name/state/ops` (API). Waiting will not produce a state — asking for one will. - **What "seal" means here:** in ChainMemory own API and MCP server, `seal` makes a single *memory* permanently immutable (`POST /v1/seal/:id`, which takes your memory number). The Project State is anchored as part of consolidation, not by sealing. `cm.py` is a third-party wrapper and may map its commands differently. - **Windows paths:** In `config.yaml`, use double backslashes: `C:\\Users\\\\...` ### Verify Setup bash # Via MCP (in chat) "Save this: We decided to use PostgreSQL for the primary database" # Via CLI cm whoami cm save "We decided to use PostgreSQL for primary DB" --project my-app --tags decision,stack cm state my-app cm verify my-app --- ## AUDITING GUIDE One of ChainMemory's most powerful capabilities is enabling **verifiable audits** of AI-assisted project decisions — without exposing private conversation content. ### Two Levels of Audit #### Level 1 — External audit (no owner access) Anyone can verify that a project state was anchored at a specific point in time, without seeing what it contains. This is like seeing a notarized seal — you know it exists, you don't know what's inside. What an external auditor sees (public, on-chain): | Data | Visible | Reveals content? | | state_hash | ✓ Public | No — SHA3-256 is irreversible | | tx_hash | ✓ Public | No — only proves the transaction happened | | block_number | ✓ Public | No — only proves when it was anchored | | project ID (hashed) | ✓ Public | No — project name is hashed | | version number | ✓ Public | No — only shows how many consolidations occurred | | Memory content | ~ Ciphertext is on-chain | No — AES-256-GCM, unreadable without the owner key | | Decision details | ✗ Private | Not on-chain as state; the memories they cite are on-chain encrypted | | Project State | ✗ Private | Only its state_hash goes on-chain | Level 1 — Public endpoint GET /v1/project/nova-logistics/state/anchor Response: { "project": "nova-logistics", "projectId": "0x77f7d980...", // hashed — original name not revealed "version": 5, "state_hash": "a7b3c9f2e1...", // proves state existed, reveals nothing about content "anchor": { "status": "anchored", "tx_hash": "0xce55a800...", "block_number": 125000, "contract": "0xa7A8BA51...e7875" } } **What this proves** A project state with hash `a7b3c9f2e1...` was registered at block 125000 on the ChainMemory blockchain. Nothing about the content is revealed. No API key required. #### Level 2 — Selective disclosure audit (owner shares data) The project owner **chooses** what to share with the auditor. The auditor then verifies the shared data against the on-chain proof. This is the powerful audit: you prove the data is authentic without an intermediary. The owner controls exactly what gets disclosed: | Disclosure level | What the auditor sees | Use case | | State only | Decisions, milestones, risks, stack — no conversation text | Investor due diligence | | State + selected memories | Decisions with supporting conversation excerpts | Compliance review | | Full export | All memories, full state, complete history | Internal audit, legal discovery | ### Step-by-Step Audit Process Example: **NovaTech**, a startup building a logistics SaaS. After 4 months using ChatGPT and Claude alternately, the CTO needs to demonstrate project traceability to investors. 1 #### Owner exports the Project State The CTO calls the API with their key and exports the state JSON: bash curl -H "x-api-key: cto-api-key" \ https://api.chainmemory.ai/v1/project/nova-logistics/state Result: 12 active decisions, 3 superseded, 8 completed milestones, 2 open risks. The CTO shares this JSON with the investor. 2 #### Auditor computes the hash The investor saves the received JSON as `state.json` and computes the state hash. The hash is **SHA3-256** over a domain prefix (`CM_PROJECT_STATE_V`) plus the canonical form of the `state` object (keys sorted recursively, compact separators, UTF-8, `state_hash` field excluded). The open reference verifier does it in one command — Python standard library only, no dependencies: bash curl -sO https://docs.chainmemory.ai/verify_state.py python3 verify_state.py state.json # computed state_hash : 0xa7b3c9f2e1d4... # declared state_hash : 0xa7b3c9f2e1d4... -> MATCH # on-chain state_hash : 0xa7b3c9f2e1d4... -> ON-CHAIN MATCH The verifier is ~90 lines of auditable code: it recomputes the hash independently and also checks it against the public on-chain anchor. No trust in ChainMemory required. 3 #### Auditor verifies against the blockchain The investor calls the public verification endpoint (no API key needed): bash curl https://api.chainmemory.ai/v1/project/nova-logistics/state/anchor # Returns: state_hash: "a7b3c9f2e1d4..." If the hashes match: the state is **authentic and unmodified** since the anchor date. 4 #### Auditor traces a specific decision (optional) If the CTO also shared memory access, the investor can drill into any decision: Decision `d005: "Migrate from REST to GraphQL"` has `evidence: ["#45", "#67", "#82"]`. The investor retrieves those 3 memories: - Memory #45 — ChatGPT session discussing API performance bottlenecks - Memory #67 — Claude session comparing REST vs GraphQL trade-offs - Memory #82 — Final decision documented with rationale Each memory has its own **SHA-256** hash of its text, with no domain separator — not to be confused with the SHA3-256 domain-separated hash of the Project State. Content verified, provenance confirmed. **What the investor can now say** "At block 125000 on June 10, 2026, NovaTech's project had 12 active decisions backed by 82 AI conversation memories. Each decision traces to specific conversations. The state hash I verified on-chain matches exactly. Nothing was altered after anchoring." ### Privacy Guarantees During Audit The critical guarantee: **the owner always controls disclosure**. - Investors see decisions and milestones — not the raw AI conversations that produced them - The blockchain proves authenticity without revealing content - Memory text (actual conversation content) is only visible if the owner explicitly exports it - The on-chain record contains hashes plus the encrypted memory content — even if the blockchain is public, without your key none of it is readable - No third party, including ChainMemory itself, can force disclosure of memory content **Important distinction** The blockchain proves *that* a state existed at a given time. It does not reveal *what* the state contained. The owner bridges the gap by selectively sharing data with the auditor. Without the owner's cooperation, the on-chain data is opaque by design. --- ## WHAT CHAINMEMORY PREVENTS Understanding what ChainMemory protects against is as important as understanding what it does. ### Context loss Every AI conversation today is ephemeral. Close the tab and everything discussed — decisions, architecture choices, research findings — vanishes. ChainMemory captures these as permanent, retrievable memories. Your next session starts where the last one ended. ### Vendor lock-in If your project knowledge exists only inside ChatGPT's conversation history, you're locked in. ChainMemory stores knowledge independently of any AI provider. Switch from ChatGPT to Claude to Gemini without losing a single decision or context. ### Retroactive manipulation Without cryptographic proof, anyone could claim "we decided X" when the actual decision was Y. ChainMemory's on-chain anchoring creates a tamper-proof record. The state hash at block 123539 proves exactly what the project state was at that moment. It cannot be altered after the fact. ### Knowledge fragmentation Teams using AI end up with critical knowledge scattered across dozens of disconnected conversations, in different tools, with different models. ChainMemory consolidates everything into a single, structured Project State — regardless of which AI or tool produced the original conversation. ### Single-AI dependency When one AI provider goes down, changes its API, or deprecates a feature, projects relying solely on that provider lose continuity. ChainMemory's cross-model architecture ensures your accumulated knowledge is accessible from any compatible AI system. ### Invisible decision drift In long-running projects, decisions evolve over months. Without a system that tracks *what* changed, *when*, and *why*, teams lose track of their own reasoning. The Project State's decision lifecycle (proposed → confirmed → superseded), with every item citing its memories, makes every evolution traceable. **The fundamental guarantee** ChainMemory ensures that AI-assisted knowledge — the decisions, discoveries, and context your team builds over weeks and months of AI-powered work — is never lost, never locked in, never falsifiable, and always portable. --- ## TRUST MODEL What you can — and cannot — trust ChainMemory combines a centralized API with decentralized verification. Understanding the trust boundaries is critical for evaluating whether ChainMemory meets your security requirements. ### Guarantees table | Question | Answer | How it's enforced | | Can the operator delete an event after it's recorded? | Yes, from the database | But the on-chain anchor preserves the state hash. Deletion is detectable: re-computing the hash from remaining events will produce a mismatch with the anchored hash. | | Can the operator modify a past state? | Yes, in the database | But any modification changes the state hash. Comparing the recomputed hash against the on-chain anchor reveals tampering immediately. | | Can the operator forge an anchor? | No | Anchors are on-chain transactions. The smart contract records the state hash immutably. Forging requires controlling the blockchain — economically infeasible with PoA consensus and multiple validators. | | Can a third party verify without trusting ChainMemory? | Yes | The verification endpoint is public and unauthenticated. Anyone can also read the smart contract directly using Web3/Ethers.js. | | Can memories be read by other users? | No | Memory content is scoped to the API key owner. What is public on-chain is ciphertext, not plaintext: decrypting it requires the key derived from the owner API key. | | Is the memory plaintext stored on-chain? | No | What is written on-chain is the AES-256-GCM **ciphertext** of each memory (`MemoryV2.writeMemory`), along with its category, importance and plaintext length. The plaintext never leaves the API database, and without the owner key nobody can decrypt it — which is also what lets you recover a memory years later from another device. The consolidated Project State is anchored as a **SHA3-256** hash only. | | Can validators see memory content? | No | For a state anchor the payload is only the project id and the state hash. For a memory it is AES-256-GCM ciphertext plus its category, importance and length: validators can order and validate it, they cannot read it. | | What happens if ChainMemory goes offline? | Memories are temporarily inaccessible | But all on-chain anchors remain verifiable independently. The blockchain continues operating even if the API is down. Users can export their data at any time. | ### Trust levels **Full trust (cryptographic)** State integrity and timestamp. Once anchored, the hash at block N is immutable. Nobody — not even ChainMemory — can alter what was recorded. **Operational trust (API-dependent)** Memory storage, retrieval, injection, and consolidation. These depend on the ChainMemory API being available and honest. The anchor mechanism acts as a check: any server-side tampering is detectable. **No trust needed** Independent verification. Anyone with a Web3 library can read the smart contract directly and compare hashes. Zero dependency on ChainMemory infrastructure. ### Sovereignty — non-custodial ChainMemory is moving to a non-custodial model where **your key lives in your client, not on the server**. You sign your own on-chain writes; the server stores ciphertext and verifies signatures, but never holds your private key. This has been proven end-to-end — a memory written entirely client-side, with the server never touching the key. **What non-custodial means here** Keys are generated client-side and the server stores only your address (`POST /v1/keys/register-pubkey`). The client signs and broadcasts each write; the server only attaches the record (`POST /v1/memory/attach`). API keys are encrypted at rest (AES-256-GCM) with a master key kept outside the app. **In progress** Blind vault: deriving the content-encryption key from your private key so the server cannot read content even in theory. The published Chrome extension still signs server-side (custodial) today; the non-custodial path ships in a new version. The capability is proven and the migration is underway. --- ## THREAT MODEL Attacks, detection, and what's out of scope No system is invulnerable. This section maps the attack surface, what ChainMemory detects or prevents, and what remains the user's responsibility. ### Attack vectors | Attack | Target | Detection / Prevention | Severity | | Retroactive state modification | API database | ✓ Detected — recomputed hash won't match the on-chain anchor | Critical | | Silent event deletion | API database | ✓ Detected — missing events change the hash chain | Critical | | Fake anchor (forge tx hash) | Verification layer | ✓ Prevented — anchors are on-chain; forging requires blockchain control | Critical | | API Key theft | User credentials | ~ User responsibility — use env vars, rotate keys, never expose in frontend | High | | Man-in-the-middle on API calls | Network | ✓ Prevented — all API traffic uses HTTPS/TLS | High | | Malicious memory injection | Project state | ~ Partial — memories are scoped to the API key owner, and consolidation rejects evidence that does not resolve to the owner's anchored memories (422). Nothing checks that content is *true*: whoever holds the key can still write and consolidate false state. The chain proves provenance, not correctness | Medium | | Validator collusion (>50% signers) | Blockchain consensus | ~ Mitigated — Clique PoA requires majority; validator set will expand to 21 seats | Medium | | Replay attack (resubmit old anchor) | Smart contract | ✓ Prevented — contract tracks version numbers; same version can't be re-anchored | Medium | | Content inference from hashes | Privacy | ✓ Prevented — SHA-256 is one-way; content can't be reversed from hash | Low | | DDoS on API | Availability | ~ Mitigated — per-IP rate limiting at the proxy (30 requests per second per IP) plus Cloudflare in front; blockchain unaffected | Medium | ### Out of scope ChainMemory does **not** protect against: - **User storing false information** — if you save a lie as a memory, ChainMemory anchors it faithfully. The system guarantees integrity (the data hasn't changed), not truthfulness (the data was correct). - **Compromised user device** — if your machine has malware, your API key and local data are exposed before they reach ChainMemory. - **AI hallucinations** — ChainMemory stores what you save, not what an AI generates. It doesn't validate whether the AI's output was accurate. **Defense in depth** ChainMemory's security model follows defense in depth: even if the centralized API is compromised, the on-chain layer provides an independent verification mechanism. No single point of failure can silently corrupt project history. --- ## INDEPENDENT VERIFICATION Verify on-chain anchors without trusting anyone You don't need ChainMemory's API to verify that a project state was anchored at a specific block. This page shows how to verify directly against the blockchain using standard Web3 tools. ### What you need - The project's state hash (from the API or shared by someone) - The transaction hash or block number of the anchor - Node.js with `ethers` installed — or any Web3 library ### Step 1 — Get the anchor data Use ChainMemory's public (no auth) endpoint or get it from whoever shared the proof: bash curl https://api.chainmemory.ai/v1/project/chainmemory/state/anchor Response { "project": "chainmemory", "projectId": "0x77f7d980...", "version": 8, "state_hash": "0xa6c45d1db753b1ec96240d169b2d91fb0ce76112558b302a8822b2988aeb8212", "anchor": { "status": "anchored", "onchain_anchor_id": 8, "tx_hash": "0x95b732d20b8935a2...", "block_number": 173831, "contract": "0xa7A8BA51950255b3e223a6745597C67009Fe7875" }, "verify": "ProjectStateAnchor.getStateAnchor(projectId, version)" } ### Step 2 — Verify on-chain with Ethers.js Connect directly to the ChainMemory RPC and read the smart contract. No API key, no account, no trust required. Ethers.js Web3.js javascript import { ethers } from 'ethers'; // Connect to ChainMemory RPC — no API key needed const provider = new ethers.JsonRpcProvider('https://rpc.chainmemory.ai'); // ProjectStateAnchor contract const CONTRACT = '0xa7A8BA51950255b3e223a6745597C67009Fe7875'; const ABI = [ 'function getStateAnchor(bytes32 projectId, uint64 version) view returns (bytes32 stateHash, uint256 anchoredAt, address anchoredBy, uint256 anchorId)' ]; const contract = new ethers.Contract(CONTRACT, ABI, provider); // The project ID is the keccak256 of the project name const projectId = ethers.keccak256(ethers.toUtf8Bytes('chainmemory')); const version = 8; // Read directly from the blockchain const [stateHash, anchoredAt, anchoredBy, anchorId] = await contract.getStateAnchor(projectId, version); console.log('On-chain state hash:', stateHash); console.log('Anchor ID:', anchorId.toString()); console.log('Anchored at:', new Date(Number(anchoredAt) * 1000).toISOString()); // Compare with the hash you received const expectedHash = '0xa6c45d1db753b1ec96240d169b2d91fb0ce76112558b302a8822b2988aeb8212'; if (stateHash === expectedHash) { console.log('VERIFIED — state matches on-chain anchor'); } else { console.log('MISMATCH — state has been tampered with'); } javascript const Web3 = require('web3'); const web3 = new Web3('https://rpc.chainmemory.ai'); const CONTRACT = '0xa7A8BA51950255b3e223a6745597C67009Fe7875'; const ABI = [{ name: 'getStateAnchor', type: 'function', stateMutability: 'view', inputs: [ { name: 'projectId', type: 'bytes32' }, { name: 'version', type: 'uint64' } ], outputs: [ { name: 'stateHash', type: 'bytes32' }, { name: 'anchoredAt', type: 'uint256' }, { name: 'anchoredBy', type: 'address' }, { name: 'anchorId', type: 'uint256' } ] }]; const contract = new web3.eth.Contract(ABI, CONTRACT); const projectId = web3.utils.keccak256('chainmemory'); const result = await contract.methods.getStateAnchor(projectId, 8).call(); console.log('On-chain state hash:', result.stateHash); console.log('Anchor ID:', result.anchorId); ### Step 3 — Verify the transaction You can also verify the raw transaction that created the anchor: javascript // Read the transaction directly const tx = await provider.getTransaction('0x95b732d20b8935a286869d90e60a40f5c31d350a94e27bfd7845770fe0c3e2c3'); console.log('From:', tx.from); // Should be a known validator console.log('To:', tx.to); // Should be the contract address console.log('Block:', tx.blockNumber); // Read the block to confirm timestamp const block = await provider.getBlock(tx.blockNumber); console.log('Block time:', new Date(block.timestamp * 1000).toISOString()); **Zero-trust verification** This entire process requires zero interaction with ChainMemory's servers. You connect directly to the blockchain's RPC endpoint and read the smart contract. Even if ChainMemory's API were compromised or offline, the on-chain data remains verifiable. **MetaMask alternative** You can also verify visually: add the ChainMemory network to MetaMask, navigate to the contract address in the [Explorer](https://chainmemory.ai/explorer), and inspect the transaction data manually. --- ## FAQ ### General #### Is ChainMemory free? Yes. The Faucet plan is free and includes memory storage, context injection, and Project Brain (the Project State viewer). The faucet gives you free AIC to interact with the blockchain. #### Are my memories private? Yes. Your memories are only accessible with your API key. The only public data are the on-chain hashes (which reveal nothing about content) and the verification endpoints, which expose hashes and metadata. The encrypted content is stored on-chain and readable there, but never the plaintext. #### What if the AI generated incorrect content in a memory? Memories capture what was said in the conversation. If the AI generated incorrect information and you saved it, that memory will reflect the error. You can archive it, or quarantine it with `POST /v1/memories/:id/trust` so it is excluded from context and injection. The Project State does not change on its own: if an item was built on that memory, correct it with a new operation. #### Can I use ChainMemory with local models? Yes, via the REST API. Any application that makes HTTP calls can save and retrieve memories. You can also configure the MCP server with local or self-hosted models. #### Who builds the Project State? Your AI client. Through `update_project_state` (MCP) or `POST /v1/project/:name/state/ops` it proposes operations — add a decision, close a risk — citing the memories that support them. The server validates them, applies them with a deterministic builder and anchors the resulting hash on-chain. No server-side model reads your memories. #### What happens if my AI says contradictory things across sessions? Nothing resolves them automatically. Both memories stay, and the client that consolidates decides: it adds the newer decision and marks the older one with `supersede_decision`. Superseded decisions remain in the state with a "superseded" status, so you always have the full history. See [Conflict Resolution](#concept-conflicts) for details. #### Can I export my data? Yes. All your memories and project states are accessible via the REST API. You can fetch them in JSON format and process them however you need. ### Plans, Limits & Quotas | Resource | Free | Starter | Pro | Team | Enterprise | | Price | $0 | $9/mo | $29/mo | $79/mo flat | from $299/mo | | Memories/month | 100 | 500 | 5,000 | 50,000 | Unlimited | | Injects/month | 5 | 15 | 100 | 1,000 | Unlimited | | Projects | 3 | 10 | 25 | Unlimited | Unlimited | | Users | 1 | 1 | 1 | Up to 10 | Unlimited | | Retention | 90 days | 1 year | Unlimited | Unlimited | Unlimited | | API requests/min | 30 | 60 | 120 | 300 | 600 | | AIC credits/month (use + gift) | 1 welcome | 30 + 60 | 120 + 250 | 600 + 1,300 | Custom | | RBAC + shared audit trail | — | — | — | 4 roles | 4 roles + SSO | Memories are never deleted: past your plan's retention window they are archived, and their on-chain hash exists forever. Upgrading restores full access to your history. Gift AIC accumulates monthly, never expires, and unlocks according to the protocol calendar. --- ## LIMITS & QUOTAS Protocol fees in AIC are identical on every plan: a Free account and an Enterprise account pay the same per operation. What a plan changes is **volume** — and how much of that volume the system enforces today. Both are stated below, separately and on purpose. ### Limits by plan | Limit | Free | Starter | Pro | Team | Enterprise | | Memories per month | 100 | 500 | 5,000 | 50,000 | unlimited | | Injections per month | 5 | 15 | 100 | 1,000 | unlimited | | Projects, at any one time | 3 | 10 | 25 | unlimited | unlimited | | Users | 1 | 1 | 1 | 10 | unlimited | | Project keys | 0 | 0 | 0 | 5 | unlimited | | Retention | 90 days | 365 days | unlimited | unlimited | unlimited | | Requests per minute | 30 | 60 | 120 | 300 | 600 | | Monthly AIC — usage + gift | — | 30 + 60 | 120 + 250 | 600 + 1,300 | custom | These are the values in the `tier_entitlements` table the server reads at runtime, not a marketing summary. An unlimited value is stored as `-1`, and the check is skipped entirely. ### What resets, and when - **Memories and injections are monthly.** The counter starts again on the first day of each month at 00:00 UTC. Free gives you 100 memories *every month*, not 100 in total. - **Projects are a concurrent cap**, not a monthly allowance: it is how many you may hold at once. Deleting one frees a slot. ### What is enforced today The server checks three operations against your plan: saving a memory, injecting context, and creating a project. **Limits currently warn, they do not block** When you go over a limit the event is recorded and the response carries an `X-Plan-Limit-Warning` header — but the request still completes. Blocking arrives with real billing; this page will say so when it changes. Once blocking is active, exceeding a limit returns `402` with `plan_limit_reached`, the limit, your usage and an upgrade link. A limit never touches your data: reading, verification and export keep working regardless. **When a paid period ends**, the plan stays in effect for a **3-day grace period**; after that the account resolves to Free until it is renewed. `GET /v1/billing/status` shows `period_end`, `grace_until`, `in_grace` and `expired`. ### What is declared but not yet enforced These values are published, returned by the API and part of the plan — but nothing acts on them yet. They are listed here rather than left to be discovered: - **Requests per minute** — the figure is real and documented, but no rate limiter reads it today. The only request limit in force is per IP at the proxy (30 requests per second per IP), the same for every plan. - **Retention** — nothing is archived or removed when the period elapses. Memories are never deleted in any case, and the on-chain fingerprint is permanent regardless of plan. - **Users and project keys** — the organization module issues them; the ceiling is not checked at issue time. - **Monthly AIC allowance** — the amounts are defined but crediting is not implemented. The API says so itself: `crediting: "Sprint B3 (pendiente)"`. **Check your own numbers** `GET /v1/billing/status` returns your effective tier and where it comes from, the enforcement mode in force, every limit above, and your usage so far this month. It reads the same source this page describes, so the two can never drift apart. --- ### Changelog #### Platform — September 2026: Provenance, Machine Discovery & Anchoring - **Provenance guard** — `POST /v1/project/:name/state/ops` now rejects the whole call with `422 evidence_unresolved` if any cited memory cannot be resolved, instead of silently dropping it; ops with no evidence carry a `provenance_warning` - **OpenAPI 3.1** at `api.chainmemory.ai/openapi.json`: 41 operations, including public verification and injection - **llms.txt** rewritten on chainmemory.ai, api and docs with verified facts - **Blind vault** in the MCP server (v2.6.0+): memories encrypted client-side from a 12-word phrase the server never sees - **MCP v2.7.0**: 36 tools with descriptions rewritten for agents, closed value sets declared; published automatically to the official MCP Registry - Machine clients using Python's standard library are no longer blocked at the edge - Project State anchoring runs automatically again every 10 minutes; versions written during the infrastructure migration were anchored retroactively #### Platform — July 2026: Trust, Rollback & Forensics - **Trust status on every memory** — memories are screened at write time by deterministic, auditable rules; suspicious ones are born `tentative` and always delivered marked - **Owner governance**: `POST /v1/memories/:id/trust` (approve / quarantine / tentative); quarantined memories are excluded from context, inject, quotes and oracle — their on-chain fingerprint remains as immutable evidence - **Verifiable rollback**: `POST /v1/project/:name/state/rollback` — append-only restore, byte-identical to the anchored source version; faithfulness proven by hash equality, history never mutated - **Memory forensics**: `GET /v1/memory/:id/forensics` — complete timeline of a memory: birth, trust, anchoring, every recall and injection, Project Brain citations - Recall instrumentation: every read is now logged with per-memory counters and token accounting - Checkpoint anchoring pipeline repaired; dual-channel system alerts (Telegram + alert-as-memory) #### MCP v2.4.0 (June 2026) - **New tool: `update_project_state`** — Autonomous consolidation via MCP. Any AI client can propose structured operations to update the Project Brain; the server validates, applies, and anchors on-chain. - 22-operation grammar for state mutations (decisions, milestones, risks, metrics, vocabulary, and more) - Resilient processing: invalid ops are rejected individually, valid ops still apply - Evidence linking via `evidence_memory_ids` — server resolves event hashes and builds Merkle proofs automatically - Architecture: *“client consolidates, chain verifies”* #### Platform — June 2026 - Project Brain consolidated and anchored on-chain (versions v1–v8, publicly verifiable) - Semantic search rewritten (faster, ~2.4s) - Non-custodial write path proven end-to-end (client signs, server never holds the key) - Encryption at rest (AES-256-GCM) for API keys - Public verification endpoint: `GET /v1/verify/:name` #### v3.0.9 (June 2026) - Fix: Project Brain displays decisions and risks correctly (Phase 2 schema) - Fix: Memory numbering shows user sequential number #### v3.0.0 (May 2026) - Project Brain: consolidated state visualization - Consolidation Engine: complete pipeline - On-chain anchoring of Project State - Public verification API #### v2.0.0 (April 2026) - MCP Server for Claude Desktop and Cursor - Automatic context injection - Support for 5 AI platforms --- ## Public Endpoints - Landing & Explorer: https://chainmemory.ai - JSON-RPC: https://rpc.chainmemory.ai - REST API: https://api.chainmemory.ai - Faucet: https://faucet.chainmemory.ai - Documentation: https://docs.chainmemory.ai - Index for LLMs: https://docs.chainmemory.ai/llms.txt