Scantool - File Scanner MCP
This server gives coding agents a structural map of a codebase—classes, functions, callers, headings, and diffs—so they can navigate and answer questions without reading whole files.
Preview a directory: orientation with entry points, hot functions, central files, and call-graph map (
preview_directory).Scan files and directories: skeletons with line numbers, signatures, condensed excerpts, budgets, depths, and git-ref support (
scan_file,scan_directory,scan_file_content).Search with context: find text or structure names, each hit showing its enclosing function/class plus leads to definitions (
search_structures).Read one node directly:
focuson a function, method, or heading to get it verbatim without guessing line ranges (scan_file,scan_file_content).Diff branches structurally: see added/changed/renamed/removed functions and classes instead of raw git diff (
scan_diff).Find callers and imports: actual call sites with
path:line, or importers of a file (callers).Compare public APIs: list exported names, signatures, and definition locations, with diffs against another ref (
surface).Check merge overlap: structures touched by multiple branches and merge-order hints (
overlap).Trace history: follow one structure across commits that changed it (
history).Resolve locations across refs: translate
path:lineorpath::namefrom one git ref to another (resolve).Detect divergence: functions breaking call patterns their siblings follow (
find_divergence).List directories only: folder hierarchy for navigation (
list_directories).
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., "@Scantool - File Scanner MCPpreview_directory . depth=normal"
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.
Scantool: give your coding agent a map of the codebase
Claude Code, Cursor and VS Code agents find a function by reading whole files. Scantool gives them the structure instead: every class, function, caller and heading with its line numbers, in one call, so the agent reads only what it needs. It works on code and on documents, and it needs no index, no API keys and no setup beyond one command.
Under the hood: a tree-sitter parser for 20+ languages, exposed as an MCP
server and as sct, a shell command the agent runs itself.
Measured on real agent episodes (2026-06-10 and 2026-06-11, Haiku subagents, same tasks in both arms):
"Where is the cache invalidated?" scantool 378 tokens / 1 call
grep 9,370 tokens / 4 calls -> 25x less
pytest skipif-caching bug scantool solved in 3 calls
grep gave up after 13,450 tokens
Read tokens per episode, same with focus 13,523
fact coverage in both arms without 54,337 -> 75% lessAcross 22 episodes the scantool agents answered with 88% fact coverage against
73% for a grep-only agent: better-anchored answers, fewer wrong files. Grep
still wins plain literal lookups and top-level overviews, by 1.4x and 1.6x.
Both axes are measured and the losses are reported in
experiments/benchmark/.
What you use it for
Each of these is one command in the agent's shell, or the matching MCP tool.
Where is X handled in this codebase?
sct search . "cache invalidat"Every hit arrives with the function or class it sits in, the line range, and leads to the definitions it calls. The agent does not open the file to find out what the match belongs to. This is the case measured at 378 tokens against 9,370 for grep.
Get oriented in an unfamiliar repo before changing it
sct .Language mix, entry points, the most-called functions and the central files, in 3 to 5k tokens. What it printed on scantool's own source, trimmed:
━━━ ENTRY POINTS ━━━
server.py:main() @1658
cli.py:main() @562
languages/__init__.py:__all__ (13 items)
━━━ core: CORE FILES (by centrality; used by = files that import it, resolved statically) ━━━
languages/models.py: imports 0, used by 33 files
class StructureNode [called by 178]Read one function without guessing line ranges
sct focus src/scantool/capabilities.py capability_of_toolsrc/scantool/capabilities.py::capability_of_tool (270-274)
capabilities.py (1-333)
- module docstring @1 # FILE: capabilities.py
- import statements @30
- Capability @34
@dataclass(frozen=True)
- CAPABILITIES = (Capability(command='', usage=('sct <dir> [--…',), short='o… @45
- capability (command: str) -> Capability @263
- capability_of_tool (tool: str) -> Capability @270
270 | def capability_of_tool(tool: str) -> Capability:
271 | for entry in CAPABILITIES:The node comes verbatim with line numbers, the rest of the file as a one-level outline, so the agent sees where it sits. In the M2c episodes this cut read tokens by 75% at unchanged fact coverage.
What did this branch change, structurally?
sct diff mainPer file: + added, ~ changed (signature, value or body), = renamed
(paired by identical body), - removed, each with the caller count among the
changed functions. Three functions with the same signature change fold into
one row. It replaces reading a full git diff to answer "what changed".
Who calls this function?
sct callers condense_excerpt --dir src/scantoolActual call sites with their enclosing function and path:line, definitions
first. Mentions in comments, docstrings and strings are not calls and never
appear.
sct callers src/scantool/code_map.pyGiven a file, the files that import it, each with the import line: the
number the preview prints as used by N files, computed from the same
statically resolved import graph.
Will these branches collide when merged?
sct overlap main feat/a feat/bStructures two or more branches touch, names two branches introduced independently, and a merge-order hint. Each branch is compared at its own merge-base.
Did the public API change?
sct surface src/scantool --against v0.25.0Every exported name with its signature and where it is defined after re-exports, and the diff of that surface between two refs.
Is a changed function out of step with its siblings?
sct divergence <dir>, and the same section inside sct diff --review,
lists functions that break a call pattern their peers follow: callers of X
also call Y, this one does not. It is a place to look, never a verdict. On a
consistent codebase it prints nothing.
Find a section in a long Markdown, SQL or config file
sct focus docs/notes.md "Quick Start"
sct scan schema.sql --depth quickHeadings, tables, views, keys and cells are nodes with line ranges, addressed the same way as functions. Code-only tools stop at the source files; a project's documentation, schema and configuration are the same kind of structure here.
Make Claude Code use fewer tokens on a large codebase
Install once, and the agent gets search_structures, scan_file with
focus= and scan_diff as MCP tools, plus sct in its shell. The tool
descriptions tell it when to reach for each, and the numbers at the top of
this page are what that saved in measured episodes.
When grep is the better tool
Literal lookups of a known string, and overviews whose answer sits in the top-level files. In the M2 tasks grep won those by 1.4x and 1.6x. Scantool wins when the question is about a concept or a structure, because the answer needs the enclosing context and grep has to open files to get it.
Related MCP server: MCP Codebase Symbols Server
Install
Scantool runs through uv. Install uv first; without it the server fails silently to start.
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS, Linux, WSLThen, in Claude Code:
claude mcp add --scope user scantool -- uvx scantoolRestart Claude Code. Every other client takes the same entry in its own config file:
{
"mcpServers": {
"scantool": {
"command": "uvx",
"args": ["scantool"]
}
}
}Client | Config file |
Claude Desktop (macOS) |
|
Cursor |
|
Windsurf |
|
VS Code (Copilot agent mode) |
|
Cline | MCP Servers panel, or |
Your team |
|
Windows, install from source, the HTTP transport and troubleshooting are in docs/install.md.
Every install has one side effect: when the server starts it also writes
sct into uv's tool bin directory, so the agent has the same reader in its
shell. SCANTOOL_NO_CLI=1 opts out. Details in docs/sct.md.
sct in the shell
Agents read most code through their shell, not through MCP tools. sct is
the same reader as a shell command, under the same interpreter as the server:
sct <dir> [--part ID] [--lines N]
sct scan <path>... [--ref REF] [--budget N] [--depth quick|normal|deep] [--lines N]
sct scan - [...] paths from stdin, one per line
sct scan - --as <path> [...] stdin content scanned as <path>
sct focus <path> <name|heading> [--ref REF] [--body] [--lines N] [--json]
sct focus <path>::<name>[@REF] the address form, one argument
sct focus - --as <path> <name> stdin content, one node
sct search <dir> <pattern> [--ref REF] [--names] [--type TYPE] [--limit N] [--offset N] [--lines N]
sct search <dir> <pattern> --names --decorator RE one row per structure, decorators on the row
sct diff <refA> [<refB>] [--repo DIR] [--path PATH] [--no-merge-base] [--review]
sct surface <package-dir> [--ref REF] [--against REF] [--part ID]
sct overlap <base> <branch>... [--repo DIR] [--path P] [--kind K] [--part ID]
sct callers <name|file> [--dir DIR] [--ref REF]
sct resolve <path:line | path::name> --from REF --to REF [--repo DIR]
sct divergence <dir> [--max-findings N]
sct history <path::name | path:line> [--ref REF] [--repo DIR]
sct <command> --help the full help; --json on every command but <dir> and divergence, --ascii anywhereOutput is valid input. A focus answer opens with the node's address,
path::Qualified.name (a-b), and that address is one argument that reads it
again. --ref reads at any git ref without a checkout. When a budget cut
something, one trailer names the call that recovers the most. Each command's
full description is in sct <command> --help and in docs/sct.md.
How it works
Scantool parses files on demand with tree-sitter and keeps no index. A parsed file is cached by its git blob id, so the same bytes at a ref, on stdin or in the next process do not parse twice.
Functions are shown as condensed skeletons: control flow, calls and returns
kept, trivial statements folded to …. The most salient functions get full
depth, the rest a two-level outline. Both the tiers and the defaults are the
measured optimum for fact coverage per token
(experiments/condensation/,
experiments/entropy_metrics/); parameters
are escape hatches, not style choices.
Nothing is dropped silently. Every answer opens with a coverage line that counts files seen, structures shown, and what was excluded and why:
<63 files seen, 1501 structures shown, 3 excluded (__pycache__/), 1 unsupported (.typed)>The output format is the API. Agents consume it directly, so format drift is
behaviour drift in the consumer. The default format is frozen by golden tests
(tests/golden/), in tree and JSON form, and a change to it is a deliberate
snapshot update. The contract in full is in
CONTRIBUTING.md.
Compared with
The three largest code-exploration MCP servers take different routes, and each route has a cost scantool does not pay. Checked against their own documentation on 2026-06-11.
Reads the code by | Runs an index or server | API keys | Edits code | |
Scantool | Parsing on demand, structure with line numbers | No | No | No |
Packing the whole repo into one file the agent reads in ranges | No (a pack step) | No | No | |
Language servers, symbol by symbol | A language server per language | No | Yes | |
Embedding index with hybrid search | A vector database | Yes | No |
None of the three extract headings, tables or keys from documents as addressable structure.
The trade-off in this category is measured. An index-based tree-sitter MCP reported 10x fewer tokens and 2.1x fewer tool calls at 83% answer quality against 92% for a raw file-exploration agent, across 31 repositories (arXiv 2603.27277, March 2026, self-reported). Scantool's own numbers above show where it wins and where grep does, on the same footing. Serena's editing is a different job and scantool does not attempt it.
Supported languages
Extension | Language | Extracted elements |
| Python | classes, methods, functions, imports, decorators, docstrings, constants |
| JavaScript | classes, methods, functions, imports, JSDoc comments, constants |
| TypeScript | classes, methods, functions, imports, type annotations, JSDoc, constants |
| Rust | structs, enums, traits, impl blocks, functions, use statements, constants |
| Go | types, structs, interfaces, functions, methods, imports, constants |
| C | functions, structs, enums, includes, constants |
| C++ | classes, functions, namespaces, templates, includes, constants |
| Java | classes, methods, interfaces, enums, annotations, imports |
| PHP | classes, methods, functions, traits, interfaces, namespaces, constants |
| C# | classes, methods, properties, structs, enums, namespaces |
| Ruby | modules, classes, methods, singleton methods, constants |
| Zig | functions, structs, enums, unions, tests, constants |
| Swift | classes, structs, enums, protocols, functions, extensions, constants |
| SQL | tables, views, functions, procedures, indexes, columns |
| HTML | document structure, elements, attributes |
| CSS | selectors, properties, media queries |
| SCSS | selectors, mixins, variables, nesting |
| YAML | mappings, sequences, scalars, anchors/aliases, multi-document streams |
| Markdown | headings (h1-h6), code blocks with hierarchy |
| Jupyter | cells, and inside them the Python and Markdown structure |
| Plain Text | sections, paragraphs |
| JSON | object keys (nested fully), arrays with item counts, scalar values |
| TOML | tables, array tables, nested keys, inline tables, arrays with item counts |
| Images | format, dimensions, colors, content type |
Broken files fall back to regex extraction, so a file that no longer parses still yields its structure. Adding a language is one file; see CONTRIBUTING.md.
MCP tools
The same capabilities as sct, for clients without a shell. Each tool's
description tells the agent when to use it. Parameters, defaults and example
output are in docs/tools.md.
Tool | What it answers |
| Orientation: entry points, hot functions, central files, call map |
| The file tree with one-line gists per file, churn and health labels |
| One file's skeleton; |
| The same reader on content given directly: a git blob, an API response, stdin |
| Text or name search with the enclosing structure and leads to definitions |
| Folders only |
| Structural diff between refs, or a ref and the working tree; |
| A package's public names, where each is defined, and the diff against a ref |
| Structures several branches touch, and a merge order |
| Actual call sites of a name |
| A |
| Functions breaking a call pattern their siblings follow |
| Commits that changed one structure |
Known limitations
Claude Desktop caps an MCP tool response at 25,000 tokens; Claude Code's cap
is set with MAX_MCP_OUTPUT_TOKENS. budget=, depth= and pattern= keep
answers under it, and the coverage line says what a cap left out.
Subagents in Claude Code that lack MCP tools still have the shell, and sct
is in it. If you want the MCP tool specifically, say so: "use scantool to
scan the codebase".
Peer divergence and the connectivity notes are hints from corpus-wide statistics, not verified defects. They tell the agent where to read.
More
docs/install.md: every client, Windows, from source, HTTP transport, troubleshooting
docs/sct.md: the shell command in full, addresses, refs, the cache
docs/tools.md: MCP tool parameters and example output
CONTRIBUTING.md: architecture, adding a language, the output contract, releasing
experiments/benchmark/: the measurements behind the numbers above
Issues and Discussions
MIT License, see LICENSE. Built on FastMCP, tree-sitter and uv.
Available Tools
13 toolscallersCallersA
Actual call sites of a function or method across a directory, never a mention in prose, a comment, a docstring or a string literal; each with its enclosing function and path:line, the definition(s) first. A qualified name (Class.method) narrows the definitions; which definition a site binds to is not resolved, and the answer says so. Given a file instead of a name, the files that import it with the import line, from the same statically resolved import graph as the preview's used by. In your shell: sct callers <name> or sct callers <name> --dir <dir> (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).
| Name | Required | Description | Default |
|---|---|---|---|
| ref | No | ||
| name | Yes | ||
| directory | No | . | |
| output_format | No | tree |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and meets it: it discloses the false-positive exclusions, the unresolved definition-binding limitation and that the answer explicitly says so, the different behavior for file inputs, and reliance on the same statically resolved import graph as `used by`.
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 core semantics are front-loaded and every clause adds information, including the shell invocation and PATH fallback. It is long and somewhat dense, but it is not padded.
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?
Despite having no output schema and no annotations, the description conveys the substance of results: definition(s) first, enclosing function, path:line, and the unresolved-binding caveat. The main gap is the undocumented optional parameters `ref` and `output_format`.
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?
The description adds meaning for `name` (function/method or file) and `directory` via `--dir`, which is valuable given zero schema description coverage. However, it never explains `ref` or `output_format`, so an agent cannot know what `ref` refers to or which output formats are valid.
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 names the specific operation: producing actual call sites of a function or method across a directory. It sharply excludes false matches like prose, comments, docstrings, and string literals, and also explains the file-input mode for finding importers.
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 gives clear usage context: a qualified name narrows definitions, a file input switches the tool to importer discovery, and `--dir` controls the directory scope. It does not explicitly name when-not-to-use sibling tools, but the invocation guidance is concrete and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_divergenceFind DivergenceA
Peer divergence across a directory: functions that break a call pattern their siblings follow (peers calling X also call Y, this one does not). A review hint, not a verified bug list; silent on a consistent codebase, and that silence is the answer. In your shell: sct --help (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).
| Name | Required | Description | Default |
|---|---|---|---|
| directory | Yes | Root directory to audit | |
| max_findings | No | Cap on the number of findings shown (default: 20) | |
| respect_gitignore | No | Respect .gitignore patterns (default: True) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does a good job: it discloses that results are review hints, not verified bugs, and explains the meaning of a silent result. It does not mention side effects, permissions, or failure behavior, but the read-only audit nature is strongly implied.
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 compact and front-loads the core concept before the caveat and shell usage. The shell command sentence is arguably extra but still useful and does not bloat the description significantly.
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 tool's purpose, caveats, and silent-result behavior are covered, but there is no output schema and the description does not explain the structure of the findings. It says 'findings' are capped, but an agent would still wonder what a finding includes or how it is formatted.
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?
All three parameters are fully described in the input schema (100% coverage), so the description does not need to add parameter-level details. The shell command in the description is useful context but does not enhance parameter understanding.
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 defines the tool's purpose with a concrete example of peer divergence ('peers calling X also call Y, this one does not') and immediately qualifies it as a review hint. It does not explicitly differentiate itself from sibling tools like scan_directory or callers, so it misses the top score.
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 implies this is a heuristic review tool rather than a definitive bug detector, and notes that silence on a consistent codebase is meaningful. However, it does not explicitly say when to choose this over sibling tools or provide when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
historyHistoryA
One structure followed backwards through the commits that touched its file: a signature or body change, a rename (paired by identical body, the earlier name followed), the commit that introduced it; a file move is followed. Commits that touched the file but not the structure are counted, not listed. What git log -L gives for a line range, keyed on the structure. In your shell: sct history <path::name> or sct history <path:line> --ref REF (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).
| Name | Required | Description | Default |
|---|---|---|---|
| ref | No | ||
| repo | No | ||
| location | Yes | ||
| output_format | No | tree |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it reveals important behavior: rename detection by identical body, following file moves, counting but not listing unrelated commits, and identifying the introducing commit. This is strong, though output details remain only loosely indicated via the git log -L comparison.
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?
Every sentence carries substantive information and there is no filler. However, the opening sentence is convoluted and passive, burying the basic 'what this tool does' under tracking details before a cleaner analogy appears.
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 gives rich behavioral rules and concrete invocation examples, but there is no output schema and the return format is only approximated by the git log -L analogy. Behavior around output_format and repo is not explained, leaving meaningful gaps for an agent.
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 explains location via examples (`path::name` or `path:line`) and shows ref usage with `--ref REF`, but repo and output_format are not described at all. Core parameters are covered, ancillary ones are not.
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 states a specific behavior: follow a code structure backwards through commits, including renames and the introducing commit. The git log -L analogy reinforces the purpose. It is somewhat dense and jargon-heavy, but still distinguishes this from the sibling tools.
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 implies when to use the tool: when you need history of a structure rather than a plain file or directory. It gives concrete shell invocations, but it does not explicitly compare against siblings or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_directoriesList DirectoriesB
Skeleton of files or a directory: every structure with path:line, signature or title, a condensed excerpt within the budget. A directory gives the tree with one-line gists. --depth quick is about 300 tokens per file, normal 1500, deep everything with module values whole (files only). Elided content is marked ⟨…⟩ +N; focus reads it. Folders only, no files: the directory hierarchy. In your shell: sct --help (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).
| Name | Required | Description | Default |
|---|---|---|---|
| directory | Yes | ||
| max_depth | No | ||
| respect_gitignore | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden, and it does disclose key behavior: returned output is a tree of one-line gists, elided content is marked '⟨…⟩ +N', and depth choices have token budgets. It does not cover side effects, auth, or error behavior, but for a read-only listing tool this is reasonably transparent.
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 text is dense and disorganized, burying the core 'folders only' behavior mid-way and appending shell-specific fallback instructions ('sct --help', venv python path) that are not relevant to MCP invocation. The opening sentence is vague and does not front-load the tool's main purpose.
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?
It covers the main output shape (directory tree, one-line gists) and depth-related behavior, which is useful since there is no output schema. But without parameter documentation for max_depth and respect_gitignore, and without clarifying the first-sentence ambiguity, an agent cannot reliably invoke all parameters correctly.
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 coverage is 0%, so the description must explain the parameters, but it only hints at directory and refers to '--depth quick/normal/deep', which does not map cleanly to the max_depth integer parameter and could mislead an agent into passing those strings. respect_gitignore is not mentioned at all.
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 identifies the resource as directory hierarchy ('Folders only, no files: the directory hierarchy') and the result as a tree with one-line gists, which is more specific than merely restating the tool name. However, the opening 'Skeleton of files or a directory' blurs whether files are included, and no sibling is named, so it is not a perfect differentiator.
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?
It gives a clear scope ('Folders only, no files') that tells an agent when this directory-tree tool is appropriate and when it is not, and it explains depth-mode trade-offs in token budgets. It does not explicitly name sibling alternatives like scan_directory or preview_directory, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
overlapOverlapA
N branches against one base, each at its own merge-base: structures touched by 2+ branches (marked base(~/+/-) when the base itself changed them since the branches forked), new names introduced independently by 2+ branches, commits two branches share (a stack: overlap between them is expected; the residual beyond their shared commits is what stays), and per branch whether it is already in the base and by which criterion (ancestor / patch-equivalent / tree-equal; patch-equivalence proves it can be deleted, not that its content is in the current tree). Ends with a merge-order hint, not a verdict. The first line names the parts (branches, history, shared, colliding, order) with line counts; --part ID prints one part alone. In your shell: sct overlap <base> <branch>... (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).
| Name | Required | Description | Default |
|---|---|---|---|
| base | Yes | ||
| kind | No | ||
| part | No | ||
| path | No | ||
| repo | No | ||
| branches | Yes | ||
| output_format | No | tree |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description bears full behavioral burden, and it delivers: it explains output parts, line counts, --part behavior, the merge-order hint not being a verdict, and the nuanced meaning of patch-equivalence. It also clarifies what can and cannot be concluded from branch-in-base criteria.
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 dense, but each clause carries meaningful information: output parts, inclusion criteria, part filtering, merge-order caveat, and invocation. The structure is front-loaded with the core analysis semantics and ends with practical command details, though the long sentences require careful parsing.
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?
In the absence of an output schema, the description thoroughly explains the return structure and semantics. It covers invocation and core required parameters, but leaves some optional parameters undocumented; this is a gap, not a fatal one, since base and branches suffice for the main use case.
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 coverage, the description compensates for base, branches, and part by explaining base/merge-base semantics and the --part ID behavior. However, kind, path, repo, and output_format are left undefined, making the parameter documentation incomplete for a tool with seven 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 states a specific analytical task: comparing N branches against one base at each branch's own merge-base. It enumerates the distinct outputs (touched structures, independently introduced names, shared commits, branch inclusion criteria), clearly distinguishing it as an overlap-analysis tool rather than a generic diff or history tool.
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 shell invocation and the phrase 'N branches against one base' imply when to use this tool, but there is no explicit guidance about when to prefer it over siblings like find_divergence or history. It tells the agent how to run it, but not the conditions that should trigger selection of overlap over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preview_directoryPreview DirectoryC
No command on a directory = orientation: size and language mix, entry points, hot functions, the call-graph map (~3-5k tokens; for first-time orientation of an unknown codebase, not for targeted questions). Line one lists the answer's parts with their line counts and the form that fetches one part alone. The file tree is the tier below (scan). In your shell: sct <dir> (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).
| Name | Required | Description | Default |
|---|---|---|---|
| part | No | ||
| depth | No | deep | |
| directory | Yes | ||
| max_files | No | ||
| max_entries | No | ||
| respect_gitignore | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavior. It mentions the output size (3-5k tokens) and content (parts, line counts, form to fetch one part). However, it does not explicitly state whether the operation is read-only, has side effects, or requires specific permissions. It does give a shell command, which is helpful, but the behavior beyond the output is not fully disclosed.
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 verbose and poorly structured. The first sentence is cryptic ('No command on a directory = orientation'), and the information is scattered. It includes a shell command but does not front-load the tool's purpose. It is not efficient.
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 has 6 parameters, no schema coverage, no output schema, and no annotations, the description is severely incomplete. It does not explain how parameters affect the output, what the exact return format is, or how to use the tool beyond a shell command. An agent cannot reliably use this tool based on the description.
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 explain the parameters. It does not. The only hint is 'the form that fetches one part alone', which might refer to the 'part' parameter, but it is not explicit. Parameters like depth, max_files, max_entries, respect_gitignore are completely unmentioned.
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 is cryptic and vague. It mentions 'orientation' and lists content like size, language mix, entry points, hot functions, and call-graph map, but does not clearly state that this tool provides an overview of a directory. The phrasing 'No command on a directory = orientation' is confusing and does not clearly differentiate from siblings like scan_directory or list_directories.
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 explicitly states when to use: 'for first-time orientation of an unknown codebase, not for targeted questions'. It also indicates that for a file tree, one should use 'scan' (likely a sibling), providing clear context and an exclusion. However, it does not name specific sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolveResolveA
Translate path:line or path::name from one ref to another: the enclosing structure with start and end at --from, and where it is at --to (same place, renamed with an identical body, or gone, with the nearest names). In your shell: sct resolve <path:line> --from REF or sct resolve <path::name> --from REF --to REF (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).
| Name | Required | Description | Default |
|---|---|---|---|
| repo | No | ||
| ref_to | No | WORKTREE | |
| location | Yes | ||
| ref_from | No | ||
| output_format | No | tree |
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 does this well by explaining the outcome categories (same place, renamed with identical body, gone with nearest names) and the structure of the result. It does not mention whether the operation is read-only or describe edge-case handling, but the core behavior is clearly disclosed.
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 compact and front-loaded: the core definition appears first, followed by concrete invocation examples. No sentence is wasted, though the density of the first sentence might make it slightly harder to parse quickly.
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?
For a tool with no annotations and no output schema, the description covers the main operation and gives usable syntax examples. It is incomplete regarding the repo parameter, output_format values, and exact return shape, which an agent would need for robust invocation.
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 useful meaning for location (path:line or path::name), ref_from (--from REF), and ref_to (--to REF). However, it does not explain repo or output_format at all, leaving two of the five parameters with only their names and defaults as guidance.
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 identifies the verb ('Translate') and resource (path:line or path::name across refs), and specifies the exact operation: locating the enclosing structure at --from and its counterpart at --to. This distinguishes it from the sibling scanning/searching tools, which focus on listing or diffing content rather than ref-to-ref translation.
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?
Usage is implied through concrete shell examples showing both the path:line and path::name forms. However, there is no explicit statement of when to prefer this tool over siblings like find_divergence or surface, nor any exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_diffScan DiffA
Structural diff between refs. One ref = that ref vs the working tree. Two refs = A...B against their merge-base by default (--no-merge-base compares the tips; a note says which). Per file: + added, ~ changed (signature: old → new; or body: N code / M doc lines), = renamed (paired by identical body; children follow a renamed class), - removed; identical signature deltas in 3+ functions fold into one row; new files as skeletons; a + or ~ function says how many other changed functions call it. The coverage line counts files changed without structural rows and names the reason for each. --review appends candidate dead/orphan/drift the changed files introduced; off by default on both doors. ref vs the working tree, or ref vs ref2; review=True appends the review tail. Use instead of git diff for review and 'what changed' questions. In your shell: sct diff <ref> or sct diff <refA> <refB> (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).
| Name | Required | Description | Default |
|---|---|---|---|
| ref | No | HEAD | |
| ref2 | No | ||
| budget | No | ||
| review | No | ||
| directory | Yes | ||
| no_merge_base | No | ||
| output_format | No | tree |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure, and it is remarkably transparent. It discloses merge-base vs tip comparison, the per-file symbol legend, folding of identical deltas, skeleton files, coverage-line behavior, and the review tail with dead/orphan/drift candidates. It even notes that --review is off by default and that a note indicates which comparison mode was used.
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 dense and front-loaded, starting with the core purpose and then providing the output legend and shell usage. It earns its length for a complex tool, but there is some redundancy, such as repeating 'ref vs the working tree, or ref vs ref2' and 'review=True appends the review tail.' It is slightly over-packed but still well structured.
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?
For a complex 7-parameter tool with no annotations and no output schema, the description covers the diff semantics and output rows very well. Yet it omits three parameters, including the only required one, directory, plus budget and output_format, leaving an agent with gaps for a correct invocation. The detail elsewhere makes these omissions conspicuous.
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?
Because schema description coverage is 0%, the description must supply parameter meaning, and it does for ref, ref2, no_merge_base, and review. However, budget, directory (the only required parameter), and output_format are never mentioned, so an agent cannot determine their semantics from either the schema or the description. This is a meaningful gap.
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 opens with 'Structural diff between refs,' naming a specific verb and resource, and then explains one-ref vs two-ref semantics precisely. The detailed output legend makes the purpose unmistakable. It does not explicitly differentiate from sibling tools, so it misses the full 5, but the purpose is otherwise very clear.
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 explicitly says 'Use instead of git diff for review and "what changed" questions,' providing both a use case and an alternative. It also explains when to use one ref vs two refs and how the default merge-base behavior works. It does not enumerate sibling-tool exclusions, but the guidance is strong enough for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_directoryScan DirectoryB
Skeleton of files or a directory: every structure with path:line, signature or title, a condensed excerpt within the budget. A directory gives the tree with one-line gists. --depth quick is about 300 tokens per file, normal 1500, deep everything with module values whole (files only). Elided content is marked ⟨…⟩ +N; focus reads it. A directory: the file tree with one-line gists per file, code health and churn labels; ref= reads it at a git ref. Replaces Glob/ls for all file types. In your shell: sct scan <dir> (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).
| Name | Required | Description | Default |
|---|---|---|---|
| ref | No | ||
| mode | No | balanced | |
| delta | No | ||
| depth | No | ||
| caller | No | ||
| pattern | No | **/* | |
| directory | Yes | ||
| max_files | No | ||
| output_format | No | tree | |
| exclude_patterns | No | ||
| include_metadata | No | ||
| respect_gitignore | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden. It is transparent about key output behaviors: depth-specific token budgets (~300/1500/whole), elision markers (⟨…⟩ +N), one-line gists, code health/churn labels, and reading a specific git ref. It stops short of stating that the operation is read-only, but the core output behavior is well covered.
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 dense but unstructured, mixing output format, depth rules, elision markers, and a shell command in one unparagraphed block. It repeats the directory-tree statement twice ('A directory gives the tree with one-line gists' vs 'A directory: the file tree with one-line gists per file...'). The shell snippet is useful but tangential, and the prose could be tightened into clearer sections.
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?
For a tool with 12 parameters, no output schema, and no annotations, the description is under-specified. It explains skeleton/tree output and covers `depth` and `ref`, but an agent cannot determine the semantics of `mode`, `delta`, or `caller`, or the allowed values of `output_format`. The lack of return-format guidance beyond the elision markers makes it hard to parse results reliably.
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 explains `depth` and `ref`, and indirectly hints at `include_metadata` via 'code health and churn labels.' However, it leaves `mode`, `delta`, `caller`, `max_files`, `output_format`, `exclude_patterns`, `respect_gitignore`, and `pattern` unexplained; opaque params like `delta` and `caller` remain ambiguous. The description does not carry the weight needed for this low-coverage 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 states what the tool produces: a structure skeleton with path:line, signature/title, and condensed excerpt, plus a directory tree with one-line gists and metadata labels. It also differentiates itself by claiming to replace Glob/ls for all file types. However, it never explicitly names sibling tools like list_directories or preview_directory, so differentiation relies on inference.
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 gives a clear context of use: it replaces Glob/ls for all file types, signaling when an agent should reach for this rather than a simple listing. It also offers depth-mode and ref options as practical usage hints. Yet it provides no explicit 'when not to use' guidance or direct comparison to sibling tools such as scan_file_content or preview_directory.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_fileScan FileB
Skeleton of files or a directory: every structure with path:line, signature or title, a condensed excerpt within the budget. A directory gives the tree with one-line gists. --depth quick is about 300 tokens per file, normal 1500, deep everything with module values whole (files only). Elided content is marked ⟨…⟩ +N; focus reads it. One file; budget=1500 for exploration, 300 for a quick look; focus='name' (or 'Class.method') reads one node verbatim instead of guessing line ranges, body_only=True without the file outline; ref= reads it at a git ref. May append a self-levelling CONNECTIVITY note (candidate dead/orphan/drift across the corpus, silent when clean). In your shell: sct scan <path> or sct focus <path> <name> (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).
| Name | Required | Description | Default |
|---|---|---|---|
| ref | No | ||
| mode | No | balanced | |
| delta | No | ||
| depth | No | ||
| focus | No | ||
| budget | No | ||
| caller | No | ||
| condense | No | ||
| body_only | No | ||
| file_path | Yes | ||
| output_format | No | tree | |
| show_complexity | No | ||
| show_decorators | No | ||
| show_docstrings | No | ||
| show_signatures | No | ||
| include_metadata | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and does a substantial job: it discloses output shape, token budgets per depth, elision marker semantics, focus/body_only behavior, and the optional CONNECTIVITY note. It leaves some behaviors like mode/delta/condense/output_format unexplained, but the core scanning behavior is well disclosed.
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 packs a lot of useful information but does so as one dense run-on paragraph with semicolons. It front-loads the main purpose, yet the lack of structure makes the many details harder to parse; every sentence is informative, but the format is not optimized for an agent scanning the text.
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?
For the required file_path and the main optional parameters, the tool is well specified with budgets, focus semantics, ref handling, and elision behavior. However, with 16 parameters, zero schema descriptions, and no output schema, the many unmentioned toggles leave the definition incomplete for full correct invocation across all options.
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 does add meaning for file_path, depth, budget, focus, body_only, and ref, but 16 parameters exist and most are never explained: mode, delta, condense, caller, output_format, show_complexity, show_decorators, show_docstrings, show_signatures, and include_metadata are all absent from the description.
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 what the tool does: it produces a skeleton of a file or directory with path:line, signatures/titles, and budgeted excerpts. It is concrete about the resource and result, but it does not explicitly differentiate itself from sibling tools like scan_file_content or scan_directory, even though it also handles directories despite the 'file' name.
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 gives practical guidance: budget=1500 for exploration, 300 for a quick look, focus for reading a single node, body_only to suppress the outline, and ref for git refs. However, it does not name alternatives or exclusion conditions, so an agent has to infer when scan_file_content or scan_directory would be more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_file_contentScan File ContentA
Skeleton of files or a directory: every structure with path:line, signature or title, a condensed excerpt within the budget. A directory gives the tree with one-line gists. --depth quick is about 300 tokens per file, normal 1500, deep everything with module values whole (files only). Elided content is marked ⟨…⟩ +N; focus reads it. Content given directly (remote files, APIs, a git blob, stdin), same budget/depth and focus as scan_file. In your shell: sct scan - --as <path> or sct focus - --as <path> <name> (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | balanced | |
| depth | No | ||
| focus | No | ||
| budget | No | ||
| content | Yes | ||
| condense | No | ||
| filename | Yes | ||
| body_only | No | ||
| output_format | No | tree | |
| show_complexity | No | ||
| show_decorators | No | ||
| show_docstrings | No | ||
| show_signatures | No | ||
| include_metadata | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses budget behavior (quick ~300 tokens, normal 1500, deep everything), elision marking (⟨…⟩ +N), focus behavior, and the fact that content can be piped via stdin. It also explains the CLI invocation fallback. This is substantial behavioral context beyond the schema. However, it doesn't disclose side effects (likely none) or error conditions, and the 'same budget/depth and focus as scan_file' reference assumes knowledge of another tool.
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 dense and information-rich, but it's a single run-on paragraph that mixes conceptual explanation with CLI usage examples. The most important distinction (content given directly) appears mid-paragraph rather than front-loaded. The CLI invocation details are useful but could be separated or condensed. Every sentence earns its place, but the structure could be improved.
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?
For a tool with 14 parameters, no annotations, and no output schema, the description is incomplete. It explains the core scanning behavior and budget/depth semantics, but doesn't explain what output_format options exist, what mode means, what condense does, or what the return structure looks like. The sibling tools (scan_file, scan_directory) suggest this is part of a family, and the description references scan_file's behavior, but an agent couldn't confidently set all 14 parameters correctly based on this description alone.
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 explains depth values (quick/normal/deep) and budget implications, and mentions focus reads elided content. It also explains the content and filename parameters implicitly via the stdin example. However, 14 parameters exist and many (mode, condense, body_only, output_format, show_complexity, show_decorators, show_docstrings, show_signatures, include_metadata) are not explained at all. The description covers maybe 4 of 14 parameters, so it partially compensates but leaves most parameters undocumented.
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 states a specific verb ('scan') and resource ('file content' or directory), and distinguishes itself from scan_file by handling content given directly (remote files, APIs, git blob, stdin) rather than paths. However, it doesn't explicitly name the sibling it differs from, and the opening 'Skeleton of files or a directory' is somewhat ambiguous about whether this tool handles directories (which scan_directory likely does).
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 gives clear context for when to use this tool: when content is provided directly (remote files, APIs, git blob, stdin), and even provides shell command examples. It implies the alternative (scan_file) for path-based scanning, but doesn't explicitly state 'use scan_file for paths' or list exclusions. The sibling list includes scan_file and scan_directory, so the differentiation is mostly implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_structuresSearch StructuresA
Text across a directory (or one file) with structural context: each hit shows its enclosing structure, plus leads to where matched names are defined; when no lead exists it says so. --names matches structure names instead of text, and an empty answer names the paths that match. The pattern is a Python regex; grep's \| is read as alternation with a note. --type filters which structures are reported; --decorator RE (with --names) keeps structures with a matching decorator and answers one row per structure, decorators on the row. 40 structures per page, --limit/--offset for the rest, and the page is stated. content_pattern finds text with its enclosing function/class/section plus leads to definitions; name_pattern/type_filter/has_decorator find structures; ref= searches at a git ref. Best first call for a targeted question; use instead of Grep. In your shell: sct search <dir> <pattern> (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).
| Name | Required | Description | Default |
|---|---|---|---|
| ref | No | ||
| limit | No | ||
| offset | No | ||
| directory | Yes | ||
| type_filter | No | ||
| name_pattern | No | ||
| has_decorator | No | ||
| output_format | No | tree | |
| min_complexity | No | ||
| content_pattern | No | ||
| include_metadata | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does a good job: it discloses pagination at 40 per page, states the page is reported, explains edge cases (no lead, empty match answer), and documents Python regex semantics including grep alternation. It doesn't cover auth requirements or failure modes, but for a search tool the disclosed behavior is substantial.
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 dense but not padded; the core purpose is front-loaded and every subsequent clause adds actionable detail about modes, regex behavior, pagination, and invocation. It reads as a long run-on block rather than structured sections, but for a tool with 11 parameters the length is mostly earned.
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 core search behavior, parameter mappings, and pagination are covered well, and there is enough detail for a first targeted code-search call. Yet with no output schema and 0% schema-description coverage, the complete omission of output_format, min_complexity, include_metadata, and type_filter allowed values leaves meaningful gaps.
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 needs to compensate, and it maps many parameters: --names/name_pattern, --type/type_filter, --decorator/has_decorator, content_pattern, ref, limit, and offset. However, output_format, min_complexity, and include_metadata are never explained, and the CLI flag names require the agent to map them to schema property names.
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 first sentence clearly states the tool searches text across a directory with structural context, and later sentences distinguish text search from structure-name search. It doesn't explicitly name a sibling as the alternative, but it does position itself as the best first call and tells the agent to use it instead of Grep, which differentiates it from a plain text search tool.
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 says 'Best first call for a targeted question; use instead of Grep' and explains the main modes (content search vs structure search vs git ref), giving an agent a clear sense of when to invoke it. It doesn't provide negative usage guidance or explicitly contrast with sibling tools like scan_file_content, so it stops short of full exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
surfaceSurfaceA
The public surface of a package directory at a ref: every exported name with its signature, how it is exported and where it is defined. Each language applies its own rule: Python's all, lazy tables and re-export chains; Rust's pub and lib.rs re-exports; TypeScript's index exports; Go's exported identifiers; visibility keywords elsewhere; a namespace or module is looked through. --against REF prints the surface diff; the header states the direction (A → B) and names its parts (added, changed, moved, removed) with line counts; --part ID prints one part alone. In your shell: sct surface <package-dir> or sct surface <package-dir> --against REF (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).
| Name | Required | Description | Default |
|---|---|---|---|
| ref | No | ||
| part | No | ||
| against | No | ||
| package_dir | Yes | ||
| output_format | No | tree |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and meets it: it states exactly what is inspected, how each language's export rules are applied, what the diff header contains (direction, parts, line counts), and what `--part` prints. It also makes the read-only nature clear by describing printed output, so the agent can infer no destructive side effects.
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 dense but front-loaded, leading with the core purpose before adding language rules, flags, and shell invocation. Every sentence contributes, though the invocation fallback sentence is slightly verbose for a tool definition.
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?
For a 5-parameter tool with no output schema and no annotations, the description explains the primary output and main modes, but it leaves `ref` and `output_format` underspecified. An agent can make a correct basic call but may mis-specify output formats or the ref parameter.
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 supply parameter meaning; it does for package_dir, --against, and --part, but leaves `ref` and `output_format` undocumented. The `ref` property is only vaguely implied by 'at a ref,' and `output_format` has no explanation at all.
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 opens with a specific resource ('public surface of a package directory at a ref') and enumerates the output ('every exported name with its signature, how it is exported and where it is defined'), making the purpose clear. It does not explicitly distinguish itself from sibling tools like scan_diff or find_divergence, so differentiation is implicit rather than stated.
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?
It gives concrete invocation patterns (`sct surface <package-dir>`, `--against REF`, `--part ID`) and explains the diff and part-printing modes, giving a clear sense of when each mode is appropriate. It does not, however, state exclusions or when to prefer a sibling tool.
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.
5 tool updates
v0.28.0- Changed
overlap1 field changed- added
Input schema / properties / partAdded value: +{ + "default": "", + "type": "string" +}
- Changed
preview_directory1 field changed- added
Input schema / properties / partAdded value: +{ + "default": "", + "type": "string" +}
- Changed
scan_file1 field changed- added
Input schema / properties / body_onlyAdded value: +{ + "default": false, + "type": "boolean" +}
- Changed
scan_file_content1 field changed- added
Input schema / properties / body_onlyAdded value: +{ + "default": false, + "type": "boolean" +}
- Changed
surface1 field changed- added
Input schema / properties / partAdded value: +{ + "default": "", + "type": "string" +}
9 tool updates
v0.26.0- Added
callers - Added
history - Added
overlap - Added
resolve - Changed
scan_diff4 fields changed- added
Input schema / properties / no_merge_baseAdded value: +{ + "default": false, + "type": "boolean" +} - added
Input schema / properties / output_formatAdded value: +{ + "default": "tree", + "type": "string" +} - added
Input schema / properties / ref2Added value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / reviewAdded value: +{ + "default": false, + "type": "boolean" +}
- Changed
scan_directory1 field changed- added
Input schema / properties / refAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
scan_file1 field changed- added
Input schema / properties / refAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
search_structures1 field changed- added
Input schema / properties / refAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +}
- Added
surface
4 tool updates
v0.23.0- Changed
scan_directory2 fields changed- added
Input schema / properties / callerAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / include_metadataAdded value: +{ + "default": true, + "type": "boolean" +}
- Changed
scan_file2 fields changed- added
Input schema / properties / callerAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / include_metadataAdded value: +{ + "default": true, + "type": "boolean" +}
- Changed
scan_file_content6 fields changed- added
Input schema / properties / budgetAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / condenseAdded value: +{ + "default": true, + "type": "boolean" +} - added
Input schema / properties / depthAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / focusAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / include_metadataAdded value: +{ + "default": true, + "type": "boolean" +} - added
Input schema / properties / modeAdded value: +{ + "default": "balanced", + "type": "string" +}
- Changed
search_structures3 fields changed- added
Input schema / properties / include_metadataAdded value: +{ + "default": true, + "type": "boolean" +} - added
Input schema / properties / limitAdded value: +{ + "default": 40, + "type": "integer" +} - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "type": "integer" +}
8 tool updates
v0.20.1- Changed
find_divergence4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / directory / descriptionAdded value: +"Root directory to audit" - added
Input schema / properties / max_findings / descriptionAdded value: +"Cap on the number of findings shown (default: 20)" - added
Input schema / properties / respect_gitignore / descriptionAdded value: +"Respect .gitignore patterns (default: True)"
- Changed
list_directories1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
preview_directory1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
scan_diff1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
scan_directory1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
scan_file1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
scan_file_content1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_structures1 field changed- added
Input schema / additionalPropertiesAdded value: +false
8 tool updates
v0.19.4- First observed
find_divergence - First observed
list_directories - First observed
preview_directory - First observed
scan_diff - First observed
scan_directory - First observed
scan_file - First observed
scan_file_content - First observed
search_structures
TDQS
Scored across 13 tools
Multiple tools share nearly identical opening descriptions: scan_file, scan_file_content, scan_directory, list_directories, and preview_directory all describe skeleton/tree output for files or directories. An agent must read carefully to distinguish file path vs. direct content vs. directory vs. folders-only vs. orientation, so boundaries are unclear.
Most names follow a verb_noun snake_case pattern (scan_file, scan_directory, search_structures, list_directories), but several tools break it with noun-only or verb-only names (history, surface, overlap, callers, resolve). The naming is readable and consistently snake_case, yet the conventions are mixed.
At 13 tools, the count is within the well-scoped range and broadly justified by the server's wide static-analysis purpose. However, several scanning variants overlap in functionality, making the set feel slightly larger than necessary.
The tool surface is comprehensive for a read-only code scanner: it covers scanning, search, callers, structural diff, history, resolve, public API surface, branch overlap, and divergence hints. There are no obvious dead ends or missing operations for the stated purpose.
Maintenance
Related MCP Connectors
Code intelligence for coding agents: semantic, AST, graph, and full-text search. 279+ languages.
AI-powered codebase analysis — call graphs, security, dead code, complexity. 150+ tools.
Code intelligence for LLMs. Analyze, search, and retrieve code from any public git repository.
Code intelligence platform for AI agents. 20 tools for architecture, security & impact analysis.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI assistants to understand and navigate codebases through structural analysis. Provides code mapping, symbol search, and impact analysis using ast-grep for accurate parsing of Python, JavaScript, TypeScript, and Go projects.452MIT
- AlicenseAqualityDmaintenanceAnalyzes codebases and extracts all symbols (functions, classes, methods, interfaces, etc.) from 10+ programming languages into LLM-optimized markdown format. Enables AI assistants to understand entire project structures efficiently without processing full source code.25 npmMIT
- FlicenseAqualityCmaintenanceAnalyzes source code across multiple languages to extract structural elements like classes, functions, and parameters using tree-sitter. It provides LLM-optimized markdown output that includes nesting levels, line numbers, and signatures to facilitate codebase navigation.1-
- AlicenseNot gradedqualityDmaintenanceEnables precise code extraction from 30+ languages using tree-sitter parsing, allowing AI assistants to retrieve functions, classes, and code snippets with accurate line numbers.8MIT