Skip to content

Add a shell shim and agent instructions for cheaper graph queries - #4

Open
IT-Cru wants to merge 2 commits into
mainfrom
agent-code-mode
Open

Add a shell shim and agent instructions for cheaper graph queries#4
IT-Cru wants to merge 2 commits into
mainfrom
agent-code-mode

Conversation

@IT-Cru

@IT-Cru IT-Cru commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Why

Calling an MCP tool puts its entire response into the agent's context. Graph
results carry per-node fields nobody reads — fingerprints, metric vectors, a dozen
complexity counters:

{"name":"atomic_write","in_degree":2,"out_degree":0,"complexity":0,"cognitive":0,
 "fp":"0488e8e4039419ae027e7e6c02c39db2023349df014da83305cd2b540048e5bc…",
 "sp":"0,0,0,0,0,0,8,39,0,0,0,0,8,4,0,0,0,0,0,0,1,0,4,8,4"}

An agent that wants three names pays for all of it. A multi-step question — schema,
then search, then trace, then snippet — pays again at every hop, because each
intermediate result has to pass through context to reach the next call.

Approach

Let the agent filter in a shell and keep only the answer. This needs no new runtime:
the agent containers already have bash, curl and jq, and CBM already exposes
query_graph for projected multi-hop queries. The only missing piece was a way to
reach the graph from a shell.

.ddev/codebase-memory/cbm — agent containers mount the project but have no
ddev binary and no MCP client. This prints only the tool result, so it pipes:

cbm search_graph --label Function \
  | jq '[.results[] | {name, file_path, out_degree}] | sort_by(-.out_degree) | .[:5]'

Measured on a three-function project: 2123 bytes of tool result down to 182 (~91%).
The saving is in per-node fields, so it grows with the result set rather than staying
at 91%.

It maps --name-patternname_pattern, fills in --project, reuses one MCP
session across calls (verified: 4 calls → 1 session, not four server processes), and
re-initializes transparently if the container restarted (verified by restarting
mid-test).

.ddev/codebase-memory/AGENT-INSTRUCTIONS.md — which tool answers which question,
call get_graph_schema first, prefer one query_graph over a chain, always pass
limit. Meant to be referenced from your own CLAUDE.md
(@.ddev/codebase-memory/AGENT-INSTRUCTIONS.md) or opencode.json instructions
array, not installed over the top — the add-on doesn't own those files.

Bug fixed: ddev cbm get_graph_schema never worked

get_graph_schema requires --project, but it was excluded from auto-injection in
both the new shim and the host ddev cbm command. So the one command the README —
and now the agent instructions — tell you to run first was failing.

An earlier test appeared to cover it, but a jq fallback (.node_labels // "n/a")
was masking the error object, so it reported success on a failure. Now asserted
through both paths.

On the project name

CBM derives the graph project name from the repository path, which inside the
container is always the mount point — so --project defaults to var-www-html
whatever your DDEV project is called. Verified across five differently-named
projects, including weird-name-99.

If it's ever wrong — a custom --name, or indexing a subdirectory — the server
answers with the names it does have:

{"error":"project not found or not indexed","available_projects":["var-www-html"]}

CBM_PROJECT overrides the default. Both documented.

Deliberately not done

Stripping heavy fields inside the bridge. It would cut tokens too, but it means
returning something other than what the server said.

Tests

New bats case (6 total): the shim lists tools, resolves --project, survives regex
arguments, pipes through jq with "fp" absent from the output, fails loudly on
a bad tool name, and serves repeated calls from one session. Plus get_graph_schema
regressions on both the shim and the host command.

Also corrects the install message, which still claimed the graph UI needs an open
agent session.

IT-Cru and others added 2 commits August 5, 2026 22:49
Calling an MCP tool puts its whole response into the agent's context, and graph
results carry per-node fields nobody reads - fingerprints, metric vectors, a dozen
complexity counters. An agent that wants three names pays for all of it, and a
multi-step question (schema, then search, then trace, then snippet) pays again at
every hop, because each intermediate result passes through context to reach the next
call.

That is the argument in Cloudflare's "code mode" post. Their hard part is the
sandbox; here there is nothing to build - the agent containers already have bash,
curl and jq, and CBM already exposes query_graph for projected multi-hop queries.

Adds .ddev/codebase-memory/cbm. The agent containers mount the project but have no
ddev binary and no MCP client, so this is the missing piece. It prints only the tool
result, so it pipes:

  cbm search_graph --label Function \
    | jq '[.results[] | {name, file_path, out_degree}] | sort_by(-.out_degree) | .[:5]'

Measured on a three-function project: 2123 bytes of tool result down to 182 (~91%).
The saving is in per-node fields, so it grows with the result set rather than staying
at 91%.

It maps --name-pattern to name_pattern, fills in --project, reuses one MCP session
across calls so a pipeline does not start a server process per invocation, and
re-initializes by itself if the container restarted.

Adds .ddev/codebase-memory/AGENT-INSTRUCTIONS.md: which tool answers which question,
call get_graph_schema first, prefer one query_graph over a chain, always pass limit.
Meant to be referenced from your own CLAUDE.md or opencode.json rather than installed
over the top - the add-on does not own those files.

Fixes get_graph_schema, which requires --project but was excluded from auto-injection
in both this shim and the host `ddev cbm` command, so `ddev cbm get_graph_schema` had
never worked - while both the README and the new instructions tell you to run it
first. An earlier test appeared to cover it but a jq fallback was masking the error
object, so it is now asserted through both paths.

On the project name: CBM derives it from the repository path, which inside the
container is always the mount point, so --project defaults to var-www-html whatever
the DDEV project is called (verified across five differently-named projects). If it
is ever wrong - a custom --name, or indexing a subdirectory - the server replies with
the names it does have, and CBM_PROJECT overrides the default.

Deliberately not done: stripping heavy fields inside the bridge would cut tokens too,
but it means returning something other than what the server said.

Also corrects the install message, which still claimed the graph UI needs an open
agent session.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The token cost of unfiltered tool responses is the reason for the shim, and it is
measurable on its own. Where the idea came from is not something a reader of the
README needs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant