cite-citadel — an LLM-maintained, fully-cited personal wiki in the Open Knowledge Format, fed by a coding-agent CLI you already have logged in, with an MCP search server. Every fact is cited to its source; nothing is invented.
Project description
cite-citadel
A fortress of cited knowledge. An LLM-maintained, fully-cited personal wiki — every fact is attested to its source, nothing is invented.
An LLM-maintained personal wiki in Google's Open Knowledge Format (OKF), with an MCP server (and a CLI that mirrors every MCP tool) so an AI can search and read it — a KISS, pure-Python 3.12 take on Andrej Karpathy's LLM-Wiki pattern.
Drop arbitrary files into raw/, in any sub-folder — if the agent CLI you use can open it, citadel
can ingest it (few exceptions). One agentic CLI session per source folds it into a cross-linked OKF
wiki under wiki/, routing each fact to the page it best fits and splitting/merging pages as the
corpus grows rather than making one page per file. Built-in helpers cover the rest: Office text
extraction, visual image reading, multi-pass folding for oversized files, duplicate-format dedup, and a
record (with the reason) in wiki/sources/index.md for anything that can't be read. Every fact cites its
raw/ source and the model uses only what is in raw/; an AI client then queries the synthesized
wiki over MCP instead of re-reading your notes.
The CLI is citadel; the PyPI package is cite-citadel. The wiki/ directory is the
database — no SQLite, no vector store. Ingest runs through a coding-agent CLI you already have
(claude, copilot, or gemini), so it uses your existing subscription and needs no API key —
that usage is under your account and your provider's terms (see
License & third-party tools).
Three guarantees that hold as the wiki grows (full rules in
citadel/rules/schema.md):
- Stays organized — ingest merges, splits, and deletes pages by fit; it never piles up one page per raw file.
- Links keep working — merges/renames repoint inbound cross-links; any dangling link fails
citadel lint/citadel check. - Honest provenance — raw facts are restated faithfully and cite their source as
[^sN]. A fact the model adds from its own knowledge must be labeled[^llmN], never disguised as a raw citation.
Quickstart
Ingest runs through a coding-agent CLI you already have — no API key, just your existing subscription.
uv init my-wiki && cd my-wiki
uv add cite-citadel
uv run citadel init
nano .env # pick your agent CLI (claude | copilot | gemini) — must be logged in
cp ~/notes/* raw/ # drop in anything your agent can open
uv run citadel ingest # one agent session per source builds the cited wiki
uv run citadel view # browse it offline
Every other knob is documented inline in the generated .env. A global install (uv tool install cite-citadel; plain pip install cite-citadel works too) drops the uv run prefixes. On Windows,
use uv run python -m citadel — the uv run citadel shorthand can be antivirus-blocked (see the
contributor note below). citadel serve exposes the wiki to any AI over MCP — and everything the
MCP server offers, the CLI offers too (search, read, status, …), so an AI without MCP access
can drive citadel through equivalent shell commands.
Local models. For a fully private wiki, point the same agent CLI at a local model (Ollama) so nothing you ingest ever leaves your machine or LAN — see Local models (Ollama).
Contributing? Run from a checkout:
uv sync, then the portableuv run python -m citadel <subcommand>(identical on Linux/macOS/Windows and needs no.exe— on Windows, antivirus can quarantine uv's generatedcitadel.exe).
How it works
Three layers (Karpathy's split; citadel/rules/schema.md has the
authoritative rules, which the ingest agent reads — referenced by path — every run):
raw/— immutable sources; ingest reads but never edits them.wiki/— the LLM-owned OKF bundle: markdown pages with YAML frontmatter, routed by kind intoconcepts/,objects/,systems/,persons/,organizations/,projects/,abbreviations/,misc/, densely cross-linked, each fact carrying a citation. The reservedindex.md,log.md, andsources/index.mdare generated, not authored.citadel/rules/— the schema/rules layer:schema.md(the format contract) +core.md(agent behavior) + per-lifecycletasks/, per-file-typeformats/, and agent-judgedgenres/briefs. Editing them changes how the wiki is built with no code change. The rules live in the package so a pip install carries them.
Per-fact provenance is the load-bearing rule. Every factual sentence ends with a GitHub-Flavored
Markdown footnote, defined in a trailing ## Sources section that links to the originating raw/
file:
Robusta has about twice the caffeine of Arabica.[^s1]
## Sources
[^s1]: [raw/coffee-guide.md](../../raw/coffee-guide.md) — coffee guide (ingested 2026-06-30)
This renders on GitHub, is trivially greppable, and needs zero custom tooling. A claim that can't be
cited is dropped, never invented; conflicting sources produce a > [!CONTRADICTION] callout. The
wiki/ folder also opens as-is as an Obsidian vault.
Test corpora
Five synthetic corpora live under corpora/, each ingestible on its own or all
together. The everyday showcase is corpora/beverages/ — a deliberately
overlapping coffee + tea corpus of 10 files in mixed styles (reference, prose, lab notes, FAQ,
brand blog) with facts that repeat, contradict, and hide in one place, plus one deliberately-false
sourced claim. Two more corpora stress the hardest guarantees:
corpora/kelvarra/ is a coherent fictional world whose
facts contradict reality, graded that they appear as stated, cited, never corrected;
corpora/leuchtfeuer/ is a three-year programme ingested in dated
waves that drives reconcile / delete / force and grades temporal supersession, German→English,
and attributed opinions (its committed raw/ is the FINAL post-wave state; stages/ holds the wave
history). Two further corpora stress scale and safety:
corpora/pemberley/ is the whole of Pride and Prejudice as one
~730k-char source, testing large-source multi-segment chunking, relationship extraction, and
narrative supersession; corpora/injection-resistance/ is three mundane
documents with adversarial instructions embedded, graded that the agent treats them as content
and never executes them.
These are test inputs, not reference material. Every wiki here is machine-generated by an LLM agent from the raw sources, and some corpora deliberately contain planted errors, contradictions, or entirely fictional "facts" — do not treat any of them as real-world knowledge.
Each corpus ships a hidden answer key at .claude/skills/verify-corpus/<name>/ground-truth.md
(outside the corpus, so the ingest agent can never see it). The parameterized verify-corpus skill
(verify-corpus <name>|all) ingests a corpus into a throwaway sandbox and grades the result against
that key by querying the wiki through citadel's own read tools, the way a user would — an end-to-end
test that every guarantee is not just built but findable. Each corpus also carries its own committed,
graded showcase wiki at corpora/<name>/wiki/, lint-checked in CI.
See the result without running anything. Browse any generated showcase wiki on GitHub — e.g.
corpora/beverages/wiki/index.md — GitHub renders the OKF pages natively, so the [^sN] citations,
cross-links, glossary, and > [!CONTRADICTION] callouts all show inline. For the richer, interactive
view — the cross-link graph, tags, and the cited raw sources embedded — open the live demo gallery
at markusneusinger.github.io/cite-citadel, which
serves one offline single-file viewer per corpus, regenerated on every push.
MCP server
citadel serve exposes eight tools over stdio: wiki_search, wiki_read, wiki_index,
wiki_sources, wiki_tags, wiki_validate, wiki_lint (read-only), and wiki_ingest (the only
mutating one). Each carries MCP behavior annotations (readOnlyHint etc.) so a client can tell the
readers from the one mutating tool. Every MCP tool has a CLI counterpart — citadel read,
citadel index, citadel sources, citadel lint, … — so an AI without MCP access can do
everything through the CLI. Wire it into an MCP client (e.g. Claude Desktop):
{
"mcpServers": {
"citadel": {
"command": "citadel",
"args": ["serve"],
"env": { "CITADEL_LLM_CLI": "claude", "CITADEL_INGEST_MODEL": "sonnet" }
}
}
}
An AI can then wiki_index() to orient, wiki_search(...) to find pages, and wiki_read(...) to
pull full cited context — answering from your synthesized wiki instead of re-retrieving documents.
Reference
citadel/rules/README.md— index of the rules tree the ingest agent follows:schema.md(structure, routing, and provenance rules),core.md(operational behavior), plus thetasks/,formats/, andgenres/briefs.citadel/templates/env.example— every configuration knob (thecitadel init.envtemplate).docs/karpathy-llm-wiki.md·docs/okf-reference.md— the pattern and the format.docs/configuration.md— everyCITADEL_*config knob.CLAUDE.md— architecture notes for contributors.CONTRIBUTING.md·CHANGELOG.md·SECURITY.md
License & third-party tools
cite-citadel is released under the MIT License.
Not affiliated. cite-citadel is an independent project — not affiliated with, endorsed by, or sponsored by Anthropic, GitHub/Microsoft, or Google. "Claude", "GitHub Copilot", and "Gemini" are their respective owners' trademarks, named only to identify the user-supplied CLI. Full disclaimer: NOTICE.md.
Bring your own CLI — your account, your provider's terms. Ingest runs your authenticated coding-agent CLI under your account, and that usage is governed by that provider's terms, not by cite-citadel: Anthropic Consumer Terms / Commercial Terms, the GitHub Copilot product-specific terms, and the Gemini Code Assist / Gemini API terms. cite-citadel calls the official binary only — it does not proxy, store, or transmit your credentials. Honest caveat: heavy, unattended, or CI ingest against a consumer subscription may hit rate limits or a provider's automated-use expectations — for that scale prefer the tier the provider designates for programmatic use.
Your wiki is yours. The providers assign output rights to you, and cite-citadel claims nothing
over wiki/ content — publish the generated wiki freely.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cite_citadel-0.3.0.tar.gz.
File metadata
- Download URL: cite_citadel-0.3.0.tar.gz
- Upload date:
- Size: 362.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
19c84eeaab65506c2080ab3057361c8fc83beb36e0c001b7d566202b327861e0
|
|
| MD5 |
c5c3e0df7b1016a7f0d92c751773acbf
|
|
| BLAKE2b-256 |
4ea37fd65f277f53b341312c24a791e7e2262eda083a06856f0c18cc3742ad9f
|
Provenance
The following attestation bundles were made for cite_citadel-0.3.0.tar.gz:
Publisher:
release.yml on MarkusNeusinger/cite-citadel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cite_citadel-0.3.0.tar.gz -
Subject digest:
19c84eeaab65506c2080ab3057361c8fc83beb36e0c001b7d566202b327861e0 - Sigstore transparency entry: 2089557410
- Sigstore integration time:
-
Permalink:
MarkusNeusinger/cite-citadel@88443363d15c8ccb5d33d91b3cc44cc2e120fb0a -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/MarkusNeusinger
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@88443363d15c8ccb5d33d91b3cc44cc2e120fb0a -
Trigger Event:
push
-
Statement type:
File details
Details for the file cite_citadel-0.3.0-py3-none-any.whl.
File metadata
- Download URL: cite_citadel-0.3.0-py3-none-any.whl
- Upload date:
- Size: 244.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81a45a1899ad56589c2a3bd1b8d079b6b7299ea05a6f69acd7fbd724debd6448
|
|
| MD5 |
59a1a4b6bbbec386998656b6cca890ea
|
|
| BLAKE2b-256 |
9d2ce7c6b8abb458ed46abac2eb55c9c0f7cf5e51b10ec8a66614aaabf99741e
|
Provenance
The following attestation bundles were made for cite_citadel-0.3.0-py3-none-any.whl:
Publisher:
release.yml on MarkusNeusinger/cite-citadel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cite_citadel-0.3.0-py3-none-any.whl -
Subject digest:
81a45a1899ad56589c2a3bd1b8d079b6b7299ea05a6f69acd7fbd724debd6448 - Sigstore transparency entry: 2089557683
- Sigstore integration time:
-
Permalink:
MarkusNeusinger/cite-citadel@88443363d15c8ccb5d33d91b3cc44cc2e120fb0a -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/MarkusNeusinger
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@88443363d15c8ccb5d33d91b3cc44cc2e120fb0a -
Trigger Event:
push
-
Statement type: