feat: MCP project config, multi-editor install, cache scaling#78
Merged
jamestexas merged 15 commits intomainfrom Mar 11, 2026
Merged
feat: MCP project config, multi-editor install, cache scaling#78jamestexas merged 15 commits intomainfrom
jamestexas merged 15 commits intomainfrom
Conversation
Add convention-based project configuration so mache can be installed as an MCP server once and automatically know what to serve per-project. - `mache init` auto-detects project type, generates .mache.json and .claude/mcp.json - `mache serve` (zero args) reads .mache.json from CWD - Bundled preset schemas (go, python, sql, cli, mcp, mcp-registry) via go:embed - Schema resolution: preset name, relative path, or absolute path - .claude/mcp.json merge preserves existing MCP server entries - Add api.SchemaVersion const for "v1"
- `mache init` now generates .claude/CLAUDE.md describing mache MCP tools, workflow, and schema preset β Claude Code reads this automatically - `mache init --global` installs mache MCP server to ~/.claude/mcp.json for user-wide availability across all Claude Code sessions - CLAUDE.md appends to existing content, skips if mache section exists
Registers mache as an MCP server with all detected editors: - Claude Code (via CLI: claude mcp add --scope user) - Cursor (~/.cursor/mcp.json) - Windsurf (~/.codeium/windsurf/mcp_config.json) - VS Code (platform-specific mcp.json) - Zed (~/.config/zed/settings.json, context_servers key) - Gemini CLI (~/.gemini/settings.json) Each editor has its own config format (mcpServers vs servers vs context_servers) and entry shape. Registration only writes if the editor's config directory exists (i.e. editor is installed). Existing config entries are preserved via JSON merge.
The FIFO content cache was hardcoded at 1024 entries, which becomes a bottleneck for large monorepos (100K+ constructs). Cache now scales to 25% of node count with floor=1024 and ceiling=16384. SQLiteGraph/WritableGraph keep their 2048 ceiling since they resolve content on-demand from SQLite (cache is just for hot files).
1. writeClaudeMCPConfig now uses map[string]any as root type to
preserve unknown top-level keys during JSON round-trip.
2. PresetNames() actually sorts the output (sort.Strings).
3. registerClaudeCodeCLI extracted into mockable var to prevent
real `claude mcp add` side effects in tests.
4. detectProjectType checks sentinel files (go.mod, pyproject.toml,
requirements.txt, setup.py, Cargo.toml) before extension counting,
so projects with code in subdirectories are detected correctly.
5. runServe logs a warning when Sources[1:] are silently ignored.
6. registerEditorMCP returns (ok, warning) β shared config files
(Zed, Gemini CLI) that fail JSON parse return a warning about
JSONC comments instead of silently skipping. SharedConfig flag
replaces name-based checks.
7. resolveSchema and resolveDataSource enforce path containment
for relative paths to prevent traversal from untrusted .mache.json.
Absolute paths bypass the check (explicit user intent).
8. init tests refactored to use execInit(w, cmd, initOpts{...})
instead of mutating package-level flag vars. Safe for t.Parallel().
β¦tie-breaking) 1. leyline defsMap: changed from map[string]string to map[string][]string to handle tokens defined by multiple constructs (e.g. Init in different packages) 2. deleteFileNodes: clean stale refs and defs maps when nodes are removed, preventing phantom callers/callees after live re-ingestion 3. detectProjectType: deterministic alphabetical tie-breaking when two languages have equal file counts
Add plugin/ directory for distribution as a Claude Code plugin: - .claude-plugin/plugin.json manifest - .mcp.json auto-starts mache serve as MCP server - agents/mache-explorer.md (MCP-tools-first exploration agent) - skills/mache-explore/SKILL.md (FUSE mount fallback) Add hybrid auto-detect to mache serve (no .mache.json required): - detectProjectLanguages() walks repo to find ALL languages - Languages with presets (go, python, sql) use embedded schemas - Remaining languages (ts, js, tf, hcl, yaml, rs) get FCA inference - Single-language projects skip namespace wrapping - Multi-language produces unified topology with language namespaces This enables the plugin to auto-configure for any codebase: Go-only projects use the hand-tuned preset, monorepos get hybrid preset+inference, and .mache.json remains the explicit override.
Address agent feedback from MCP testing: - find_definition: exposes defs map (symbol β construct dir) as MCP tool with exact match, case-insensitive fallback, and fuzzy suggestions - get_overview: aggregate first-contact orientation tool returning top-level dirs, node counts, ref/def token stats - get_communities summary mode: new summary=true param returns compact output (community sizes + top 5 members) instead of full member lists that blew up at 103K chars on real codebases Adds DefsMap() to both MemoryStore and SQLiteGraph, gated behind defsMapProvider interface (mirrors existing refsMapProvider pattern). Updates mache-explorer agent docs with new tools and workflows.
The MCP server was failing health checks because schema auto-detection, tree-sitter parsing, FCA inference, and graph building all happened before the server started listening on stdio. Introduces lazyGraph wrapper that implements Graph + all provider interfaces (refsQuerier, refsMapProvider, defsMapProvider). The MCP server now starts immediately and responds to initialize/tools/list without delay. Graph construction is deferred to the first actual tool call via sync.Once.
β¦al dirs - list_directory: surface callers/ and callees/ virtual dirs on construct nodes - search: add optional 'type' param to filter by construct type in path - read_file: add 'paths' param for batch reads (JSON array), reduces round-trips - task install: build + codesign + copy to ~/.local/bin (fixes macOS SIGKILL)
- search: add 'role' param β 'definition' searches defs map, 'reference' (default) searches mache_refs. Lets agents distinguish where a symbol is declared vs where it's used. - find_callees: return structured hints when empty (unexported methods, wrong path type) instead of bare []. - mache-explorer agent: document batch read_file, role/type filters, find_definition as primary lookup tool.
β¦ummaries Dogfooding the MCP self-hosting revealed three issues: 1. search with role=definition returned duplicate results when the same construct path was indexed under multiple token variants (e.g. "GetCallers" and "graph.MemoryStore.GetCallers"). Dedup by path. 2. list_directory on large packages (e.g. go/graph/functions with 120+ entries) was dominated by Test*/Benchmark* noise. Add exclude_tests boolean param to filter them out. 3. get_communities summary top_members included "/source" suffix on every entry β pure noise for the consumer. Strip it. Also fixes TestFindCallees_EmptyWithoutExtractor which expected "[]" but the handler now returns structured JSON with hints.
- read_file now returns SourceOrigin (file, start_byte, end_byte) so consumers know exactly where each construct lives in the real filesystem - write_file wires the full splice pipeline: validate (tree-sitter) β format (gofumpt/hclwrite) β atomic splice β shift origins β update graph - writeBacker interface + lazyGraph delegation for write-back capability - JSON struct tags on SourceOrigin for clean serialization
jamestexas
added a commit
that referenced
this pull request
Mar 12, 2026
- README: update feature matrix, tool table, and landscape for 9 MCP tools (find_definition, get_overview, write_file added in PR #78) - ARCHITECTURE: update MCP server description and key file reference - PRIOR_ART: add codebase-memory-mcp (DeusData) detailed comparison β inspiration source for communities, overview, and definition tools
jamestexas
added a commit
that referenced
this pull request
Mar 12, 2026
- README: update feature matrix, tool table, and landscape for 9 MCP tools (find_definition, get_overview, write_file added in PR #78) - ARCHITECTURE: update MCP server description and key file reference - PRIOR_ART: add codebase-memory-mcp (DeusData) detailed comparison β inspiration source for communities, overview, and definition tools
jamestexas
added a commit
that referenced
this pull request
Mar 12, 2026
#80) * docs: update MCP tool count to 9, add codebase-memory-mcp to PRIOR_ART - README: update feature matrix, tool table, and landscape for 9 MCP tools (find_definition, get_overview, write_file added in PR #78) - ARCHITECTURE: update MCP server description and key file reference - PRIOR_ART: add codebase-memory-mcp (DeusData) detailed comparison β inspiration source for communities, overview, and definition tools * feat: consume leyline LSP tables for hover, diagnostics, and MCP tools Materializer (`materializeVirtuals`): - New `materializeLSP()` reads `_lsp_hover` and `_lsp` tables produced by `leyline lsp` and creates `{construct}/hover` and `{construct}/diagnostics` file nodes in the db. - `extractCallerDir` updated to recognize `hover` and `diagnostics` as leaf names. MCP server (`registerMCPTools`): - `get_type_info` tool: queries `_lsp_hover` for type signatures and documentation. Agents can ask "what type does X return?" without parsing source. - `get_diagnostics` tool: queries `_lsp` for LSP diagnostics (errors, warnings). Agents can ask "what's wrong?" without running a linter. Both tools gracefully degrade β if no LSP tables exist, they return a helpful error pointing to `leyline lsp`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: add TODO for schema-driven LSP file materialization Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
mache initβ generates.mache.json,.claude/mcp.json, and.claude/CLAUDE.mdfor per-project MCP setup. Auto-detects project type (Go, Python, SQL) from file extensions.mache init --globalβ registers mache as an MCP server with all detected editors: Claude Code (via CLI), Cursor, Windsurf, VS Code, Zed, Gemini CLI. Only writes config if the editor's directory exists. Preserves existing entries via JSON merge.mache servezero-arg mode β reads.mache.jsonfrom CWD, resolves schema via bundled presets (go:embed), serves without explicit args.api.SchemaVersionconst β replaces magic"v1"string.New files
cmd/config.gocmd/config_test.gocmd/init.gomache initcommand (project + global modes)cmd/init_test.gocmd/schemas.gogo:embedbundled preset schemas +PresetNames()cmd/schemas/*.jsonEditor registration details
claude mcp add --scope user~/.cursor/mcp.jsonmcpServers~/.codeium/windsurf/mcp_config.jsonmcpServersmcp.jsonservers"type":"stdio"~/.config/zed/settings.jsoncontext_servers"source":"custom"~/.gemini/settings.jsonmcpServersTest plan
task test)task lintβ 0 issues)task build)mache initin a Go project creates correct.mache.json+.claude/mcp.json+.claude/CLAUDE.mdmache init --globalregisters with installed editorsmache serve(zero args) works in a project with.mache.json