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: 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_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.

sct callers src/scantool/code_map.py

Given 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/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|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 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. 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. Answers: who calls this function; find usages and references of a function or method; which files import this file. 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

A3.9/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 output structure (enclosing function and path:line, definitions first), a limitation (definition binding not resolved, and the result says so), and scoping constraints (only actual call sites, not prose). It also ties to a statically resolved import graph, giving deeper context.

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 not wasteful—every sentence adds a distinct fact (scope, output, limitation, usage, shell alternatives). It's front-loaded with the core purpose and ends with practical invocation details. While slightly long, it is structured informationally and avoids redundancy.

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 main behavior, limitations, and usage for two of four parameters, and gives output hints. However, it leaves `ref` and `output_format` unaddressed, and since there is no output schema, the return format description is only partial. An agent would need to infer or probe to fully understand the tool's interface.

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 four parameters. It explains `name` (can be a function/method name or a file path) and `directory` via the shell example, but gives no information about `ref` or `output_format` (its purpose, allowed values, or defaults). This is a significant gap.

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 the tool's role with precision: it finds actual call sites of a function/method across a directory, explicitly excluding prose/comments/docstrings/string literals. It lists the exact questions it answers (who calls this, usages/references, file imports) and differentiates itself from the broader scanning siblings by focusing on call sites.

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 clear scenarios for when to use it ('who calls this function; find usages and references; which files import this file') and includes concrete shell invocations. It does not explicitly state when not to use it or name alternative tools, but the usage context is clear enough for an agent to decide.

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. Answers: functions that break a pattern their siblings follow; likely missed calls, as a review hint. 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 provided, the description carries the full burden of behavioral disclosure. It clearly states that the tool is a review hint, not a verified bug list, and that silence is a valid answer on consistent codebases. It also includes a CLI invocation hint. However, it does not explicitly mention side effects (though scanning is likely read-only) or error handling, which prevents a perfect score.

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 verbose and includes an extraneous shell command (sct --help) that is not essential for an MCP tool definition. The core explanation is clear, but the added CLI hint and repetitive phrasing ('functions that break a pattern their siblings follow' appears twice) make it less concise than it could be. A tighter version would front-load the core purpose and omit irrelevant instructions.

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 explains the tool's purpose, output (functions breaking patterns), and the special case of silence. It covers the essential context for a scan tool with three parameters. However, it lacks explicit guidance on when to use this tool versus similar siblings, and the inclusion of a CLI command that may not be applicable in all environments adds noise. Overall, it is adequate but 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?

The input schema has 100% description coverage for all three parameters (directory, max_findings, respect_gitignore), so the description does not need to add parameter details. The description does not provide additional semantic value beyond the schema, so the baseline of 3 applies. The shell command hint is unrelated to parameter semantics.

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 states the tool's purpose: finding peer divergence in a directory, specifically functions that break a call pattern their siblings follow. It gives a concrete example and distinguishes itself from a bug list, making it unambiguous. The verb 'find' and resource 'divergence' are specific, and it effectively communicates the core functionality.

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 it is for review purposes ('A review hint, not a verified bug list') and mentions it returns silence on consistent codebases, but it does not explicitly name alternatives or state when to use this tool versus siblings like scan_directory or search_structures. There is no clear 'when not to use' guidance, so the agent must infer usage context.

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. Answers: which commits changed this function or class, and when; git log or git blame for one function; how a function evolved across commits. 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.8/5.0
Behavior5/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, and it delivers. It explains precisely how the traversal works: signature/body changes are followed, renames are paired by identical body, file moves are followed, and commits touching the file but not the structure are counted but not listed. This is rich behavioral detail far beyond a generic 'history' statement.

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 includes valuable information like rename handling, file moves, and the Python fallback command, but the first sentence is grammatically awkward and hard to parse: 'One structure followed backwards through the commits that touched its file: ...' The structure is not front-loaded or scannable; the core purpose takes several sentences to emerge clearly.

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?

