XRAY MCP
XRAY MCP is a code-navigation MCP server that lets an agent see a codebase's shape — structure, definitions, signatures and references — without reading whole files.
Map a repo with
explore_repo(root_path, max_depth, include_symbols, focus_dirs, max_symbols_per_file): a.gitignore-aware directory tree, optionally annotated with each file's signatures and doc lines, for progressive drill-down from structure to detail.Find definitions with
find_symbol(root_path, query): fuzzy, case/separator-insensitive search over functions, methods, classes and types, returning name, type, parent, path and line range.Read a file's API with
read_interface(root_path, file_path): every class/function/method signature plus one-line doc and line number, nested by scope, skipping function bodies and nested inner functions.Trace references with
what_breaks(exact_symbol): structural lookup of a symbol object returned byfind_symbol, returning code references with surrounding context while excluding comments and string literals (name-based, not type-aware).Work across languages — Python, JavaScript, TypeScript and Go — with zero per-language setup, caching parsed results per file (mtime/size) and parallelising large repos.
Run anywhere MCP is supported (Claude Code, Claude Desktop, Cursor, VS Code) via the
xray-mcpcommand.
Note: the schema's what_breaks takes a whole symbol object (exact_symbol) rather than the README's name/path/line arguments, and find_symbol in the schema exposes no limit parameter.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@XRAY MCPshow me all functions that call validate_user in the current project"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
XRAY
An MCP server that lets coding agents see a codebase's shape — layout, signatures, definitions, references — without reading whole files.
Why
Coding agents already have grep, glob and file reads. Where they burn context is:
Reading a 1,500-line file to learn three function signatures.
read_interfacereturns the file's API — every class, method, function and type with its signature, one-line doc and line number — so the agent reads only the lines it needs.Grepping a name and wading through comments, strings and partial matches.
find_symbolreturns definitions only, ranked, fuzzy.what_breaksreturns identifier references with comments and string literals excluded.
grep / rg | XRAY | LSP | |
Setup | none |
| a server per language |
Finds definitions only | ✗ | ✓ | ✓ |
Skips comments & strings | ✗ | ✓ | ✓ |
File API without the bodies | ✗ | ✓ | partial (document symbols) |
Type-aware references | ✗ | ✗ (name-based) | ✓ |
XRAY sits between the two: syntax-aware via tree-sitter, zero per-language setup, and honest about not resolving types.
Related MCP server: mcp-codebase-intelligence
Install
uv tool install git+https://github.com/srijanshukla18/xrayThen register the xray-mcp command with your client.
Claude Code
claude mcp add xray -s user -- xray-mcpClaude Desktop, Cursor, VS Code, others — add to the client's MCP config:
{ "mcpServers": { "xray": { "command": "xray-mcp" } } }To run without installing: uvx --from git+https://github.com/srijanshukla18/xray xray-mcp.
There is also install.sh, which installs uv if needed and then runs the command above.
Tools
All paths in results are absolute. root_path is the project directory.
explore_repo(root_path, max_depth=None, include_symbols=False, focus_dirs=None, max_symbols_per_file=5)
Directory tree honouring .gitignore (via git ls-files, or a .gitignore parser outside git). Directories cut off by max_depth show their file count. Output is capped at 1,000 lines.
explore_repo("/home/me/xray", max_depth=2)
/home/me/xray/
├── src/
│ └── xray/ (6 files)
├── tests/
│ ├── __init__.py
│ └── test_xray.py
├── pyproject.toml
└── README.mdfocus_dirs takes paths relative to the root; with include_symbols=True each file lists its signatures:
explore_repo("/home/me/xray", focus_dirs=["src/xray/core"], include_symbols=True, max_symbols_per_file=3)
/home/me/xray/
└── src/
└── xray/
└── core/
├── files.py
│ ├── def list_files(root: Path) -> List[str] # Return POSIX paths, relative to root, of every non-ignored…
│ ├── def _in_excluded_dir(rel: str) -> bool
│ ├── def _git_files(root: Path) # Tracked + untracked-but-not-ignored files, or None if root isn't in…
│ └── ... and 1 more
...find_symbol(root_path, query, limit=10)
Fuzzy search over definitions. Case and separators are ignored ("user service" finds UserService), a Class.method query matches methods by their class, and an exact spelling wins ties.
find_symbol("/home/me/xray", "symbols for")
[{
"name": "symbols_for", "type": "method", "parent": "SymbolIndex",
"path": "/home/me/xray/src/xray/core/symbols.py", "start_line": 357, "end_line": 385,
"signature": "def symbols_for(self, rel_paths: List[str], prune: bool = False) -> Dict[str, List[dict]]"
}]read_interface(root_path, file_path)
A file's API, nested by scope, with line numbers. Functions defined inside other functions are left out — they're not part of the interface. Paths outside root_path are refused.
read_interface("/home/me/xray", "src/xray/core/indexer.py")
src/xray/core/indexer.py (13 symbols; left column is the line number)
17 def _norm(text: str) -> str
21 class XRayIndexer
22 def __init__(self, root_path: str)
28 def _rel(self, path: str) -> str # Resolve a user-supplied path to a POSIX path relative to root, refusing…
105 def find_symbol(self, query: str, limit: int = 10) -> List[Dict[str, Any]]
134 def read_interface(self, file_path: str) -> str
...what_breaks(root_path, name, path=None, line=None, limit=50)
Every identifier spelled exactly name, excluding comments, string literals and the definitions themselves (which are listed separately). Pass the path and line of the definition you mean, and XRAY warns when other definitions share the name.
what_breaks("/home/me/xray", "list_files", path="src/xray/core/files.py", line=18, limit=2)
{
"symbol": "list_files",
"total_references": 7,
"files": 2,
"references": [
{"file": "/home/me/xray/src/xray/core/indexer.py", "line": 9,
"text": "from xray.core.files import list_files\nfrom xray.core.symbols import ..."},
{"file": "/home/me/xray/src/xray/core/indexer.py", "line": 50,
"text": ") -> str:\n files = list_files(self.root_path)\n if focus_dirs:"}
],
"definitions": [{"path": "/home/me/xray/src/xray/core/files.py", "line": 18}],
"note": "Name-based: every identifier spelled exactly like this, excluding comments and strings. ...",
"truncated": "showing first 2 of 7; raise limit to see more"
}It is name-based, not type-aware. what_breaks("save") finds every .save in the repo, not just the one on your class. Use it as a precise grep, not as a compiler.
Languages
Language | Extensions | Extracted |
Python |
| functions, async functions, classes, methods; first line of docstrings |
JavaScript |
| functions, generators, classes, methods, |
TypeScript |
| JavaScript's set plus interfaces, type aliases, enums, namespaces, abstract classes |
Go |
| functions, methods, structs, interfaces, other type declarations |
For non-Python languages the doc is the first line of the // or /** */ comment directly above the definition.
How it works
Files:
git ls-files --cached --others --exclude-standard, so nested.gitignores, negations and global excludes all behave exactly as in git. Dependency and build directories (node_modules,vendor,.venv,dist, …) are always skipped.Parsing: ast-grep's Python binding (tree-sitter grammars). One pass per file extracts every definition;
explore_repo,find_symbolandread_interfaceall read that same data.Cache:
~/.cache/xray/<hash-of-root>.sqlite(honoursXDG_CACHE_HOME), one row per file keyed on mtime and size. Only changed files are re-parsed; the cache survives server restarts.Large repos: batches of 200+ files are spread over up to 8 worker processes.
Measured on a 21,000-file Go/TS repo (Apple M-series, 10 cores): first find_symbol 8 s (builds the cache), later calls ~1 s, what_breaks ~2 s.
Development
git clone https://github.com/srijanshukla18/xray && cd xray
uv sync
uv run pytesttest_samples/ holds one file per language; the tests assert exact names and line numbers against them, and drive the tools through a real MCP client.
Uninstall
uv tool uninstall xray && rm -rf ~/.cache/xrayor run uninstall.sh.
Design notes
Approaches tried before settling on this one:
grep — can't tell a definition from a comment or a string.
Raw tree-sitter bindings — grammar and binding build problems across platforms.
LSP — precise, but asks users to install and run a language server per language.
Comby — unstable for this workload.
ast-grep CLI — correct, but its JSON repeats each matched node's full text; on a 20k-file repo that was ~1 GB of output per index. The in-process binding gives the same parser without the serialisation.
Available Tools
4 toolsexplore_repoA
🗺️ STEP 1: Map the codebase structure - start simple, then zoom in!
PROGRESSIVE DISCOVERY WORKFLOW:
First call: explore_repo("/path/to/project") - See directory structure only
Zoom in: explore_repo("/path/to/project", focus_dirs=["src"], include_symbols=True)
Go deeper: explore_repo("/path/to/project", max_depth=3, include_symbols=True)
INPUTS:
root_path: The ABSOLUTE path to the project (e.g., "/Users/john/myproject") NOT relative paths like "./myproject" or "~/myproject"
max_depth: How deep to traverse directories (None = unlimited, accepts int or string)
include_symbols: Show function/class signatures with docs (False = dirs only, accepts bool or string)
focus_dirs: List of top-level directories to focus on (e.g., ["src", "lib"])
max_symbols_per_file: Max symbols to show per file when include_symbols=True (accepts int or string)
EXAMPLE 1 - Initial exploration (directory only): explore_repo("/Users/john/project")
Returns:
/Users/john/project/
├── src/
├── tests/
├── docs/
└── README.md
EXAMPLE 2 - Zoom into src/ with symbols: explore_repo("/Users/john/project", focus_dirs=["src"], include_symbols=True)
Returns:
/Users/john/project/
└── src/
├── auth.py
│ ├── class AuthService: # Handles user authentication
│ ├── def authenticate(username, password): # Validates credentials
│ └── def logout(session_id): # Ends user session
└── models.py
├── class User(BaseModel): # User account model
└── ... and 3 more
EXAMPLE 3 - Limited depth exploration: explore_repo("/Users/john/project", max_depth=1, include_symbols=True)
Shows only top-level dirs and files with their symbols
💡 PRO TIP: Start with include_symbols=False to see structure, then set it to True for areas you want to examine in detail. This prevents information overload!
⚡ PERFORMANCE: Symbol extraction is cached per git commit - subsequent calls are instant!
WHAT TO DO NEXT:
If you found interesting directories, zoom in with focus_dirs
If you see relevant files, use find_symbol() to locate specific functions
| Name | Required | Description | Default |
|---|---|---|---|
| root_path | Yes | ||
| max_depth | No | ||
| include_symbols | No | ||
| focus_dirs | No | ||
| max_symbols_per_file | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure and excels. It explains the tool's progressive workflow, caching behavior ('Symbol extraction is cached per git commit - subsequent calls are instant!'), performance implications, and output format through detailed examples. It also clarifies path requirements ('ABSOLUTE path... NOT relative paths') and default behaviors.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (workflow, inputs, examples, tips, next steps) and uses emojis for visual organization. While slightly verbose, every sentence adds value: the workflow guides usage, examples illustrate outputs, tips optimize performance, and next steps connect to sibling tools. It could be more concise but remains highly effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is exceptionally complete for a tool with 5 parameters, 0% schema coverage, no annotations, but an output schema. It covers purpose, usage workflow, parameter details, behavioral traits (caching, performance), examples with output formats, and integration with sibling tools. The presence of an output schema means return values don't need explanation, and the description fills all other gaps comprehensively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Given 0% schema description coverage, the description fully compensates by providing comprehensive parameter semantics. Each of the 5 parameters is clearly explained with purpose, constraints, and examples: root_path (absolute vs. relative), max_depth (unlimited vs. limited), include_symbols (dirs only vs. with symbols), focus_dirs (top-level directories to filter), and max_symbols_per_file (limit when symbols shown). The examples demonstrate practical usage of all parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Map the codebase structure - start simple, then zoom in!' It specifies the verb ('explore', 'map') and resource ('repo', 'codebase structure'), and distinguishes it from sibling tools by focusing on structural discovery rather than symbol searching (find_symbol), interface reading (read_interface), or breakage analysis (what_breaks).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when and how to use this tool versus alternatives. It outlines a 'PROGRESSIVE DISCOVERY WORKFLOW' with three steps, advises starting with 'include_symbols=False' to avoid overload, and directs users to 'use find_symbol() to locate specific functions' after exploration. It clearly differentiates from sibling tools by positioning explore_repo as the entry point for structural mapping.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_symbolA
🔍 STEP 2: Find specific functions, classes, or methods in the codebase.
USE THIS AFTER explore_repo() when you need to locate a specific piece of code. Uses fuzzy matching - you don't need the exact name!
INPUTS:
root_path: Same ABSOLUTE path used in explore_repo
query: What you're looking for (fuzzy search works!) Examples: "auth", "user service", "validate", "parseJSON"
EXAMPLE INPUTS: find_symbol("/Users/john/awesome-project", "authenticate") find_symbol("/Users/john/awesome-project", "user model") # Fuzzy matches "UserModel"
EXAMPLE OUTPUT: [ { "name": "authenticate_user", "type": "function", "path": "/Users/john/awesome-project/src/auth.py", "start_line": 45, "end_line": 67 }, { "name": "AuthService", "type": "class", "path": "/Users/john/awesome-project/src/services.py", "start_line": 12, "end_line": 89 } ]
RETURNS: List of symbol objects (dictionaries). Save these objects - you'll pass them to what_breaks()! Empty list if no matches found.
WHAT TO DO NEXT: Pick a symbol from the results and pass THE ENTIRE SYMBOL OBJECT to what_breaks() to see where it's used in the codebase.
| Name | Required | Description | Default |
|---|---|---|---|
| root_path | Yes | ||
| query | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden and adds valuable behavioral context: it explains the fuzzy matching capability, returns a list of symbol objects or empty list if no matches, and specifies that results should be saved for use with what_breaks(). It doesn't cover permissions or rate limits, but provides clear operational details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections (description, usage, inputs, examples, returns, next steps) and front-loaded purpose. Slightly verbose due to detailed examples and instructions, but every sentence adds value for tool invocation and workflow integration.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 2 parameters with 0% schema coverage, no annotations, but an output schema exists, the description is complete: it covers purpose, usage, parameters with semantics, example inputs/outputs, return behavior, and integration with sibling tools (explore_repo and what_breaks), leaving no gaps for agent operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate fully. It does so by explaining both parameters: root_path ('Same ABSOLUTE path used in explore_repo') and query ('What you're looking for (fuzzy search works!)') with examples and formatting guidance, adding meaning beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Find specific functions, classes, or methods in the codebase' with 'fuzzy matching'. It distinguishes from siblings like explore_repo (which it follows) and what_breaks (which it precedes), making the verb+resource+scope specific and differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance is provided: 'USE THIS AFTER explore_repo() when you need to locate a specific piece of code.' It names the sibling tool explore_repo as a prerequisite and indicates when to use this tool (for fuzzy searching after exploration), with no misleading or missing exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_interfaceA
📖 READ INTERFACE: Get a high-level overview of a file without reading implementation.
Returns function signatures, class definitions, and docstrings. Perfect for understanding how to USE a module without reading the whole thing.
INPUTS:
root_path: The ABSOLUTE path to the project root
file_path: The path to the specific file you want to read (can be relative to root)
EXAMPLE: read_interface("/Users/john/project", "src/auth.py")
| Name | Required | Description | Default |
|---|---|---|---|
| root_path | Yes | ||
| file_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It describes what the tool returns (interface elements) and its non-destructive nature (implied by 'read'), but doesn't cover aspects like error handling, performance characteristics, or authentication needs. The description adds useful context about the tool's scope but lacks comprehensive behavioral details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (purpose, returns, usage context, inputs, example) and uses emojis for visual organization. While slightly longer than minimal, every sentence adds value. The information is front-loaded with the core purpose stated first.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (2 parameters, no annotations, but has output schema), the description provides good coverage. It explains the purpose, parameters, and includes an example. Since an output schema exists, it doesn't need to detail return values. The main gap is lack of behavioral details like error cases or limitations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage for 2 parameters, the description compensates well by explaining both parameters in the INPUTS section: 'root_path' as 'The ABSOLUTE path to the project root' and 'file_path' as 'The path to the specific file you want to read (can be relative to root)'. It also provides a concrete example that clarifies usage. This adds significant meaning beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose with specific verbs ('Get a high-level overview', 'understanding how to USE') and distinguishes it from siblings by focusing on extracting interface information rather than exploring, finding symbols, or analyzing breaks. It explicitly mentions what it returns (function signatures, class definitions, docstrings) and what it doesn't do ('without reading implementation').
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context about when to use this tool ('Perfect for understanding how to USE a module without reading the whole thing'), which implicitly suggests alternatives like reading the full file. However, it doesn't explicitly mention when not to use it or name specific sibling tools as alternatives, though the context is sufficient for differentiation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
what_breaksA
💥 STEP 3: See what code might break if you change this symbol.
USE THIS AFTER find_symbol() to understand the impact of changing a function/class.
IMPROVEMENTS:
Uses structural search (ast-grep) to find ACTUAL code references (ignoring comments/strings).
Returns 2 lines of context around each match.
INPUT:
exact_symbol: Pass THE ENTIRE SYMBOL OBJECT from find_symbol(), not just the name! Must be a dictionary with AT LEAST 'name' and 'path' keys.
EXAMPLE INPUT:
First, get a symbol from find_symbol():
symbols = find_symbol("/Users/john/project", "authenticate") symbol = symbols[0] # Pick the first result
Then pass THE WHOLE SYMBOL OBJECT:
what_breaks(symbol)
EXAMPLE OUTPUT: { "references": [ { "file": "/Users/john/project/src/api.py", "line": 23, "text": " # Authenticate the user user = authenticate_user(username, password) if not user:", "type": "code" } ], "total_count": 1, "strategy": "structural", "note": "Found 1 references using structural search." }
| Name | Required | Description | Default |
|---|---|---|---|
| exact_symbol | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes key behaviors: it performs structural search using ast-grep, ignores comments and strings, returns 2 lines of context around each match, and outputs a structured result with references and metadata. However, it doesn't mention potential limitations like performance or error handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (purpose, usage, improvements, input, examples), but it includes an extensive example input and output that could be condensed. Most sentences earn their place by providing essential information, though the examples are detailed and might be overly verbose for a concise description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (structural code analysis), no annotations, and an output schema that covers return values, the description is complete enough. It explains the tool's purpose, usage context, behavioral traits, parameter requirements, and provides illustrative examples, compensating well for the lack of structured metadata.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It adds significant meaning beyond the schema by explaining that 'exact_symbol' must be 'THE ENTIRE SYMBOL OBJECT from find_symbol(), not just the name!' and specifying it 'Must be a dictionary with AT LEAST 'name' and 'path' keys.' This clarifies the parameter's purpose and constraints that aren't in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'See what code might break if you change this symbol.' It specifies the verb ('see what code might break') and resource ('this symbol'), and distinguishes it from sibling tools by explicitly mentioning it should be used 'AFTER find_symbol()' and contrasting with 'structural search' versus other approaches.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use this tool: 'USE THIS AFTER find_symbol() to understand the impact of changing a function/class.' It also specifies an alternative approach by noting it 'Uses structural search (ast-grep) to find ACTUAL code references (ignoring comments/strings),' implying a distinction from other search methods.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v1.0.0- Changed
explore_repo7 fields changed- removed
Input schema / properties / focus_dirs / titleRemoved value: -"Focus Dirs" - removed
Input schema / properties / include_symbols / titleRemoved value: -"Include Symbols" - removed
Input schema / properties / max_depth / titleRemoved value: -"Max Depth" - removed
Input schema / properties / max_symbols_per_file / titleRemoved value: -"Max Symbols Per File" - removed
Input schema / properties / root_path / titleRemoved value: -"Root Path" - removed
Output schema / properties / result / titleRemoved value: -"Result" - removed
Output schema / titleRemoved value: -"_WrappedResult"
- Changed
find_symbol4 fields changed- removed
Input schema / properties / query / titleRemoved value: -"Query" - removed
Input schema / properties / root_path / titleRemoved value: -"Root Path" - removed
Output schema / properties / result / titleRemoved value: -"Result" - removed
Output schema / titleRemoved value: -"_WrappedResult"
- Added
read_interface - Changed
what_breaks1 field changed- removed
Input schema / properties / exact_symbol / titleRemoved value: -"Exact Symbol"
3 tool updates
- First observed
explore_repo - First observed
find_symbol - First observed
what_breaks
TDQS
Scored across 4 tools
Each tool has a distinct, non-overlapping purpose in the code exploration workflow: explore_repo maps structure, find_symbol locates specific symbols, read_interface provides file overviews, and what_breaks analyzes dependencies. The tools are clearly sequenced and complementary, with no ambiguity in their roles.
Three tools use snake_case with descriptive verbs (explore_repo, find_symbol, read_interface), while what_breaks uses snake_case but with a less conventional verb phrase. The naming is mostly consistent and readable, with only minor deviation in style for what_breaks.
Four tools is well-scoped for a code exploration server, covering the essential workflow from mapping structure to analyzing impacts. Each tool earns its place without redundancy, and the count aligns with the progressive discovery approach described.
The tool set provides complete coverage for codebase exploration: explore_repo for initial mapping, find_symbol for searching, read_interface for understanding files, and what_breaks for impact analysis. There are no obvious gaps, and the tools support a full workflow from discovery to dependency checking.
Maintenance
Related MCP Connectors
Code intelligence platform for AI agents. 20 tools for architecture, security & impact analysis.
Code intelligence for coding agents: semantic, AST, graph, and full-text search. 279+ languages.
Give your AI agent a persistent map of your project's structure, dependencies, and bugs.
Codebase intelligence for AI agents — dead code, blast radius, ownership.
Related MCP Servers
- AlicenseAqualityCmaintenanceProvides AI assistants with progressive code intelligence to explore repository structure, find symbols, and assess the impact of changes using ast-grep.324 PyPIMIT
- AlicenseNot gradedqualityCmaintenanceProvides a semantic understanding of your codebase by parsing with tree-sitter and building a graph of symbols and dependencies. Enables AI assistants to navigate code, analyze changes, and discover architecture using 18 tools with minimal context overhead.12 npm1MIT
- FlicenseNot gradedqualityAmaintenanceProvides efficient code navigation and graph-based analysis for AI agents, enabling symbol resolution, callers, implementations, and type schemas with minimal token usage.-
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to semantically navigate codebases via an AST index, supporting symbol search, usage lookup, module exploration, and dependency analysis.MIT