|
| 1 | +# WhyGraph as a service |
| 2 | + |
| 3 | +Editors aren't the only thing that can talk to WhyGraph. The MCP server is a plain stdio program, so |
| 4 | +any application that speaks MCP can connect to it for git-based analysis of a target repo. Think of a |
| 5 | +review bot, an onboarding assistant, or an internal dev portal that needs the *why* behind a chunk of |
| 6 | +code - not just the code. |
| 7 | + |
| 8 | +This page covers that model: a containerized `whygraph-mcp` endpoint a third-party app drives over |
| 9 | +MCP, reading the same on-disk data your scan produces. |
| 10 | + |
| 11 | +## The shape of it |
| 12 | + |
| 13 | +A consuming app launches the WhyGraph image, mounts the target repo at `/workspace`, and speaks MCP |
| 14 | +over stdio. The scan **writes** the databases; the MCP server **reads** them. One repo on disk is the |
| 15 | +single source of truth. |
| 16 | + |
| 17 | +```mermaid |
| 18 | +flowchart LR |
| 19 | + app["Consuming app<br/>(bot · portal · assistant)"] |
| 20 | + mcp["whygraph-mcp<br/>(container)"] |
| 21 | + repo[("/workspace mount<br/>.whygraph + .codegraph")] |
| 22 | +
|
| 23 | + app -- "MCP over stdio" --> mcp |
| 24 | + mcp -- "reads cached evidence + rationale" --> repo |
| 25 | + scan["whygraph scan"] -- "writes" --> repo |
| 26 | +``` |
| 27 | + |
| 28 | +The consuming app gets the full read surface over MCP: |
| 29 | + |
| 30 | +- **Evidence** - `whygraph_evidence_for` and `whygraph_area_history` for the commits, PRs, and issues |
| 31 | + behind a path or symbol. |
| 32 | +- **Rationale** - `whygraph_rationale_brief` for a structured why-this-exists card. |
| 33 | +- **Resources** - `whygraph://commit/{sha}`, `whygraph://pr/{number}`, `whygraph://issue/{number}`, |
| 34 | + and `whygraph://repo/overview`. |
| 35 | + |
| 36 | +See the [MCP surface reference](../reference/mcp.md) for exact signatures. |
| 37 | + |
| 38 | +## Scan first |
| 39 | + |
| 40 | +The server reads cached data - it doesn't crawl on demand. So the target repo must be scanned before |
| 41 | +an app connects, or the tools have nothing to return. |
| 42 | + |
| 43 | +```bash |
| 44 | +cd /path/to/target-repo |
| 45 | +whygraph scan |
| 46 | +``` |
| 47 | + |
| 48 | +!!! warning "An unscanned repo returns nothing" |
| 49 | + `whygraph_rationale_brief` raises an error when a target maps to no scanned commit, and the |
| 50 | + evidence tools come back empty. Run `whygraph scan` (and keep it fresh with |
| 51 | + [git hooks](../guide/scanning.md#keep-it-fresh)) before pointing an app at the server. |
| 52 | + |
| 53 | +## Launch the endpoint |
| 54 | + |
| 55 | +The MCP server runs from the same image as everything else. Mount the target repo and run |
| 56 | +`whygraph-mcp`: |
| 57 | + |
| 58 | +```bash |
| 59 | +docker run --rm -i \ |
| 60 | + -v "/path/to/target-repo:/workspace" -w /workspace \ |
| 61 | + ghcr.io/mtrdesign/whygraph whygraph-mcp |
| 62 | +``` |
| 63 | + |
| 64 | +The `-i` flag keeps stdin open for the MCP stdio transport. Your app spawns this command and talks |
| 65 | +JSON-RPC to it, exactly as an editor would. The [`install.sh` shim](docker.md) wraps the same call as |
| 66 | +a bare `whygraph-mcp` on `PATH`. |
| 67 | + |
| 68 | +## Credentials |
| 69 | + |
| 70 | +What the app needs depends on what it asks for: |
| 71 | + |
| 72 | +- **Reading cached evidence and rationale needs no credentials.** It's all in the mounted databases. |
| 73 | +- **Generating a *new* rationale card needs an LLM key.** `whygraph_rationale_brief` calls the |
| 74 | + configured provider on a cache miss. Supply the key through the environment |
| 75 | + (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `DEEPSEEK_API_KEY`) or the repo's `whygraph.toml` |
| 76 | + `[llm.*]` table. |
| 77 | + |
| 78 | +!!! info "Tokens never live in the image" |
| 79 | + Pass credentials at run time via env or the gitignored `whygraph.toml` - never bake them into a |
| 80 | + built image. This matches WhyGraph's own invariant for the Docker shim. |
| 81 | + |
| 82 | +## Current scope |
| 83 | + |
| 84 | +Today the server speaks MCP over **stdio, one session per process**. There's no long-running HTTP |
| 85 | +endpoint yet - each connection is its own `docker run`. A persistent server mode with an HTTP MCP |
| 86 | +transport is on the [roadmap](../roadmap.md), not built. |
| 87 | + |
| 88 | +For now, model your integration as "spawn a session, run the tools you need, let it exit" - the same |
| 89 | +lifecycle an editor uses, driven by your app instead. |
0 commit comments