EKOS — Enterprise Knowledge Operating System

Claude Code stops re-deriving your codebase from scratch.

Every question Claude Code asks about a repo — where's this implemented, what does this module do, what else touches this — has an answer EKOS already compiled, with the evidence attached. Served read-only over MCP, so Claude reads a cited answer instead of grep-read-reread-forget. Every number on this deck was measured live against this repo and a real compiled ledger, not estimated.

grep → open file → open file → …vs one MCP call, evidence attached
§ 01 / without EKOS
The question: "where is Observer implemented?"

Grep finds the files. Understanding them means opening every one.

$ grep -rln "impl Observer for" ekos/plugins/ ekos/crates/
ekos/plugins/oracle/src/lib.rs
ekos/plugins/pentaho/src/lib.rs
ekos/plugins/confluence/src/lib.rs
ekos/plugins/snowflake/src/lib.rs
ekos/plugins/file/src/lib.rs
ekos/plugins/sap/src/lib.rs
ekos/plugins/crypto/src/lib.rs
ekos/plugins/fabric/src/lib.rs
ekos/plugins/salesforce/src/lib.rs
ekos/plugins/github/src/lib.rs
ekos/plugins/git/src/lib.rs
ekos/plugins/localdocs/src/lib.rs

12 files, one round-trip — cheap. But the grep hit only says where, not what each one does. Confirming that means opening all 12, full files, before Claude can actually answer the question.

  • Locategrep -rn output: 851 bytes
  • Confirmall 12 lib.rs files, read in full: 149,194 bytes
  • Round-trips1 grep + 12 reads = 13 tool calls
§ 02 / with EKOS
Same question, through the MCP server

One call. Structured. Ids ready for the next hop.

ekos_search(query: "Observer trait")
{ "matches": [
  // all 7 real plugin implementers,
  // each with an id for the next call
  { "id": "7cdc5253-...", "name":
     "ekos/plugins/file/src/lib.rs" },
  { "id": "8941bcba-...", "name":
     "ekos/plugins/git/src/lib.rs" },
  { "id": "62e147c2-...", "name":
     "ekos/plugins/salesforce/src/lib.rs" },
  // … 14 more matches, incl. Cargo.toml
  // and one RFC — see § 08
] }

One tool call returns 17 ranked matches — every real plugin implementer plus some Cargo.toml/RFC noise, honestly (see § 06). Each match carries an id: no second grep needed to go deeper, just ekos_state(id) or ekos_neighborhood(id) on the ones that matter.

§ 03 / measured, side by side
The numbers that actually moved

The win isn't always fewer bytes. It's fewer round-trips — and it compounds on wayfinding.

StepWithout EKOSWith EKOS
Locate all Observer implementers851 B (grep) → then 12 more reads1,620 B, 1 call, ids included
Round-trips to a usable answer13 (1 grep + 12 reads)1
"What does this module do?" (observation-sdk/lib.rs)8,490 B — the whole file600 B curated excerpt, ~14x smaller

First hop's raw bytes: EKOS's 1,620 B response is larger than the 851 B grep output, because it carries structure (ids, evidence) grep can't — the payoff shows up one hop later, when EKOS needs zero further reads to know what each file is and grep needs 12. The wayfinding case is the clean win: a 600-byte excerpt instead of the full 8,490-byte file for "what is this module for."

§ 04 / why this matters for an agent specifically
Not just shorter — traceable

Every object carries the evidence it was compiled from.

