Saving Tokens Is Only Half of What Synaptic Does

Synaptic gives AI coding agents a persistent code graph, reducing wasted tokens while improving impact analysis, test selection, refactoring, and review.

Colin Vaughn10 min read
AI Coding Agents Need Better Context, Not More Context.” The left side shows a traditional workflow of text search, opening files, following imports, finding callers and tests, with problems such as high token use and missed dependencies. The right side shows Synaptic converting a multilingual codebase into a knowledge

Why is a persistent code graph useful beyond token savings?

A persistent, source-linked graph helps an agent find the right code before it opens files. Reusing that graph can reduce repeated context, but it also supports change-impact analysis, test selection, refactoring, and review with evidence that remains available after a prompt ends.

When I talk about Synaptic, I usually start with the token savings. It is the clearest number, and it solves a real problem: coding agents spend a lot of their context rediscovering code they may have inspected only a few prompts earlier. They search for a term, open several files, follow imports, and keep expanding the prompt until they feel confident enough to make a change.

Synaptic takes a different approach. It converts the codebase into a persistent, source-linked graph that an agent can query before it starts opening files. Functions, classes, types, resources, database objects, events, and other parts of the system become nodes, while calls, imports, references, inheritance, database access, and runtime handoffs become relationships.

The agent still reads the source code. Synaptic simply helps it find the right source before it fills the context window with entire files.

The measurable benefit: less wasted context

I benchmarked this against Synaptic’s own Rust codebase, which contained 199 files, 56,408 lines, and more than 510,000 tokens at the time of the test. I asked six structural questions covering areas such as HTTP request handling, session cleanup, graph merging, extraction, and pull-request ranking.

The graph responses used 11,702 tokens in total. Reading the complete source files containing the same results would have required 365,254 tokens. Depending on the question, Synaptic used between 27 and 38 times fewer tokens, with an overall reduction of roughly 31 times. (GitHub)

That result does not mean every repository will see exactly the same reduction. The benchmark was run on Synaptic’s own source and compared a bounded graph response with the full files containing the returned symbols. What it demonstrates is that an agent does not need to load every potentially relevant file just to discover how the pieces connect.

The full graph also is not placed inside the model’s prompt. It remains outside the context window as an index, and the agent receives only the ranked section needed for the current question.

But token savings are only the easiest part of Synaptic to measure. They are not the main reason I built it.

Thirty tools, not one search box

The larger problem is that coding agents can write code before they properly understand the system they are changing. Saving tokens does not solve that by itself. The agent also needs ways to inspect architecture, trace dependencies, estimate risk, choose tests, review a branch, and verify that a refactor did not damage the structure of the project.

Synaptic currently exposes 30 read-only MCP tools by default. They all work from the same graph, but they answer different engineering questions. (GitHub)

  • Codebase orientation and navigation: query_graph, get_node, get_source, get_neighbors, get_community, god_nodes, graph_stats, list_repos, repo_stats, shortest_path, and describe_node help the agent locate the relevant subsystem, inspect individual symbols, follow paths, understand architectural communities, and identify highly connected areas of the codebase.

  • Dependencies and search: affected, find_callers, find_callees, find_references, structural_search, search_text, and dynamic_hazards help the agent distinguish direct calls from broader references, calculate reverse impact, search the graph with SYNQL, find text inside source files, and identify behavior static analysis may not be able to resolve completely.

  • Change forecasting and verification: working_changes_impact, predict_impact, affected_tests, predict_edit, time_travel_diff, plan_rename, and readiness_audit show what a branch touches, what a proposed edit may break, which tests are relevant, how the graph changed between revisions, and where a refactor or port may need additional review.

  • Pull-request review: list_prs, get_pr_impact, and triage_prs combine pull-request status with architectural blast radius, giving an agent more context than the size of the diff alone.

  • Database review: audit_sql and advise_sql inspect existing or proposed SQL for performance and security risks while cross-referencing the database objects already represented in the graph.

This is what I mean when I say Synaptic can help an AI produce better code. It does not change the model or make generated code automatically correct. It gives the model a better engineering process and more opportunities to catch a bad assumption before the change is merged.

Reviewing architecture with SYNQL

SYNQL is one of the clearest examples of the difference between Synaptic and a basic code map. It is a Cypher-inspired query language exposed through the structural_search tool.

Normal code search finds matching text. SYNQL searches the structure of the codebase. It can filter symbols by kind, visibility, source location, lines of code, fan-in, fan-out, degree, community, signature, and relationships with other symbols. It also supports built-in architectural patterns for singletons, factories, observers, service locators, and god classes. (GitHub)

An agent could use SYNQL to find public classes with unusually high fan-out, locate every implementation of an interface, identify large methods in highly connected parts of the system, or trace a multi-hop relationship between two components. It can also request a structural outline of every symbol defined in a file without reading the full file.

That creates a more useful form of automated code review. Instead of opening a handful of files and asking the model to vaguely look for architectural problems, the agent can run a repeatable query against measurable properties of the graph.

search_text complements SYNQL rather than trying to replace it. Error messages, configuration values, TODO comments, string literals, and magic numbers are still text-shaped problems. Synaptic can find those values in the source and connect each result back to the enclosing graph symbol, giving the agent a direct path from a text match to callers, impact, source, and tests.

Understanding impact beyond direct callers

One of the most common ways an automated change goes wrong is that the agent understands the function being edited but not everything that depends on it.

