Skip to main content
Glama
mariusei

Scantool - File Scanner MCP

by mariusei

Scantool: give your coding agent a map of the codebase

PyPI version License: MIT

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% less

Across 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 FILES (by centrality) ━━━
  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_tool
src/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 main

Per 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/scantool

Actual call sites with their enclosing function and path:line, definitions first. Mentions in comments, docstrings and strings are not calls and never appear.

Will these branches collide when merged?

sct overlap main feat/a feat/b

Structures 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.0

Every 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 quick

Headings, 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, WSL

Then, in Claude Code:

claude mcp add --scope user scantool -- uvx scantool

Restart 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)

~/Library/Application Support/Claude/claude_desktop_config.json

Cursor

~/.cursor/mcp.json, or .cursor/mcp.json per project

Windsurf

~/.codeium/windsurf/mcp_config.json

VS Code (Copilot agent mode)

.vscode/mcp.json, with the top-level key servers instead of mcpServers

Cline

MCP Servers panel, or ~/.cline/mcp.json for the CLI

Your team

.mcp.json in the project root; Claude Code asks each member once

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> [--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 anywhere

Output 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

Repomix

Packing the whole repo into one file the agent reads in ranges

No (a pack step)

No

No

Serena

Language servers, symbol by symbol

A language server per language

No

Yes

claude-context

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

.py, .pyw

Python

classes, methods, functions, imports, decorators, docstrings, constants

.js, .jsx, .mjs, .cjs

JavaScript

classes, methods, functions, imports, JSDoc comments, constants

.ts, .tsx, .mts, .cts

TypeScript

classes, methods, functions, imports, type annotations, JSDoc, constants

.rs

Rust

structs, enums, traits, impl blocks, functions, use statements, constants

.go

Go

types, structs, interfaces, functions, methods, imports, constants

.c, .h

C

functions, structs, enums, includes, constants

.cpp, .hpp, .cc, .hh

C++

classes, functions, namespaces, templates, includes, constants

.java

Java

classes, methods, interfaces, enums, annotations, imports

.php

PHP

classes, methods, functions, traits, interfaces, namespaces, constants

.cs

C#

classes, methods, properties, structs, enums, namespaces

.rb

Ruby

modules, classes, methods, singleton methods, constants

.zig

Zig

functions, structs, enums, unions, tests, constants

.swift

Swift

classes, structs, enums, protocols, functions, extensions, constants

.sql

SQL

tables, views, functions, procedures, indexes, columns

.html

HTML

document structure, elements, attributes

.css

CSS

selectors, properties, media queries

.scss

SCSS

selectors, mixins, variables, nesting

.yaml, .yml

YAML

mappings, sequences, scalars, anchors/aliases, multi-document streams

.md

Markdown

headings (h1-h6), code blocks with hierarchy

.ipynb

Jupyter

cells, and inside them the Python and Markdown structure

.txt

Plain Text

sections, paragraphs

.json

JSON

object keys (nested fully), arrays with item counts, scalar values

.toml

TOML

tables, array tables, nested keys, inline tables, arrays with item counts

.png, .jpg, .gif, .webp

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

preview_directory

Orientation: entry points, hot functions, central files, call map

scan_directory

The file tree with one-line gists per file, churn and health labels

scan_file

One file's skeleton; focus= reads one node verbatim; budget= caps the size

scan_file_content

The same reader on content given directly: a git blob, an API response, stdin

search_structures

Text or name search with the enclosing structure and leads to definitions

list_directories

Folders only

scan_diff

Structural diff between refs, or a ref and the working tree; review=True adds divergence

surface

A package's public names, where each is defined, and the diff against a ref

overlap

Structures several branches touch, and a merge order

callers

Actual call sites of a name

resolve

A path:line or path::name carried from one ref to another

find_divergence

Functions breaking a call pattern their siblings follow

history

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

MIT License, see LICENSE. Built on FastMCP, tree-sitter and uv.

Available Tools

13 tools
callersCallersA

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. 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).

