EKOS
EKOS는 기업 지식을 지속적으로 재구성, 컴파일, 저장 및 제공하는 AI 네이티브 플랫폼입니다.
문서
Compile a GitHub repositoryinto 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.
§ 01 / problem
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
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
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
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>;
}
Text becomes traceable relationships.
// 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 recoverconverges. - EvidencedEvery edge cites the exact file entry or body sentence that produced it.
§ 05 / store
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
Eleven 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 tool | Answers |
|---|---|
| ekos_search | Find an object by name or kind |
| ekos_neighborhood | What's connected to this, N hops out |
| ekos_dependents | What breaks if this changes — incoming vs. outgoing edges |
| ekos_impact | Multi-hop blast radius across the whole graph |
| ekos_state | Reconstruct state as of any RFC 3339 timestamp |
| ekos_diff | What knowledge changed since T |
| ekos_ekl | Run a structured knowledge-query expression |
| ekos_status | Ledger entry / object / relationship counts |
| ekos_transformation_explain | What a legacy ETL/SQL transformation actually does, evidence per step |
| ekos_transformation_diff | Did a migration change a transformation's meaning |
| ekos_identity_review | Confirm/reject a cross-system identity match — the one write-capable tool |
§ 07 / invariants
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.
§ 08 / install & run
Clone, build, compile, serve.
terminal — macOS / Linux / WSL2
# 1. clone — the Cargo workspace root is ekos/, not the repo root
$ git clone https://github.com/alexeyban/EKOS.git
$ cd EKOS/ekos
# 2. build (needs Rust stable via rustup.rs + a C toolchain)
$ cargo build --release --workspace
$ cargo install --path crates/cli
# 3. compile a workspace's knowledge, once
$ cd /path/to/your/repo
$ ekos init
$ ekos build && ekos recover && ekos resolve && ekos compile && ekos commit
# 4. serve it over MCP, stdio
$ ekos mcp serve --workspace .
Prerequisites: Rust stable (2024 edition needs rustc 1.85+) and a C/C++ toolchain — rusqlite 's bundled SQLite and the zstd crate both compile native C at build time even though the project itself is pure Rust. Windows has a native path too (winget + MSVC build tools); WSL2 is the path of least friction if you'd rather follow the Linux steps unmodified.
- Verify
ekos --help·cargo test --workspace— 500+ tests - GitHub connector config
[connectors.github]inekos.toml— owner, repo, token env var - Full OS-by-OS stepsREADME.md → Installation (macOS, Windows native, WSL2)
Point an agent at your repo. Not the API — the compiled knowledge.
terminal — wire it into Claude Code
# register the server — path-based
$ claude mcp add ekos -- ekos --config ekos.toml \
mcp serve --workspace /path/to/workspace
# or path-free, via env vars
$ claude mcp add ekos --env EKOS_WORKSPACE=/path/to/workspace \
-- ekos mcp serve
"What does PR #47 actually close,
and which files does it touch?"
→ ekos_neighborhood(pr_47_id)
{ "relationships": [
{ "kind": "References", "to": "issue_12",
"evidence": "body: closes #12" },
{ "kind": "References", "to": "file:src/auth.rs",
"evidence": "PR file-change entry" }
] }
EKOS · RFC 0013 (MCP Server) + RFC 0020 (GitHub Connector) · github.com/alexeyban/EKOS (main branch)