EKOS — Enterprise Knowledge Operating System

Compile a GitHub repository
into an MCP server.

Not a wrapper around the GitHub API. A compiler pass — issues, PRs, files, and their real relationships become append-only, evidence-backed knowledge that any MCP-speaking agent can query directly.

GitHub repo Observer Recovery pass Ledger ekos mcp serve Claude / any agent
§ 01 / problem
Why this exists

Agents read your repo. They don't understand it.

A coding agent can grep your issues and diff your PRs, but it re-derives the same facts every session: which files a PR actually touched, which issue a merge closed, what depends on what. None of it persists, and none of it is traceable back to a source.

  • TodayFree-text issues/PRs, re-read and re-guessed on every prompt.
  • MissingA structured "references X" relationship agents can query instead of infer.
  • EKOSCompiles that relationship once, stores it with evidence, serves it over MCP.
§ 02 / architecture
The pipeline

One compiler, four semantic primitives.

Object · Relationship · Event · Evidence — everything GitHub emits gets mapped onto these before it ever reaches an agent.

Source
GitHub repo
Observation
GitHubObserver
Compiler pass
GitHubAnalyzerPass
Storage
Semantic Ledger
Runtime
read-only
Interface
ekos mcp serve
§ 03 / observe
Stage 1 — Observation

Every issue and PR becomes one artifact.

GitHubObserver walks GET /issues?state=all and GET /pulls/{n}/files, distinguishing issues from PRs the same way GitHub's own API does. A MockGitHubClient exercises the real mapping logic with zero network dependency — the same discipline used for every other connector in the codebase.

  • EmitsOne ObservationArtifact per issue/PR, target "{owner}/{repo}#{number}"
  • Config[connectors.github] — owner, repo, token env var
observation-sdk / github
pub struct GitHubItem {
    pub number: u64,
    pub title: String,
    pub body: String,
    pub state: String,          // "open" | "closed"
    pub is_pull_request: bool,
    pub files_changed: Vec<String>,
}

pub trait GitHubClient: Send + Sync {
    async fn list_items(
        &self, owner: &str, repo: &str
    ) -> Result<Vec<GitHubItem>, GitHubClientError>;
}
§ 04 / compile
Stage 2 — Recovery pass

Text becomes traceable relationships.

GitHubAnalyzerPass
// PR → changed file
References(pr_id, file_id)
  evidence: "the PR's file-change entry"

// body text: "Fixes #12"
References(issue_47, issue_12)
  evidence: "body sentence containing keyword"

// deterministic id — stable across re-runs
Uuid::new_v5(NAMESPACE, "github:{owner}/{repo}#{n}")

Every PR's files_changed becomes a References edge to that file's object. Every recognized closing keyword — closes, fixes, resolves — becomes a References edge between items. No LLM guesses at the relationship; GitHub already told us what closed what.

  • IdempotentSame item, same run, same object id — every re-ekos recover converges.
  • EvidencedEvery edge cites the exact file entry or body sentence that produced it.
§ 05 / store
Stage 3 — The ledger

Append-only. Content-addressable. Never rewritten.

  • ObjectAn Issue or PullRequest — named, typed, with its number/state/body excerpt as properties.
  • RelationshipA References edge — PR → file, or item → item via a closing keyword.
  • EvidenceThe literal source text every conclusion traces back to — never optional.
  • EventA timestamped fact in the append-only stream, replayable at any point in time.

The ledger never edits history — it only appends. That single invariant is what makes ekos_diff possible downstream: "what has changed since T" is a query over the log, not a guess from two snapshots.

§ 06 / serve
Stage 4 — ekos mcp serve

Seven tools. One read-only runtime.

stdio, newline-delimited JSON-RPC 2.0 — the transport every MCP client already speaks. No network surface, no auth story, no new dependency.

MCP toolAnswers
ekos_searchFind an object by name or kind
ekos_neighborhoodWhat's connected to this, N hops out
ekos_dependentsWhat breaks if this changes — incoming vs. outgoing edges
ekos_stateReconstruct state as of any RFC 3339 timestamp
ekos_diffWhat knowledge changed since T
ekos_eklRun a structured knowledge-query expression
ekos_statusLedger entry / object / relationship counts
§ 07 / invariants
Why an agent can trust it

Four guarantees no vector index gives you.

Read-only Runtime

The handler holds no write path — an agent can query the ledger but never mutate it.

Evidence-traceable

Every Object and Relationship cites the exact source line that produced it — no unsourced claims.

Append-only

Nothing is edited in place, so "what changed since T" is a real, replayable query.

Deterministic ids

The same issue or PR resolves to the same object across every rebuild — no drift, no duplicates.

Try it

Point an agent at your repo. Not the API — the compiled knowledge.

terminal
# compile the repo once
$ ekos build

# serve it to any MCP client over stdio
$ ekos mcp serve --workspace .

# point Claude Code / Claude Desktop at it — one line of config
{ "command": "ekos", "args": ["mcp", "serve"] }
EKOS · RFC 0013 (MCP Server) + RFC 0020 (GitHub Connector) · github.com — coming soon