Given that there is no output schema and no annotations, the description provides a surprisingly complete picture: it explains what is followed, what is counted vs listed, and gives both common invocation forms including a fallback for when `sct` is not on PATH. It falls short only by not describing the output format (`tree` default) or the `repo` parameter, but the core usage context is well covered.

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 for the schema's silence. It does partially explain the `location` parameter through examples (`<path::name>` and `<path:line>`) and shows how to pass `--ref REF`. However, it does not explain `repo` or `output_format` at all, leaving 2 of 4 parameters undocumented in both schema and description.

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: track a code structure (function/class) backwards through commits, answering 'which commits changed this function or class, and when.' It uses a specific verb ('followed backwards') and a specific resource ('structure'), and the use-case list helps distinguish it from generic git/history tools. However, it does not explicitly distinguish itself from sibling tools like find_divergence or scan_diff, so it is not a 5.

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 use cases: 'which commits changed this function or class, and when; git log or git blame for one function; how a function evolved across commits.' This implies when to use the tool, but it does not state when not to use it or compare it with sibling tools. It offers shell invocation examples, which helps, but the usage guidance remains implicit rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_directoriesList DirectoriesC

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. Answers: read a file's contents; outline of a file; list the functions and classes in a file; read or show the source of one function, method or class by name. 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

C2.1/5.0
Behavior2/5

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

The description discloses some behavior, such as 'Elided content is marked ⟨…⟩ +N' and depth-based token budgets, but it is inconsistent (e.g., 'Skeleton of files' vs. 'Folders only, no files') and does not clarify side effects, permissions, or the exact output shape. With no annotations, the description carries full burden and fails to give a coherent behavioral picture.

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 long, rambling, and mixes tool-specific behavior with generic CLI usage instructions ('In your shell: sct --help'). It is not front-loaded; the core operation is buried in the middle. Every sentence does not earn its place, and the irrelevant CLI help paragraph should be removed.

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 3 parameters, no output schema, and no annotations, the description is severely incomplete. It does not explain what the returned tree looks like, how max_depth affects output, or how respect_gitignore changes behavior. The mention of elision markers is useful but not enough to make the tool safely callable.

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%, so the description must detail all three parameters (directory, max_depth, respect_gitignore) but does not. It vaguely mentions '--depth quick' and token budgets without mapping to the max_depth parameter, and it never addresses respect_gitignore. This is a critical gap for an agent to invoke the tool correctly.

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

Purpose3/5

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

The description suggests this tool lists a directory tree with one-line gists ('A directory gives the tree with one-line gists') and claims 'Folders only, no files', but it opens with a vague phrase about 'skeleton of files or a directory' that muddies the resource. It does not explicitly state the verb+resource in a focused way nor differentiate from siblings like scan_directory or preview_directory.

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?

No explicit when-to-use or alternative-selection guidance is provided. The 'Answers:' section lists general capabilities of an underlying CLI tool, not conditions for choosing this tool over its siblings. The only implicit hint is 'Folders only, no files', which is not framed as a decision rule.

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. Answers: do branches conflict or change the same functions; in which order to merge several branches; which commits two pull requests share. 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
partNo
pathNo
repoNo
branchesYes
output_formatNotree

TDQS

A4.1/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 transparency burden and does well: it explains output parts, base(~/+/-) markers, the patch-equivalence caveat, and that the result is a hint rather than a verdict. It does not explicitly state whether the tool is read-only, but the analytical framing implies no mutation.

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 long but dense, with no filler. The most important framing ('N branches against one base, each at its own merge-base') is front-loaded, and each sentence contributes semantic detail, caveats, or invocation instructions. The inline Python fallback is extra but useful.

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 tool with no output schema and no annotations, the description is quite complete: it names the output parts, explains markers and caveats, lists the questions it answers, and gives an invocation. The main gaps are the unexplained optional schema fields and the lack of a precise output shape beyond the first-line summary.

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 meaningfully clarifies the required base and branches parameters via the `sct overlap <base> <branch>...` syntax and maps `--part ID` to the part parameter. However, it leaves `kind`, `path`, `repo`, and `output_format` unexplained, which is a notable gap given the schema offers no descriptions.

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 defines what the tool does: it compares N branches against one base at each branch's own merge-base and reports structures touched by 2+ branches, shared commits, base containment, and a merge-order hint. This distinguishes it from single-branch diff or divergence siblings by emphasizing multi-branch conflict and ordering questions.

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 states concrete use cases: determining branch conflicts, deciding merge order, and identifying commits shared by pull requests. It also warns that the output is 'a merge-order hint, not a verdict.' It does not explicitly name alternative sibling tools or say when not to use this tool, so it falls short of full guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

preview_directoryPreview DirectoryA

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). Answers: an overview of a codebase or repository; where to start in an unfamiliar project; entry points and the most-called functions. In your shell: sct <dir> (if sct is not on PATH, "/app/.venv/bin/python" -m scantool.cli replaces sct).

