code-graph · mcp · context-engineering
Why your AI assistant should query your architecture, not your files
File dumps and embeddings break down on large C# codebases. A semantic code graph gives an LLM the exact dependency paths a question needs — nothing more.
On this page
Every AI coding assistant faces the same bottleneck: it can only reason about what fits in its context window. On a small project that is no problem — paste the repo, ask the question. On a real C# monorepo with thousands of types, it becomes the problem.
The two default strategies, and why they fail
Strategy one: dump the files
The brute-force approach hands the model whole files — the one you are editing, plus whatever looks related. It fails in both directions at once:
- Too much: most of every file is irrelevant to the question. You pay for tokens that carry no signal.
- Too little: the behavior you ask about usually lives between files — an interface here, three implementations there, a decorator registered in a DI container nobody remembers.
Strategy two: embeddings
Embeddings retrieve text that resembles the question. But resemblance is not relevance. The method that breaks when you change an interface does not share vocabulary with that interface. It shares a compile-time relationship with it. No embedding captures that reliably, and the index goes stale the moment the code changes.
What the compiler already knows
Here is the thing: a complete, precise graph of your codebase already exists. The C# compiler builds it on every compilation — every symbol, every type, every call, every dependency. Then it throws that graph away the moment it has emitted IL.
GraphSlice builds that graph and keeps it. A purpose-built tree walker reads
your solution's source directly. It resolves symbols, types, and calls
across projects, then writes the result as a semantic code graph: nodes
for solutions, projects, types, and methods; edges for the relationships
between them — calls edges (CALLS), inheritance, references, and package
dependencies.
Context slices, not searches
A graph that cannot fit in a context window is no better than a repo that cannot fit in a context window. The unit of delivery matters. GraphSlice serves context slices — the minimal subgraph that answers one question:
> what breaks if I change IPaymentProcessor?
IPaymentProcessor (interface, Billing.Core)
├── implemented by StripeProcessor (Billing.Stripe)
├── implemented by InvoiceProcessor (Billing.Invoicing)
├── injected into CheckoutService..ctor (Web.Checkout)
└── mocked in PaymentProcessorTests (Billing.Tests)
That is the whole answer. Four dependency paths, a few hundred tokens — instead of forty files and a prayer.
Why MCP is the right delivery channel
GraphSlice serves context slices over the Model Context Protocol (MCP), so any MCP-compatible agent can request them as tools:
- The agent asks a structural question ("who calls this?", "trace this dependency") instead of a text query.
- The graph does the reasoning about structure, so the agent can spend its reasoning budget on intent.
- Your repository is never uploaded or indexed by a third party. The graph runs where your code runs.
The payoff
Correct context, not just nearby context. Smaller windows, flatter costs as the repo grows, and answers grounded in how the software actually fits together. Your AI assistant stops being a very confident text search. It becomes an engineer with the graph in hand.