ParametersJSON Schema
NameRequiredDescriptionDefault
refNo
nameYes
directoryNo.
output_formatNotree

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Since no annotations are provided, the description carries the behavioral disclosure burden. It reveals output ordering (definitions first), output components (enclosing function and path:line), filtering behavior, and a key limitation (binding to a specific definition is not resolved). It does not explicitly state read-only behavior, but the overall query nature and lack of contradiction compensate partially.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but economical: three sentences deliver the definition, scope exclusions, output details, resolution limitation, and runnable command. Every sentence contributes unique value, and the core meaning is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

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 does a solid job explaining output structure and limitations. However, it omits semantics for `ref` and `output_format`, both of which are present in the schema and could affect invocation or result rendering. It is adequate for basic use but incomplete for full parameter understanding.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has no property descriptions, and schema coverage is 0%, so the description must explain the parameters. It does cover `name` and `directory` (via the CLI command), but it says nothing about `ref` or `output_format`. Two of the four parameters remain unexplained, leaving the agent to guess their meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise action and resource: 'Actual call sites of a function or method across a directory.' It further clarifies what is excluded (prose, comments, docstrings, string literals), making the tool's purpose unambiguous. The qualified-name behavior adds another distinguishing detail.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit invocation patterns and defines the tool's scope boundaries: actual code call sites only, never textual mentions. It also explains when to use a qualified name to narrow definitions. It stops short of naming alternative sibling tools, but the usage context is clearly established.

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
directoryYesRoot directory to audit
max_findingsNoCap on the number of findings shown (default: 20)
respect_gitignoreNoRespect .gitignore patterns (default: True)

TDQS

A3.6/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
refNo
repoNo
locationYes
output_formatNotree

TDQS

A3.5/5.0
Behavior4/5

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.

Conciseness3/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
directoryYes
max_depthNo
respect_gitignoreNo

TDQS

B3.4/5.0
Behavior4/5

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.

Conciseness2/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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. In your shell: sct overlap <base> <branch>... (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).

ParametersJSON Schema
NameRequiredDescriptionDefault
baseYes
kindNo
pathNo
repoNo
branchesYes
output_formatNotree

TDQS

A3.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden, and it does so thoroughly: it discloses expected stack overlap, residual commit semantics, the meaning of patch-equivalence, and explicitly warns that the result is 'a merge-order hint, not a verdict.' It also explains the significance of base markers.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and information-rich, but it is a single sprawling paragraph that mixes output semantics, caveats, and shell invocation. It is not poorly sized, but better structure (bullets or separation of output categories from usage) would improve scannability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the tool's output structure and command invocation well, which is important given there is no output schema or annotations. However, it omits semantics for four optional parameters and does not provide sibling-tool guidance, leaving some ambiguity for complex calls.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 clarifies the two required parameters through the command syntax `sct overlap <base> <branch>...`, but it leaves the optional parameters (`kind`, `path`, `repo`, `output_format`) unexplained. This is partial compensation, not complete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool's purpose: comparing N branches against one base at their own merge-bases and reporting overlapping structures, names, commits, and base-inclusion criteria. It uses specific verbs and resources, but it does not explicitly distinguish itself from siblings like find_divergence or scan_diff.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when the tool would be used (branch-overlap analysis) and even provides a shell invocation, but it does not state when to prefer this tool over alternatives such as find_divergence or scan_diff. There is no explicit 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.

preview_directoryPreview DirectoryB

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). 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).

ParametersJSON Schema
NameRequiredDescriptionDefault
depthNodeep
directoryYes
max_filesNo
max_entriesNo
respect_gitignoreNo

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the behavioral disclosure burden. It discloses the output nature (orientation summary, ~3-5k tokens, call-graph map) and scopes the tool to broad orientation rather than targeted queries. It does not mention side effects, read-only behavior, or how the tool behaves with atypical inputs, but the output and scope are 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.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short and mostly front-loaded, and it includes a useful shell invocation plus fallback command. However, the opening sentence is syntactically confusing ('No command on a directory') and the relation to 'scan' is cryptic. The content earns its place, but the phrasing weakens the structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The core use case and output shape are described, but the tool has five parameters, no output schema, and no annotations. An agent cannot determine how to use or interpret depth, max_files, max_entries, or respect_gitignore. The missing parameter context makes the description incomplete for reliable invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description essentially compensates for none of the five parameters. The only parameter hinted at is 'directory' via the shell example 'sct <dir>'; depth, max_files, max_entries, and respect_gitignore are entirely unexplained. This is a substantial gap for an agent trying to invoke the tool correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool's purpose: it provides an orientation-level overview of a directory, including size, language mix, entry points, hot functions, and a call-graph map. It also distinguishes this from the file-tree-level 'scan' tool. However, the opening phrase 'No command on a directory' is garbled and obscures the intended meaning.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the intended use case: first-time orientation over an unknown codebase, and explicitly says it is not for targeted questions. It also positions 'scan' as the tier below for file trees. It does not enumerate sibling alternatives or give precise when-not-to-use conditions for each sibling, but it offers enough routing guidance.

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
repoNo
ref_toNoWORKTREE
locationYes
ref_fromNo
output_formatNotree

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
refNoHEAD
ref2No
budgetNo
reviewNo
directoryYes
no_merge_baseNo
output_formatNotree

