You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Drop call_hierarchy, halve the tool-schema context cost (v1.3.0)
Second-pass surface optimization after v1.2.0, same evidence base
(130 agent A/B transcripts):
- call_hierarchy removed (11 tools now): zero calls even on the multihop
eval questions — agents iterate find_callers, and reachability covers
the directed case. It was also the most expensive tool at runtime.
- Docstrings tightened: shared conventions (project_root resolution,
limit/offset pagination, JSON/text format, envelope shape) now live
once in the server-level instructions string instead of being repeated
in every tool description. Per-session tool payload drops from
~4,700 to ~2,900 tokens. No parameter or schema changes.
244 tests pass; golden kernel eval unchanged (def-mutex_lock known-fail
only, identical on HEAD).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|`symbol_info`|**A one-shot overview card** — definitions (with kind, signature, scope, and `#ifdef` guard), reference count, hottest files, `EXPORT_SYMBOL*` status, and which tool to use next. Multiply-defined symbols are explained as "N definitions under M distinct guards"; macro-generated ones resolve with a `resolved_via` flag. The best first query for any unfamiliar symbol. |
203
203
|`get_symbol_body`|**Just the source of a definition.** The 271-line `tcp_v4_rcv` function — not the 3,500-line file it lives in. Handles functions, structs, and multi-line macros. |
204
-
|`find_callers`|**The call graph, deduplicated.** Every reference mapped to its enclosing function with call counts: 245 raw lines for `ext4_mark_inode_dirty` collapse to 62 callers. |
205
-
|`call_hierarchy`|**Multi-level impact analysis.** Who calls X, who calls *those*, up to 5 levels — a cycle-safe, capped tree instead of N rounds of grep. |
204
+
|`find_callers`|**The call graph, deduplicated.** Every reference mapped to its enclosing function with call counts: 245 raw lines for `ext4_mark_inode_dirty` collapse to 62 callers. Iterate it to walk the caller graph as deep as you need. |
206
205
|`find_callees`|**The outgoing call graph.** What does this function call? Body-extracted call sites, each verified against the index, split into in-tree (with locations) and external. |
207
206
|`reachability`|**"Can this function end up in that one?"** — BFS over the caller graph returns the *shortest* call chain from A to B with the file:line of every call site (`ksys_read → vfs_read → rw_verify_area`), or an honest "no static path" that names the function-pointer caveat. One call instead of a dozen find_callers rounds. |
208
207
|`blast_radius`|**What does my diff impact?** Takes `git diff <ref>`, maps changed lines to their enclosing functions via the index, then walks callers outward — results ranked by distance (changed functions first, direct callers next). The pre-merge "what else must I re-check" answer, tied to real git state. |
209
208
|`summarize_references`|**A ranked per-file count.** The cheap first move for hot symbols — `kmalloc`'s 2,744 references become one screen of "where usage concentrates". |
210
209
211
-
A two-level `call_hierarchy` on the kernel's `ext4_mark_inode_dirty` — 87 compact lines instead of dozens of grep rounds:
@@ -258,7 +244,7 @@ Since v0.8.0 every tool returns a **machine-readable JSON envelope by default**
258
244
-**`resolved_via` says *how* a symbol was found** when it took macro-family resolution rather than a literal index match (`"macro:SYSCALL_DEFINE"`, `"fuzzy:vfs_read"`) — see [Macro-generated symbols](#macro-generated-symbols-resolve-too-sys_read--syscall_define3).
259
245
-`next_tools` tells the agent the highest-value follow-up call for what was (or wasn't) found.
260
246
-`total`/`offset`/`truncated` replace the text continuation footer; errors keep the envelope with an `error` field.
261
-
- Composite tools return tool-shaped `results` (e.g. `call_hierarchy` a nested caller tree, `find_callees``{in_tree, external}`, `symbol_info` an overview object, `reachability` a hop chain) inside the same envelope.
247
+
- Composite tools return tool-shaped `results` (e.g. `find_callees``{in_tree, external}`, `symbol_info` an overview object, `reachability` a hop chain) inside the same envelope.
262
248
263
249
### `#ifdef`-aware: know which definition your config actually compiles
264
250
@@ -336,7 +322,7 @@ Incremental refreshes recollect the list, so newly ignored files drop out of the
Now `find_definition("py_util")`, `get_symbol_body` (indentation-aware for Python), `find_callees`, `call_hierarchy` — all work across every language in the tree, in one index.
349
+
Now `find_definition("py_util")`, `get_symbol_body` (indentation-aware for Python), `find_callees`, `find_callers` — all work across every language in the tree, in one index.
364
350
365
351
Force a specific parser label with `--label`, `GTAGS_MCP_LABEL`, or `label` in `.gtags-mcp.toml` (e.g. `default` for native-only, `pygments` for plugin-everything).
366
352
@@ -380,7 +366,7 @@ flowchart LR
380
366
end
381
367
382
368
subgraph proc["mcp-gtags-server — spawned once per window, lives for the session"]
Copy file name to clipboardExpand all lines: pyproject.toml
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
[project]
2
2
name = "mcp-gtags-server"
3
-
version = "1.2.0"
3
+
version = "1.3.0"
4
4
description = "Indexed code navigation for AI coding agents — replace grep scans with GNU Global (gtags) lookups over MCP. ~100x faster and radically less noise on million-line C/C++ codebases."
0 commit comments