ParametersJSON Schema
NameRequiredDescriptionDefault
partNo
depthNodeep
directoryYes
max_filesNo
max_entriesNo
respect_gitignoreNo

TDQS

A3.6/5.0
Behavior3/5

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

With no annotations, the description carries the burden. It discloses the output length (~3-5k tokens), the format (line one lists parts with line counts), and that it fetches one part alone via the 'part' parameter. It also reveals that the tool runs a shell command (sct) and provides the fallback invocation. This is helpful but does not disclose side effects (likely read-only) or error handling, which is acceptable for an orientation tool.

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 moderately sized and front-loads the core purpose. It is structured into a few sentences covering orientation, output format, use cases, and shell invocation. Some redundancy (e.g., repeating the fallback command) but generally efficient.

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?

Given the tool's complexity (6 params, no schema coverage, no output schema), the description provides a reasonable overview: output length, parts list, use case, and shell command. It lacks detailed parameter explanations (e.g., depth values) but provides enough to get an agent started. For an orientation tool that typically uses defaults, this is sufficient.

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 the 'part' parameter (to fetch one part alone) and mentions depth, max_files, max_entries implicitly through limits. However, it does not explain the exact semantics of depth (deep vs shallow), max_entries, or respect_gitignore beyond what the schema field names imply. The description adds minimal value for parameters beyond the 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 clearly states the tool provides an orientation overview of a codebase, including size, language mix, entry points, hot functions, and a call-graph map. This distinguishes it from sibling tools like scan_directory (which likely does a file tree scan) and list_directories (which lists directories). However, the description is somewhat abstract and could be more explicit in stating it previews a directory's structure and statistics.

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 states when to use this tool: for first-time orientation of an unknown codebase, not for targeted questions. It also contrasts with the file tree (which is the tier below via scan). It does not name a specific sibling alternative but implies that scan_directory is for the tree. This is clear guidance for typical use cases.

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). Answers: where a line or function is at another commit; map a line number from one commit to another. 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.9/5.0
Behavior3/5

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

With no annotations present, the description bears full responsibility for behavioral disclosure. It explains the core computation and possible outcomes (same place, renamed with identical body, or gone with nearest names), which is genuinely useful. However, it does not explicitly state that the operation is read-only, does not describe the response/output format, and does not discuss error cases, leaving meaningful gaps for a tool without annotation safety hints.

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 efficient: it defines the operation, the semantic outcomes, the use cases, and a concrete shell invocation, all in a few sentences. The command example is front-loaded with the core syntax and includes a fallback invocation, making every sentence earn its place without padding.

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 5-parameter tool with no output schema and no annotations, the description covers the essential semantics of location, ref_from, and ref_to, and handles the likely main use cases. But it omits repo and output_format entirely, and does not explain what the returned output looks like or what 'tree' format means. An agent could make the most common call correctly, but not all supported calls confidently.

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 the location input format ('path:line' or 'path::name') and illustrates --from/--to usage with shell examples, which maps well to ref_from and ref_to. However, repo and output_format are never mentioned, and the defaults (e.g., ref_to defaults to WORKTREE) are only implicitly suggested by the example. This is partial but not complete compensation for the empty schema.

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 'Translate' and the exact resource types ('path:line' or 'path::name'), then explains the mapping between refs. It differs clearly from sibling tools like find_divergence or search_structures by focusing on cross-commit location translation rather than scanning or diffing.

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 explicit use cases: 'where a line or function is at another commit' and 'map a line number from one commit to another', which tells an agent when to invoke it. It does not name alternative tools or exclusion conditions, so it lacks the explicit when-not-to-use guidance, but the context is clear enough for routing.

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. Answers: what changed between two commits or branches, per function; review the changes of a pull request or branch; local changes against HEAD, as structures rather than lines. 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.4/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. It discloses substantial behavioral details: the default merge-base behavior, the --no-merge-base alternative, per-file change categories (+/~/=/-), folding of identical signature deltas, skeleton files, coverage line behavior, and the --review flag being off by default. It doesn't mention performance or error behavior, but the disclosed behavior is rich and specific.

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 information-dense and front-loaded with the core diff semantics, but it is long and somewhat stream-of-consciousness. The shell command example at the end is useful but the sentence 'ref vs the working tree, or ref vs ref2; review=True appends the review tail' partially repeats earlier content. Every sentence carries information, but the structure could be tightened.

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?