TDQS

A4/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
refNo
modeNobalanced
deltaNo
depthNo
callerNo
patternNo**/*
directoryYes
max_filesNo
output_formatNotree
exclude_patternsNo
include_metadataNo
respect_gitignoreNo

TDQS

B3.4/5.0
Behavior4/5

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.

Conciseness3/5

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.

Completeness2/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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 FileC

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; 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).

ParametersJSON Schema
NameRequiredDescriptionDefault
refNo
modeNobalanced
deltaNo
depthNo
focusNo
budgetNo
callerNo
condenseNo
file_pathYes
output_formatNotree
show_complexityNo
show_decoratorsNo
show_docstringsNo
show_signaturesNo
include_metadataNo

TDQS

C2.5/5.0
Behavior2/5

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 mention elision markers (⟨…⟩ +N), focus behavior, and a self-levelling CONNECTIVITY note, which are useful. However, it does not state whether the operation is read-only, what the return structure looks like, how errors are handled, or any side effects. For a scan tool this is a notable gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a dense single paragraph that mixes core functionality, parameter details, CLI commands, and a caveat about the PATH. It is not front-loaded and would benefit from bullet points or clear sections. It contains some redundancy (e.g., repeated mention of budget) and is more verbose than necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 15 parameters and no output schema, the description is incomplete. It does not describe the output format (beyond 'skeleton'), does not explain many parameters, and lacks guidance on expected return values or error conditions. While it covers some advanced features, the overall completeness is inadequate for an agent to use it confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

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 for all 15 parameters. It explains depth levels (quick/normal/deep), budget values, focus, and ref, but leaves delta, condense, output_format, show_complexity, show_decorators, show_docstrings, show_signatures, include_metadata, and caller entirely unexplained. The partial coverage is insufficient for the parameter count.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb ('scan') and resource ('files or a directory') and describes the output as a skeleton with structure, signatures, and excerpts. It is not a tautology and provides a concrete picture of what the tool does, though it does not explicitly contrast itself with sibling tools like scan_directory or scan_file_content.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives parameter-level guidance (budget for quick vs. exploration, focus for reading a node verbatim) but does not indicate when to choose this tool over its siblings. There is no mention of alternatives or exclusion criteria, leaving the agent to infer the tool's niche from the title and generic scan behavior.

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNobalanced
depthNo
focusNo
budgetNo
contentYes
condenseNo
filenameYes
output_formatNotree
show_complexityNo
show_decoratorsNo
show_docstringsNo
show_signaturesNo
include_metadataNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses depth levels (quick ~300 tokens, normal 1500, deep everything), elision markers (⟨…⟩ +N), and that focus reads elided content. It provides shell command examples. However, it does not cover all behavioral aspects like exact output format or error handling. Substantial insight but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but front-loaded with the main purpose. Each sentence adds detail about behavior, depth, or usage. It is not overly brief but is well-structured, with key information upfront and examples. It is appropriately sized for the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 13 parameters, no output schema, and no annotations, the description provides a fair amount of context: core behavior, depth options, shell usage. However, it leaves many parameters undefined and relies on 'same as scan_file' which may not be obvious to the agent. For a complex tool, it is not fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It explains the depth parameter (quick/normal/deep), focus (reads elided content), and budget (token counts implied). It does not describe mode, output_format, condense, show_* flags, or other parameters. It adds value for key parameters but does not cover the majority of the 13 parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states it scans file content given directly (remote files, APIs, git blob, stdin) and produces a skeletal structure with path:line, signatures, and excerpts. It explicitly mentions 'Content given directly' and 'same budget/depth and focus as scan_file', which differentiates it from the sibling scan_file (which presumably uses file paths). This is a specific verb+resource with clear sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool: when you have content directly rather than a file path. It provides shell command examples but does not explicitly name alternative tools or state 'use this instead of scan_file when providing content'. It gives clear context about the input type but lacks explicit exclusions.

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. 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).

ParametersJSON Schema
NameRequiredDescriptionDefault
refNo
limitNo
offsetNo
directoryYes
type_filterNo
name_patternNo
has_decoratorNo
output_formatNotree
min_complexityNo
content_patternNo
include_metadataNo

TDQS

A4.5/5.0
Behavior4/5

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 discloses pagination (40 per page, --limit/--offset, page stated), the empty-answer behavior ('an empty answer names the paths that match'), the grep alternation quirk ('grep's \| is read as alternation with a note'), and the CLI invocation fallback. It does not explicitly state that the tool is read-only, but the search semantics and 'use instead of Grep' strongly imply a non-mutating operation. The only minor gap is not stating whether results are sorted or how the tree output is structured, but the description is rich enough to earn a 4.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but front-loaded: the first sentence establishes the core value proposition, and the rest adds mode distinctions, pagination, and CLI invocation. It is longer than ideal, but every sentence carries distinct information. The CLI invocation detail at the end is useful but could be trimmed or moved to a separate field; still, the structure is logical and scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex 11-parameter tool with no annotations and no output schema, the description covers the main usage modes, pagination, edge-case behavior (empty answer, grep alternation), and CLI fallback. It does not document output_format, min_complexity, or include_metadata, and it does not describe the return value shape beyond 'each hit shows its enclosing structure'. Given the tool's complexity, a 4 is appropriate; a 5 would require explicit coverage of every parameter and the output format.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 for the 11 parameters. It explains the key parameter groups: content_pattern (text with enclosing structure), name_pattern/type_filter/has_decorator (structure-name search), ref (git ref), limit/offset (pagination), and --names (which maps to name_pattern). It does not explain output_format, min_complexity, or include_metadata, but the core decision-driving parameters are covered. Given the high parameter count and zero schema coverage, this is a strong compensation effort, though not perfect.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb ('Search') and resource ('text across a directory or one file') and immediately distinguishes itself from plain grep by adding structural context: each hit shows its enclosing structure and leads to definitions. It also names the sibling alternative ('use instead of Grep') and explains the --names mode, so an agent can tell exactly what this tool does and how it differs from a plain text search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Best first call for a targeted question; use instead of Grep', giving a clear when-to-use directive and naming the alternative. It also explains the two main modes (content_pattern vs name_pattern/type_filter/has_decorator) and the ref= option, so an agent knows which parameters to set for which intent. This is unusually complete usage guidance.

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). 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).

ParametersJSON Schema
NameRequiredDescriptionDefault
refNo
againstNo
package_dirYes
output_formatNotree

TDQS

A3.6/5.0
Behavior4/5

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 language-specific export rules, namespace/module traversal, and that --against produces a diff with direction in the header. It does not mention output_format behavior or failure modes, but it provides substantial behavioral detail beyond a vague summary.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose, then adds language-specific context, diff mode, and shell usage. Its four sentences each add meaningful information, though the opening sentence is dense and the command examples could be more compact.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with four parameters, no annotations, and no output schema, the description provides a strong semantic overview and even details the return content (names, signatures, export style, definition location). However, it omits explicit documentation for output_format and ref parameter mapping, leaving some ambiguity for a complex tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Because schema description coverage is 0%, the description must compensate for missing parameter documentation. It explains package_dir through the shell command, against through --against REF, and ref through 'at a ref', but it never explains the output_format parameter or enumerates its possible values. This is partial compensation with clear gaps.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: it shows the public surface of a package directory at a ref, listing every exported name with its signature, export style, and definition location. This is specific enough to distinguish it from sibling tools like list_directories or scan_directory, though it does not explicitly name an alternative to contrast against.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives concrete shell invocations and explains the --against REF diff mode, so an agent can understand how to run it. However, it does not explicitly state when to prefer this tool over siblings such as scan_diff, overlap, or scan_directory, leaving the decision to inference.

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.

  1. 9 tool updatesv0.26.0
    • Addedcallers
    • Addedhistory
    • Addedoverlap
    • Addedresolve
    • Changedscan_diff4 fields changed
      • addedInput schema / properties / no_merge_base
        Added value: +{
        +  "default": false,
        +  "type": "boolean"
        +}
      • addedInput schema / properties / output_format
        Added value: +{
        +  "default": "tree",
        +  "type": "string"
        +}
      • addedInput schema / properties / ref2
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedInput schema / properties / review
        Added value: +{
        +  "default": false,
        +  "type": "boolean"
        +}
    • Changedscan_directory1 field changed
      • addedInput schema / properties / ref
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
    • Changedscan_file1 field changed
      • addedInput schema / properties / ref
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
    • Changedsearch_structures1 field changed
      • addedInput schema / properties / ref
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
    • Addedsurface
  2. 4 tool updatesv0.23.0
    • Changedscan_directory2 fields changed
      • addedInput schema / properties / caller
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedInput schema / properties / include_metadata
        Added value: +{
        +  "default": true,
        +  "type": "boolean"
        +}
    • Changedscan_file2 fields changed
      • addedInput schema / properties / caller
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedInput schema / properties / include_metadata
        Added value: +{
        +  "default": true,
        +  "type": "boolean"
        +}
    • Changedscan_file_content6 fields changed
      • addedInput schema / properties / budget
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedInput schema / properties / condense
        Added value: +{
        +  "default": true,
        +  "type": "boolean"
        +}
      • addedInput schema / properties / depth
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedInput schema / properties / focus
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedInput schema / properties / include_metadata
        Added value: +{
        +  "default": true,
        +  "type": "boolean"
        +}
      • addedInput schema / properties / mode
        Added value: +{
        +  "default": "balanced",
        +  "type": "string"
        +}
    • Changedsearch_structures3 fields changed
      • addedInput schema / properties / include_metadata
        Added value: +{
        +  "default": true,
        +  "type": "boolean"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "default": 40,
        +  "type": "integer"
        +}
      • addedInput schema / properties / offset
        Added value: +{
        +  "default": 0,
        +  "type": "integer"
        +}
  3. 8 tool updatesv0.20.1
    • Changedfind_divergence4 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / directory / description
        Added value: +"Root directory to audit"
      • addedInput schema / properties / max_findings / description
        Added value: +"Cap on the number of findings shown (default: 20)"
      • addedInput schema / properties / respect_gitignore / description
        Added value: +"Respect .gitignore patterns (default: True)"
    • Changedlist_directories1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedpreview_directory1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedscan_diff1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedscan_directory1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedscan_file1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedscan_file_content1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedsearch_structures1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
  4. 8 tool updatesv0.19.4
    • First observedfind_divergence
    • First observedlist_directories
    • First observedpreview_directory
    • First observedscan_diff
    • First observedscan_directory
    • First observedscan_file
    • First observedscan_file_content
    • First observedsearch_structures

TDQS

B3.1/5.0

Scored across 13 tools

Disambiguation2/5

The scan/list/preview family (preview_directory, list_directories, scan_file_content, scan_file, scan_directory) shares nearly identical descriptions and differs only by subtle input-target or output-level details, making tool selection ambiguous. The remaining tools are more distinct, but the overlap among the scanning tools creates real boundary confusion.

Naming Consistency2/5

Names mix verb_noun forms (scan_file, search_structures) with bare nouns (surface, overlap, callers, history) and a lone verb (resolve). The scan_* prefix is consistent, but the broader set lacks a single predictable convention, and list_directories vs scan_directory adds further inconsistency.

Tool Count4/5

13 tools is a substantial but reasonable surface for a comprehensive code-analysis server, covering scanning, diffing, search, callers, history, and ref resolution. The count is slightly inflated by five overlapping list/scan/preview tools, but overall it remains within a well-scoped range.

Completeness4/5

The tool set covers orientation, scanning, search, diffing, branch overlap, callers, history, and symbol resolution, providing broad read-only code-analysis coverage. Minor gaps exist—such as raw full-file content retrieval and explicit definition lookup—but these are workable through existing skeleton and context tools.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables 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.
    4
    52
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Analyzes 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.
    2
    5 npm
    MIT