ekos_neighborhood — observation-sdk/lib.rs
{ "objects": [{
  "name": "ekos/crates/observation-sdk/src/lib.rs",
  "evidence": ["29069ec0-..."],
  "properties": {
    "artifact_id": "b4aa558e...",
    "excerpt": "//! Observation SDK —
      contract between the compiler and
      connectors. Every connector ...
      implements the \`Observer\` trait ..."
  }}]}

A plain grep result is a filename and a line number — Claude still has to trust its own reading of the file to answer correctly. An EKOS object ships the excerpt it was compiled from and an evidence id pointing at the exact artifact_id behind it. Claude can cite the fragment instead of paraphrasing from memory — the same append-only, evidence-backed guarantee the rest of EKOS runs on, not a special case for MCP.

§ 05 / past one repo
The ledger doesn't stop at this repo's boundary

One workspace, many projects, still one call.

88,637
compiled entries in the live ledger
22,032
objects across the whole workspace
10,335
relationships compiled so far

ekos_status, called live: this ledger spans every project under the workspace root, not just EKOS itself. Without it, a question that crosses repo boundaries means cd-ing into each one and repeating the whole grep/read cycle per project. With it, the query surface doesn't change — same ekos_search call, same evidence guarantee, whichever project the answer turns out to live in.

§ 06 / what it costs to have EKOS available
Tool schemas load on demand, not eagerly

Deferred loading means idle capability isn't a token tax.

/context — this session, real output
System prompt      9.6k tokens  (1.0%)
System tools      12.6k tokens  (1.3%)
MCP tools            595 tokens  (0.1%)
Custom agents        992 tokens  (0.1%)
Messages         111.4k tokens (11.5%)
Free space       787.8k        (81.5%)

967k token window, claude-sonnet-5

Only 4 of EKOS's 11 MCP tools were ever loaded into this session's context — ekos_status, ekos_search, ekos_dependents, ekos_neighborhood — because those are the ones this session actually called. The other 7 (ekos_state, ekos_ekl, ekos_diff, ekos_impact, ekos_identity_review, ekos_transformation_explain/_diff) stay unloaded, fetchable on demand, costing nothing until asked for. All 11 definitions loaded eagerly would run ~2,208 tokens combined — instead this session paid 595, 0.1% of the 967k-token window.

§ 07 / not staged for this deck
Pulled from real session transcripts, last 24 hours

What EKOS usage actually looks like when nobody's demoing it.

SessionAskedTool calls
5a904f01…"What changed across the workspace in the last 7 days?"ekos_status, ekos_diff
cd71a423…"Where is auth implemented across the estate, and what breaks if Postgres → Cosmos DB?"13 calls: status, search ×3, state ×5, dependents ×2, ekl
7247d986… (this one)Researching the token-cost example for § 03–05 of this deck6 calls: status, search ×2, dependents, neighborhood ×2

2 ekos-knowledge skill invocations, 21 mcp__ekos__ekos_* calls, across 3 sessions in a 24-hour window — 8 other sessions active in the same window made zero EKOS calls, honestly: not every task needs a compiled ledger. Source: ~/.claude/projects/<project>/*.jsonl, grepped for tool_use blocks.

§ 08 / honest limits
Where grep still wins outright

Search is excerpt-ranked today, not symbol-aware — and it shows.

ekos_search(query: "PassManager") — real response
{ "matches": [
  { "name": "compiler-core/src/lib.rs" },
  { "name": "0001-compiler-core.md" },
  { "name": "compiler-core/Cargo.toml" }
]}
// pass.rs — where PassManager is actually
// *defined* — never appears.

grep -rn "PassManager" finds pass.rs immediately — 14 hits, one command. EKOS's search ranks by file/excerpt relevance, not by symbol definitions, so a type's actual home file can lose to files that merely mention its name. Today EKOS is a wayfinding and evidence layer — the fast first hop and the cross-project reach — not a replacement for a symbol-level call graph or a deep-dive Read. Stated plainly, the same way two other real gaps got filed and fixed instead of hidden.

Try it

One command wires Claude Code to your compiled ledger.

terminal
# compile once
$ ekos build && ekos recover && ekos resolve && ekos compile && ekos commit

# register the MCP server with Claude Code
$ claude mcp add ekos -- ekos mcp serve --workspace .
DocWhere
Full scripted walkthroughdemo/DEMO.md — 12 acts, real subagents, real transcripts
MCP tool referenceekos/crates/cli/src/commands/mcp.rs — all 11 tools, one write-capable
EKOS · RFC 0013 (MCP server) · every number above measured live against this repo, github.com/alexeyban/EKOS