Given the tool's complexity (7 params, no output schema, no annotations), the description is quite complete. It explains the diff modes, per-file change categories, the coverage line, the review feature, and provides shell usage. It doesn't document budget or output_format, but the core semantics an agent needs to select and invoke the tool are present.

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. It explains the core ref/ref2 semantics ('One ref = that ref vs the working tree', 'Two refs = A...B against their merge-base'), the review flag ('--review appends candidate dead/orphan/drift'), and no_merge_base ('--no-merge-base compares the tips'). It doesn't explicitly explain budget or output_format, but the most critical parameters are covered.

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 states the tool performs a structural diff between refs, with specific verbs and resources: 'Structural diff between refs', 'One ref = that ref vs the working tree', 'Two refs = A...B against their merge-base'. It distinguishes itself from git diff and sibling tools by focusing on per-function structural changes rather than line-level diffs.

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 when to use it: 'Use instead of git diff for review and what changed questions' and lists concrete use cases: 'what changed between two commits or branches, per function; review the changes of a pull request or branch; local changes against HEAD'. It also provides shell command examples with sct diff, which is actionable guidance.

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. Answers: read a file's contents; outline of a file; list the functions and classes in a file; read or show the source of one function, method or class by name. 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 provided, the description carries the full burden of behavioral disclosure, and it does substantial work: token-budget estimates per depth, elision marker '⟨…⟩ +N', tree output with code health and churn labels, and git-ref support via 'ref='. It does not mention side effects or permissions, but as a read-oriented scanning tool this is a minor gap rather than a fatal one.

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 front-loaded with the core concept, but it wanders into run-on sentences and repeats the directory-tree idea twice. The shell invocation is useful, but the overall paragraph would be clearer with bullets or separate sections for behavior, parameters, and usage.

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, this description is not complete enough. It covers depth, ref, elision, and high-level output shape, but leaves many parameters undefined, and does not explain mode, output formats, filtering, or metadata options. An agent would still need to guess or probe to use the tool fully.

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 the 12 parameters. It explicitly explains only depth and ref, and implies directory and directory-tree output. Parameters such as mode, pattern, delta, max_files, exclude_patterns, include_metadata, respect_gitignore, output_format, and caller are left completely undocumented. This is a significant semantic 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 clearly states what the tool produces: a skeleton of files with path:line, signatures/titles, and excerpts, or a directory tree with one-line gists. It also lists specific answerable questions (read file contents, outline a file, list functions/classes). However, it does not explicitly differentiate this tool from sibling tools like scan_file, scan_file_content, or preview_directory, so its boundary is slightly blurred.

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 concrete use cases: reading file contents, outlining files, listing functions/classes, and reading a function by name. It also says 'Replaces Glob/ls for all file types,' which signals when to prefer it. It lacks explicit when-not-to-use guidance or alternatives relative to the sibling set, so it does not fully meet the highest bar.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

scan_fileScan FileA

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). Answers: read a file's contents; outline of a file; list the functions and classes in a file; read or show the source of one function, method or class by name. 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
body_onlyNo
file_pathYes
output_formatNotree
show_complexityNo
show_decoratorsNo
show_docstringsNo
show_signaturesNo
include_metadataNo

TDQS

A3.5/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 of behavioral disclosure. It explains output shape (skeleton/tree with path:line and gists), token budgets per depth, elision marker '⟨…⟩ +N', focus behavior, body_only, ref, and the conditional connectivity note. It does not discuss errors or side effects, but for a read/scan-style tool this is substantial disclosure.

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 one long dense paragraph with many stacked clauses, making it information-heavy but not easy to scan. It does front-load the core concept and ends with a useful CLI invocation, but it would benefit from clearer segmentation or bullet-style structure.

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 16-parameter tool with no annotations and no output schema, the description covers key use cases, budget semantics, focus behavior, and output elision, which is reasonably complete. However, several parameters remain underspecified and the directory-mode overlap with scan_directory is not resolved, leaving notable gaps.

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 for all 16 parameters. It adds real semantics for depth, budget, focus, body_only, and ref, but leaves many parameters like delta, condense, caller, output_format, and the show_* family unexplained. Some are inferable from their names, but the compensation is incomplete.

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?

