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
Two tool-behavior improvements, both kernel-verified.
1. ctags export recovery — closes the last eval known-fail.
GNU Global's C parser derails on sparse annotations
(__acquires(lock) on a forward declaration) and silently drops
every definition below the derail point; find_definition
("mutex_lock") returned 7 shadows/variants but never the real
kernel/locking/mutex.c:314. EXPORT_SYMBOL*(sym) always sits in the
defining .c and IS indexed, so: an export site whose file has no
definition record is proof of a parser miss — confirm with a
(cached) Universal Ctags scan and prepend the definition, flagged
resolved_via "ctags:EXPORT_SYMBOL".
- macros.export_sites() extracts (path, line, variant) per export.
- enrich.definition_tag() picks definition-shaped ctags tags
(prototypes/externvars rejected).
- server._export_recovery() + shared _resolve_definitions(): wired
into find_definition, symbol_info (free — refs already fetched),
get_symbol_body, and find_callees, so the recovered definition is
also readable and analyzable. -sx retry covers fully-missed
symbols whose occurrences land in GSYMS. Disabled with the
existing enrichment knob (--no-enrich / GTAGS_MCP_ENRICH /
enrich=false); best-effort, never fails a query.
- def-mutex_lock (known-fail since v1.0.0) now PASSES and asserts
top_path + resolved_via: eval is 65/65 = 100% recall,
15/15 = 100% precision@1 on the mid-2026 master snapshot.
2. Per-file `global -fx` definition cache for the caller graph.
reachability/blast_radius run _callers_of once per BFS node and
kept re-running identical `global -fx <file>` subprocesses for hot
files. New LRU (capacity 4096) keyed by (root, index generation,
path) — generation bumps on every build/refresh path, so entries
die with the index state they were read from; negative results
cached; thread-safe. Measured: warm reachability 552ms -> 46ms,
warm find_callers on a 200-caller symbol 61ms -> 3ms.
Tests 293 -> 304: export_gap_project fixture reproduces the parser
derail end-to-end (skips if upstream fixes it), recovery via
find_definition/symbol_info/get_symbol_body/find_callees, opt-out
inertness, -fx run-counting (one run per file per generation),
cache invalidation via update_index, generation-bump coverage, plus
pure export_sites/definition_tag units.
Stability exercise: 28-call matrix (new def-recovered-mutex_lock
case), 28/28 sane, zero anomalies; docs/capability.md operational
table and known-limitations rewritten accordingly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: README.md
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,7 +25,7 @@ Every AI coding agent — Claude Code, Cursor, Codex, you name it — answers *"
25
25
26
26
-**~100× faster per query** — milliseconds instead of seconds, at any codebase size
27
27
-**Radically less noise** — the definition, not 7,873 lines of matches
28
-
-**Speaks kernel** — `#ifdef` guard stacks with `.config` filtering, and macro-generated symbols (`sys_read` → its `SYSCALL_DEFINE3` site) that no other tagging tool resolves
28
+
-**Speaks kernel** — `#ifdef` guard stacks with `.config` filtering, macro-generated symbols (`sys_read` → its `SYSCALL_DEFINE3` site) that no other tagging tool resolves, and definitions the parser misses recovered from their `EXPORT_SYMBOL` site via ctags
29
29
-**Zero index management** — first query builds the index, every query auto-refreshes it
30
30
-**Correctness measured in CI** — a 65-case golden eval covering all 11 tools against a pinned kernel: 100% recall, 100% precision@1 ([docs/capability.md](docs/capability.md))
31
31
-**Works everywhere MCP does** — Claude Code, Claude Desktop, Cursor, any MCP client
@@ -42,6 +42,7 @@ Measured on a full Linux kernel checkout — **65,163 C/C++ files, 37.1 million
42
42
| Show me `tcp_v4_rcv`'s implementation |*read a 3,500-line file*|**`get_symbol_body`**|**exactly the 271-line function**|
43
43
| Who calls `ext4_mark_inode_dirty`? | 245 raw match lines |**`find_callers`**|**62 deduped caller functions, with counts**|
44
44
| Where is `sys_read`*really* defined? |*no answer — the name is macro-generated*|**0.03 s**|`fs/read_write.c SYSCALL_DEFINE3(read, ...)`, flagged `resolved_via`|
45
+
| Where is `mutex_lock` defined? | 24,774 noisy match lines |**0.2 s**|`kernel/locking/mutex.c:314` — recovered via `EXPORT_SYMBOL` + ctags after gtags' parser derails on it |
45
46
| Does `ksys_read` ever reach `rw_verify_area`? |*N rounds of grep + reading*|**0.6 s**| the shortest call chain, with every call site's file:line|
46
47
| What does my uncommitted diff impact? |*not answerable*|**0.1 s**|`blast_radius`: changed functions + callers, ranked by distance |
47
48
@@ -53,7 +54,7 @@ One-time index build: **66 s** for the whole kernel. Incremental refresh after e
53
54
54
55
The speed is nice. The real win is **precision**: an agent that gets 5 exact lines instead of 7,873 noisy ones keeps its context window for actual reasoning.
55
56
56
-
And the answers are *measured*, not assumed: CI runs a [65-case golden eval](evals/golden.jsonl) against pinned kernel v6.16 on every push — currently **100% recall, 100% precision@1** across definitions, macro resolution, references, callers, callees, definition bodies, `#ifdef` guards, and reachability, covering all 11 tools. The full methodology, numbers, and honest limitations live in [docs/capability.md](docs/capability.md).
57
+
And the answers are *measured*, not assumed: CI runs a [65-case golden eval](evals/golden.jsonl) against pinned kernel v6.16 on every push — currently **100% recall, 100% precision@1** across definitions, macro resolution, export recovery, references, callers, callees, definition bodies, `#ifdef` guards, and reachability, covering all 11 tools. The full methodology, numbers, and honest limitations live in [docs/capability.md](docs/capability.md).
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.3.1"
3
+
version = "1.4.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