sage-wiki
Local-first knowledge graph that compiles documents into an interlinked, human-readable wiki with provenance. Exposes 19 MCP tools over stdio/SSE and a versioned REST API under /v1/. Output is Obsidian-compatible markdown.
How to connect
MCP (primary): The server runs as a subprocess over stdio, or over SSE/HTTP:
{
"mcpServers": {
"sage-wiki": {
"command": "sage-wiki",
"args": ["serve", "--transport", "stdio", "--project", "/path/to/wiki"]
}
}
}
REST (/v1/): When the server is running with --ui, the REST facade is at /v1/. Auth is Bearer-token (same as SAGE_WIKI_TOKEN); loopback is zero-config. All errors use a fixed {error: {code, message, details}} envelope.
The 19 MCP Tools
wiki_add_ontology (write)
Create an ontology entity or relation.
- REST: POST /v1/ontology/entities / POST /v1/ontology/relations
Argument Type Required Default entity_idstring no — entity_namestring no — entity_typestring no — relationstring no — source_idstring no — target_idstring no —
wiki_add_source (write)
Add a source file to a source folder and update the manifest.
- REST: POST /v1/sources
Argument Type Required Default pathstring yes typestring no —
wiki_capture (write)
Capture knowledge from a conversation or text.
- REST: POST /v1/capture
Argument Type Required Default contentstring yes contextstring no — tagsstring no —
wiki_commit (write)
Git add and commit all changes.
- REST: POST /v1/git/commit
Argument Type Required Default messagestring no —
wiki_compile (async)
Run the full compile pipeline: diff → summarize → extract concepts → write articles.
- REST: POST /v1/jobs/compile (async — 202 + job_id)
Argument Type Required Default dry_runboolean no false freshboolean no false pruneboolean no false
wiki_compile_diff (read)
Show added/modified/removed source files compared to the manifest.
- REST: GET /v1/compile/diff
wiki_compile_topic (async)
Compile sources for a specific topic on demand.
- REST: POST /v1/jobs/compile?topic=... (async — 202 + job_id)
Argument Type Required Default max_sourcesnumber no — topicstring yes
wiki_graph_query (read)
Answer a relational question by graph traversal: seed entities are resolved from the question (aliases resolve to their canonical entity), a bounded multi-hop subgraph is serialized, and the answer is grounded ONLY in those edges — every citation carries source_doc and confidence provenance.
- REST: POST /v1/graph/query
Argument Type Required Default as_ofstring no — hopsnumber no — max_edgesnumber no — modestring no — questionstring yes
wiki_learn (write)
Store a learning entry for the self-learning loop.
- REST: POST /v1/learnings
Argument Type Required Default contentstring yes tagsstring no — typestring yes
wiki_lint (async)
Run linting passes on the wiki.
- REST: POST /v1/jobs/lint (async — 202 + job_id)
Argument Type Required Default fixboolean no false passstring no —
wiki_list (read)
List wiki articles, optionally filtered by entity type.
- REST: GET /v1/entities
Argument Type Required Default typestring no —
wiki_ontology_query (read)
Query the ontology graph.
- REST: GET /v1/ontology/{entity}/traverse
Argument Type Required Default depthnumber no — directionstring no — entitystring yes relationstring no —
wiki_provenance (read)
Show source-article provenance.
- REST: GET /v1/provenance
Argument Type Required Default articlestring no — sourcestring no —
wiki_query (compound)
Ask a free-form question against the wiki: searches sources and compiled articles, synthesizes a cited answer with the LLM (spends LLM budget), and files the result to wiki/under_review/ by default (trust output review) or wiki/outputs/ only when trust include_outputs is 'true'.
- REST: —
Argument Type Required Default questionstring yes top_knumber no —
wiki_read (read)
Read the full content of a wiki article by path.
- REST: GET /v1/articles/{path}
Argument Type Required Default pathstring yes
wiki_search (read)
Search the wiki with hybrid retrieval: BM25 + vector over documents and chunks, fused with ontology-graph proximity.
- REST: GET /v1/search
Argument Type Required Default boost_tagsstring no — channelsstring no — expandboolean no false limitnumber no — querystring yes rerankboolean no false tagsstring no —
wiki_status (read)
Show wiki stats: sources, concepts, entries, vectors, entities, relations.
- REST: GET /v1/status
wiki_write_article (write)
Write a concept article, create ontology entity, and embed vector.
- REST: PUT /v1/articles/{concept}
Argument Type Required Default conceptstring yes contentstring yes
wiki_write_summary (write)
Write a summary markdown file, index in FTS5, and optionally embed vector.
- REST: PUT /v1/summaries
Argument Type Required Default conceptsstring no — contentstring yes sourcestring yes
Error Codes
Branch on code, never on message:
| Code | HTTP | When |
|---|---|---|
invalid_argument |
400 | Missing, malformed, or out-of-range argument. |
unauthenticated |
401 | Missing or invalid Bearer token. |
forbidden |
403 | Host not allowed; path containment violation. |
not_found |
404 | Article, entity, or job does not exist. |
conflict |
409 | Compile already in progress; job already finished. |
feature_disabled |
412 | as_of without temporal enabled; mode=global without communities enabled. |
payload_too_large |
413 | Capture content over 100 KB. |
internal |
500 | Unclassified tool failure. Message must not leak paths. |
unavailable |
503 | Backend / store unavailable. |
Opt-In Features
All opt-in flags live under config.yaml → ontology:
| Flag | Default | Unlocks |
|---|---|---|
ontology.temporal.enabled |
true | Historical queries (as_of in graph_query), temporal validity edges. |
ontology.triples.enabled |
false | Subject-predicate-object fact extraction from articles. |
ontology.resolve.enabled |
false | Entity resolution — merges duplicate entities across documents. |
ontology.communities.enabled |
false | Community detection via Louvain; mode=global in graph_query. |
Tiers
Sources are assigned a tier determining compile depth:
| Tier | Label | What Happens |
|---|---|---|
| 0 | Index | File metadata only — no LLM cost. |
| 1 | Embed | Vector embeddings — no LLM summarization. |
| 3 | Full Compile | Summarize → extract concepts → write articles. Tier 3 is ~5–8 min/doc. There is no Tier 2. |
There is no Tier 2. Tiers go 0 → 1 → 3.
Important Correctness Points
- Tiers are 0 / 1 / 3 — there is no Tier 2. Documents and tooltips that claim a Tier 2 are wrong.
ontology.temporal.enableddefaults true (per code).ontology.triples,ontology.resolve, andontology.communitiesdefault false.as_ofrequiresontology.temporal.enabled;mode=globalrequiresontology.communities.enabled.compileandlintare job submissions — they return202 Acceptedwith ajob_id, not a blocking result. PollGET /v1/jobs/{id}for status.- Evidence spans (
provenance) quote the compiled summary, not the source document. The summary is the distilled, LLM-processed form.
Install
# MCP (stdio — primary integration path)
sage-wiki serve --project /path/to/wiki
# REST (with Web UI)
sage-wiki serve --ui --project /path/to/wiki
# Agent skill installation
npx skills add https://github.com/xoai/sage-wiki --skill sage-wiki
Pre-1.0 notice: Every surface here is experimental. Tool semantics, argument names, and REST routes may change between versions. Pin the version you depend on.
Generated by tools/skillgen — 19 tools in registry.