States a specific verb and resource: scanning a file/directory to produce a skeleton with line numbers, signatures or titles, and condensed excerpts. It is clear about what it returns and even lists the questions it answers, but it does not explicitly differentiate from sibling tools like scan_file_content or scan_directory, and it admits both file and directory targets despite its name.

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 'Answers:' enumeration gives concrete use cases such as reading file contents, outlining a file, listing functions/classes, and reading a single source node. It also mentions exploration vs quick-look budgets. However, it never explicitly says when to prefer this tool over its many siblings or what exclusions apply, so the guidance is implied rather than explicit.

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. Answers: read a file's contents; outline of a file; list the functions and classes in a file; read or show the source of one function, method or class by name. 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
body_onlyNo
output_formatNotree
show_complexityNo
show_decoratorsNo
show_docstringsNo
show_signaturesNo
include_metadataNo

TDQS

A3.7/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 disclosure burden and does substantial work: it explains output shape (skeleton, path:line, directory tree gists), elision marker '⟨…⟩ +N' and focus behavior, and per-depth token budgets (quick 300, normal 1500, deep). It omits edge-case behavior like error handling or network failures, but the core read-only 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.

Conciseness3/5

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

The description is dense and every clause adds information, but it is a single run-on paragraph that mixes output format, budgets, elision, use cases, and shell commands without clear separation. The opening phrase 'Skeleton of files or a directory' is confusing as a purpose statement and reduces clarity.

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 14 parameters, no output schema, and no annotations, the description covers the core use cases and key behavioral parameters but leaves many schema fields and edge behaviors unaddressed. An agent can likely call the tool for reading or outlining directly supplied content, but would be guessing about output_format variants, condense behavior, and the display toggles.

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 meaningfully explains depth (quick/normal/deep with token approximations), budget, focus, and indirectly content and filename via 'Content given directly' and the `--as <path>` CLI form. However, most optional toggles—mode, condense, body_only, output_format, show_*, include_metadata—are left unexplained, so compensation is only partial.

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 action as scanning directly supplied content and extracting structural information: 'every structure with path:line, signature or title' and the 'Answers:' list covering read contents, outline, list functions/classes, and show source by name. It distinguishes from scan_file by noting that 'content [is] given directly' rather than via filesystem path, though it does not explicitly name the sibling as the alternative.

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 clear context for when to use this tool: when content is supplied directly from remote files, APIs, git blobs, or stdin. It also provides concrete shell invocations (`sct scan - --as <path>`, `sct focus - --as <path> <name>`) and explains depth/budget behavior, but it does not explicitly say when not to use it or directly contrast it with scan_file/scan_directory.

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; an empty answer names the paths that match and what the other reading finds (the pattern as text, or as names). 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. Answers: find where a function or class is defined; find text in code across files. 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.4/5.0
Behavior5/5

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

With no annotations provided, the description carries the full transparency burden and discharges it thoroughly: it discloses match semantics (Python regex, grep `\|` read as alternation with a note), edge-case behavior (empty answer names paths and the alternate reading; no-lead cases are explicitly stated), output shape (one row per structure, decorators on the row), pagination (40 per page, page stated, --limit/--offset), and git-ref search. This far exceeds what annotations would typically provide.

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 a single dense run-on paragraph with no internal structure and noticeable repetition (the content_pattern vs name_pattern/type_filter/has_decorator distinction is stated twice). Every sentence does carry information, and the core purpose is front-loaded, but the wall-of-text format imposes a heavy parsing burden on the agent.

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 an 11-parameter tool with zero schema descriptions, no annotations, and no output schema, the description is remarkably complete on the main search paths: modes, filters, pagination, regex semantics, edge cases, and shell invocation are all covered. It is not a 5 because three parameters (output_format, min_complexity, include_metadata) remain undefined and the CLI-flag phrasing requires the agent to infer the schema-property mapping.

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 coverage is 0%, so the description is the sole source of parameter meaning, and it does explain the behavioral core: content_pattern, name_pattern, type_filter, has_decorator, limit/offset, and ref all receive semantic content including their interplays (e.g., --decorator only operates with --names). However, it uses CLI flag names rather than schema property names (--names vs name_pattern, --type vs type_filter), forcing the agent to infer the mapping, and it leaves output_format, min_complexity, and include_metadata completely unexplained.

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 a specific job — searching text across a directory or single file and returning hits with enclosing structural context plus leads to definitions. It also positions the tool against alternatives ('Best first call for a targeted question; use instead of Grep') and enumerates its two answer types: finding where a function/class is defined and finding text in code. The verb-resource-scope combination is unambiguous despite the fragment-style opening sentence.

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?

