Part of the Citrate Network — own the means of computation. · Docs · Run a node · Contribute → free membership
Citrate Atlas — the documentation webapp for the Citrate Network (the site published at docs.citrate.ai): guides, API references, live contract-address pages, and an in-page "Ask Atlas" assistant.
citrate-atlas is a Next.js app that renders the Citrate docs — tutorials, concept guides,
generated API references, a live contract-address table for chain 40204, and a changelog. It
ships an agentic "Ask Atlas" assistant backed by the Citrate inference gateway (OpenAI-
compatible), an MCP toolbox, and optional grounding in the live knowledge graph. Auth is
OIDC (via citrate-identity) and fails closed; a mock auth mode is provided for local
development. It is the human-facing companion to the SDKs and the rest of the stack.
Live site: https://docs.citrate.ai. Depends (at runtime, optionally) on the inference gateway (citrate-inference-gateway), identity (citrate-identity), and a chain RPC (citrate-chain) for the live sandboxes.
node --version # Node 20 LTS+ (Next 16 / React 19)
npm --versiongit clone https://github.com/CitrateNetwork/citrate-docs.git
cd citrate-docs
npm install
npm run build # generates content + changelog, then next build; runs bundle/auth gates
npm run typecheck # tsc --noEmit
npm test # vitestprebuild/predev regenerate the changelog and compile the Markdown content set. The
postbuild step runs confidentiality + auth-mode + access-clock + MCP-key gates and will
fail the build if a confidential doc or an unsafe auth default leaked into the bundle.
cp .env.example .env.local # then edit (see Configuration)
npm run dev # http://localhost:3000The dev script sets NEXT_PUBLIC_AUTH_MODE=mock ALLOW_MOCK_AUTH=1, so it boots with the
fixture tier-switcher and needs no external IdP — you can browse the docs immediately.
Verify it's up:
curl -sSf http://localhost:3000 >/dev/null && echo "atlas up on :3000"Production-style run (after npm run build):
npm start # next start on :3000 (expects real OIDC env)Wire Atlas to a local Citrate stack instead of the public services.
- Auth — for pure docs browsing, keep the default local
npm run dev(mock auth, no IdP). To exercise real login, run citrate-identity locally and set theOIDC_*vars to point at it (e.g.OIDC_ISSUER=http://localhost:4000), withNEXT_PUBLIC_AUTH_MODE=oidc. - Ask Atlas → local inference gateway — run
citrate-inference-gateway
and point Atlas at it:
Or point at any local OpenAI-compatible server with
CITRATE_INFERENCE_MODE=gateway CITRATE_GATEWAY_URL=http://localhost:8080/v1 # note the /v1 CITRATE_GATEWAY_API_KEY=cgk_... # server-only; never NEXT_PUBLIC_ CITRATE_MODEL_NAME=gemma-4-E4B-it-Q4_K_M
CITRATE_INFERENCE_MODE=local+CITRATE_INFERENCE_URL=http://127.0.0.1:8080/v1. If the backend is unreachable, Ask falls back to a deterministic extractive answer, so the docs still respond. - Live sandboxes → local chain — point the read-only sandboxes at your local devnet
(chain 40204):
CITRATE_RPC_URL=http://localhost:8545
- End-to-end check —
npm run dev, openhttp://localhost:3000, and ask Ask Atlas a question; a grounded answer confirms the gateway wiring.
For the full multi-repo bring-up, see the LOCAL_STACK guide at https://docs.citrate.ai.
Copy .env.example → .env.local. Key variables (full annotated list in .env.example):
| Env var | Default | Purpose |
|---|---|---|
NEXT_PUBLIC_AUTH_MODE |
oidc (prod) / mock (via npm run dev) |
auth mode; mock needs ALLOW_MOCK_AUTH=1 and a non-prod build |
OIDC_ISSUER / OIDC_JWKS_URL / OIDC_CLIENT_ID |
https://auth.citrate.ai … |
citrate-identity OIDC (required when oidc; fails closed if unset) |
CITRATE_INFERENCE_MODE |
gateway |
gateway | local | onchain |
CITRATE_GATEWAY_URL |
https://infer.citrate.ai/v1 |
Ask Atlas inference backend (append /v1) |
CITRATE_GATEWAY_API_KEY |
— | cgk_ bearer key (server-only) |
CITRATE_RPC_URL |
https://rpc.citrate.ai |
chain 40204 RPC for the read-only sandboxes |
MCP_API_KEYS |
{} (fail-closed → public) |
HMAC-keyed key→tier map for the MCP toolbox; entries come from node scripts/mint-mcp-key.mjs |
MCP_KEY_PEPPER |
unset (no key resolves) | server-only HMAC pepper for MCP keys: ≥ 32 chars, ≥ 8 distinct, no padding. A store without a usable pepper fails the build. Mint keys only with scripts/mint-mcp-key.mjs |
DOCS_TRUST_VERCEL_FORWARDED |
unset | 1 on Vercel only: key the rate limiter on x-vercel-forwarded-for |
.env.example documents the fail-closed defaults for auth, the MCP key hashing, and the
optional live knowledge-graph (MEM_*) wiring.
The contract-address pages are rendered at build time (prebuild and predev run
scripts/gen-addresses.mjs) from the canonical address book, one page per network. The precompile page
is generated from a citrate-chain checkout and committed (Vercel builds without the chain).
| Page | Generator | Inputs |
|---|---|---|
content/chain/_generated/addresses.md (/chain/addresses, the current network) and addresses-<network>.md (/chain/addresses/<network>, every network) |
npm run docs:addresses |
content/chain/networks.json; each network's book from its @citratelabs/chain-config npm alias, or a frozen copy of the chain's archived book in content/chain/address-books/; the getCode snapshots in content/chain/address-books/ |
content/chain/_generated/precompiles.md (/chain/precompile-addresses) |
npm run docs:precompiles |
core/execution/src/precompiles/mod.rs, core/execution/src/agent_fork.rs, the book's precompiles block |
content/chain/networks.json names every network, the one that is current, where its book comes from
(an npm alias, or, for the current network while its chain-config release is not yet published, a pinned
copy of the chain's root book with book.packagePending naming that release; the page then tells readers
the npm package is still the previous network's),
the sha256 of the book's bytes and its block-0 hash. The generator refuses a book whose bytes or genesis
hash differ from the registry and a getCode snapshot taken for another book. The address pages are
committed too, and a test fails if they differ from what the generator renders. truth-lint fails a
hand-written page that cites an address of a retired network that the current book does not carry.
The only hand-written precompile input is the description map in scripts/lib/precompile-descriptions.mjs.
The generator fails if the chain or the book has a precompile the map lacks, or the other way round.
Both generators take --chain <dir> (default ../citrate-chain) and --check (fail on drift, write
nothing). Under --check with a chain checkout, gen-addresses also fails when a registered book or
snapshot differs from the chain's copy, so a new genesis on chain main turns it red until this repo
follows. The chain-sync-check workflow runs both checks against CitrateNetwork/citrate-chain at the
repo variable CITRATE_CHAIN_REF (default main), on every PR and daily.
At a new genesis, once chain-config has published the new book (for example 0.3.0 for r1007), the
chain has archived the old root book, and the new getCode snapshot is on the chain checkout:
npm install --save-exact 'citrate-book-r1007@npm:@citratelabs/chain-config@0.3.0'
# content/chain/networks.json: add r1007 as "current" (package citrate-book-r1007, its genesisHash and
# chainPath contracts/addresses/40204.json); set r1006 to "archived" with retiredAt and the chainPath
# of the chain's archived r1006 root book; point "current" at r1007
git -C ../citrate-chain fetch origin && git -C ../citrate-chain checkout <genesis-commit-or-main>
npm run docs:addresses -- --sync --chain ../citrate-chain # snapshots, archived books, sha256 pins, pages
npm run docs:precompiles -- --chain ../citrate-chain
npm run content # rebuild content/_generated/content.ts
npm run docs:chain-check # both --check gates, expect green- Docs: https://docs.citrate.ai
- Depends on: citrate-identity · citrate-inference-gateway · citrate-chain
- Documents: citrate-sdk-js · citrate-sdk-python · citrate-sdk-marketplace
- Contributing (DCO):
CONTRIBUTING.md· Security:SECURITY.md· License:LICENSE
Licensed under the Apache License, Version 2.0 (see LICENSE). This is the open-source infrastructure tier of Citrate's open-core model. The commercial application layer is source-available under BUSL-1.1. Licensor: Citrate Inc.