find_callers answers who calls or uses a symbol, while find_callees shows what that symbol calls. Both can include the exact source lines where those relationships occur.

find_references deliberately answers a broader question. A class, interface, enum, constant, or shared type may be imported, implemented, inherited from, or used in a signature without appearing as a direct function call. The references tool includes those relationships, along with supported cross-language and cross-repository uses. (GitHub)

The affected tool then walks those relationships backward to calculate the reverse-impact surface. For a class or interface, it can include the dependencies attached to its members instead of incorrectly treating the bare type as unused. This matters because callers usually attach to methods, not to the class node itself.

Synaptic also avoids treating “zero static callers” as proof that code is safe to change. Reflection, computed names, dynamic imports, dispatch tables, event systems, and runtime-generated behavior can hide real dependencies from static analysis. dynamic_hazards surfaces those locations, and other tools can attach a caveat when a symbol appears unused inside an area containing unresolved dynamic behavior. (GitHub)

That is a small but important difference. An incomplete answer that clearly states its uncertainty is much safer than a confident answer that quietly ignores what it cannot resolve.

Following a change across the real system

Modern applications rarely stay inside one file, language, or repository. A TypeScript frontend may call a Java service, which publishes an event consumed by Python. A Rust library may be reached through native bindings. Several repositories may depend on the same API, queue, database table, or message format.

Traditional code navigation often stops when execution leaves the current language or repository. Synaptic can represent supported handoffs across HTTP, gRPC, WebSockets, queues, events, process IPC, native bindings, SQL, and federated repositories. Reverse-impact and path queries can then continue across those relationships instead of ending at the nearest import boundary. (Synaptic)

Every relationship also carries provenance. Extracted relationships can be distinguished from inferred or ambiguous ones, allowing the agent and the developer to see which parts of an answer come directly from parser evidence and which parts rely on a lower-confidence bridge.

This is especially useful when a change appears small locally. Renaming a field, changing a route, modifying a database object, or adjusting a message format may affect consumers that do not exist anywhere in the current repository.

Reviewing a change before it becomes a regression

Synaptic’s forecasting tools are designed to make the agent think about consequences before it writes the patch.

predict_edit can model deleting a symbol, changing its signature, or narrowing its visibility. It separates relationships that are likely to break from lower-confidence cases that should be reviewed manually.

predict_impact works from selected files or the current working-tree diff. It identifies the changed graph nodes, public APIs at risk, transitive dependents, affected tests, an overall risk level, and a verification checklist. affected_tests provides a focused list of tests that reach the changed code, while working_changes_impact shows which nodes and architectural communities the current branch touches before a pull request even exists. (GitHub)

The pull-request tools apply the same idea to team review. A ten-line change inside a highly connected authentication component may be riskier than a much larger change inside an isolated internal utility. get_pr_impact and triage_prs help an agent prioritize based on architectural impact instead of relying only on line count or file count.

For refactors, plan_rename creates a confidence-scored plan without modifying the source. Higher-confidence edit locations are separated from references that deserve manual review. After the edits are applied, the graph can be rebuilt and verified through the CLI to check that references were preserved and no unexpected cycles appeared.

time_travel_diff takes that idea further by comparing the graph between Git revisions. It can report new and removed dependencies, removed APIs, architectural drift, new cycles, and change hotspots. A normal diff shows which lines changed; a graph diff helps explain what changed in the architecture. (GitHub)

Code quality also includes SQL and project readiness

Not every serious problem appears in a call graph. Database performance, permissions, unfinished implementations, generated-resource conflicts, and project configuration can all turn an otherwise reasonable code change into a production issue.

audit_sql reviews the SQL-aware graph for risks such as missing indexes, row-level-security gaps, overly broad grants, likely SQL injection, SELECT *, N+1 patterns, missing primary keys, and queries that prevent effective index use. advise_sql performs similar checks on a proposed query before it is added, while also checking the tables, indexes, and security policies already represented in the graph. (GitHub)

readiness_audit looks for a different class of problem: placeholders, stubs, framework sentinel returns, generated-resource conflicts, and project metadata that may block a port or release. It does not pretend to replace a real build, but it gives the agent another focused review step before declaring the work complete.

Read-only by default

All 30 default MCP tools are read-only. They can inspect the graph, source, Git state, pull requests, tests, and project structure, but they do not edit the repository.

There is an optional 31st tool called speculate, which is only exposed when execution is deliberately enabled. It applies a proposed change inside a disposable Git worktree, runs the tests considered at risk, performs a build or type check, and reports the results without modifying the developer’s actual working tree. (GitHub)

I think that separation is important. Understanding, reviewing, forecasting, and planning should be safe by default. Running project commands should be an explicit decision.

What better AI-generated code means

When I say Synaptic can help an AI produce better code, I am not claiming that a graph guarantees a correct patch. I mean the agent can understand more of the system before it edits, inspect more than direct callers, review structural patterns with SYNQL, identify unresolved dynamic behavior, estimate the blast radius, choose relevant tests, inspect pull-request risk, review SQL, and verify the structure after a refactor.

The token savings make that process more efficient. The other tools are what make the process more thorough.

An AI coding agent should not have to rediscover the architecture of a system every time it receives a task. That architecture should remain available as a persistent, queryable layer, with every answer leading back to the source and evidence behind it.

That is the goal of Synaptic: less irrelevant context, a clearer understanding of the system, and better evidence before code is changed.

Learn more at synapticgraph.com or view the source and documentation in the ColinVaughn/Synaptic repository on GitHub.