Explicit when-to-use guidance is present: 'Best first call for a targeted question; use instead of Grep,' followed by the specific question types the tool answers. It stops short of a 5 because it names no sibling tool in the current toolset and gives no when-not-to-use exclusions (e.g., when a plain content scan via scan_file_content 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.

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. Answers: the public API of a package or module; exported names and where each is defined; API changes between two versions. 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
partNo
againstNo
package_dirYes
output_formatNotree

TDQS

A4.5/5.0
Behavior4/5

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

The description discloses several behavioral traits: it looks through namespaces/modules, applies language-specific export rules, and supports diffing with --against. It also explains the output structure (header with direction and parts, line counts). However, it doesn't mention potential side effects or performance characteristics, though as a read-only analysis tool this is less critical. No annotations are provided, so the description carries the full burden, and it does a good job.

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 well-organized, front-loading the core purpose and then explaining the diff mode and use cases. It's longer than ideal but every sentence adds value, covering language-specific rules, output structure, and shell usage. The structure could be slightly improved by separating the diff explanation from the core purpose, but it's still effective.

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?

Given the tool's complexity (5 parameters, no output schema, no annotations), the description is quite complete. It explains the main use cases, the diff mode, and even provides shell invocation examples. It doesn't detail the exact output format for the tree mode, but the description of 'every exported name with its signature, how it is exported and where it is defined' gives a clear picture. The main gap is the lack of explicit parameter descriptions for output_format and part, but these are partially covered.

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. It explains the key parameters: package_dir (the package directory), ref (the ref to analyze), against (the ref to diff against), and part (which part of the diff to print). It doesn't explicitly explain output_format, but the default 'tree' is implied by the description's focus on structure. This is strong compensation for the lack of schema descriptions.

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 states the tool's purpose: it shows the public surface of a package directory at a ref, including exported names, signatures, export mechanism, and definition location. It also distinguishes itself from siblings by focusing on the public API surface rather than general file/directory scanning or diffing.

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 explains when to use this tool: to answer questions about a package's public API, exported names, and API changes between versions. It also provides concrete shell usage examples and mentions the --against flag for diffs, which helps an agent decide when to use this tool versus alternatives like scan_diff or find_divergence.

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. 5 tool updatesv0.28.0
    • Changedoverlap1 field changed
      • addedInput schema / properties / part
        Added value: +{
        +  "default": "",
        +  "type": "string"
        +}
    • Changedpreview_directory1 field changed
      • addedInput schema / properties / part
        Added value: +{
        +  "default": "",
        +  "type": "string"
        +}
    • Changedscan_file1 field changed
      • addedInput schema / properties / body_only
        Added value: +{
        +  "default": false,
        +  "type": "boolean"
        +}
    • Changedscan_file_content1 field changed
      • addedInput schema / properties / body_only
        Added value: +{
        +  "default": false,
        +  "type": "boolean"
        +}
    • Changedsurface1 field changed
      • addedInput schema / properties / part
        Added value: +{
        +  "default": "",
        +  "type": "string"
        +}
  2. 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
  3. 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"
        +}
  4. 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
  5. 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.2/5.0

Scored across 13 tools

Disambiguation3/5

Several tools overlap heavily: scan_file, scan_file_content, scan_directory, and list_directories all share nearly identical descriptions about scanning files/directories with depth budgets, making it hard to distinguish their exact purposes. Other tools like preview_directory, search_structures, and callers are more distinct, but the scanning cluster creates real ambiguity.

Naming Consistency3/5

Most tools use a verb_noun pattern (preview_directory, scan_file, search_structures, find_divergence), but the pattern is inconsistent: 'list_directories' vs 'scan_directory' for similar operations, and bare nouns like 'surface', 'overlap', 'callers', 'history', 'resolve' break the verb-first convention. The naming is readable but not predictable.

Tool Count4/5

13 tools is within a reasonable range for a code-scanning/analysis server covering preview, scan, search, diff, history, and API surface operations. A few tools (list_directories, scan_file_content) feel redundant with scan_file/scan_directory, so the count is slightly high but not excessive.

Completeness4/5

The toolset covers the core codebase exploration lifecycle well: orientation (preview_directory), file/directory scanning, structural search, callers, history, diff, divergence, and API surface. Minor gaps exist—there's no explicit tool for writing/editing files (though that may be out of scope) and no direct 'get file at ref' tool separate from scan_file's ref parameter—but the surface is largely complete for read-only analysis.

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
    3 npm
    MIT