skim-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@skim-mcpskim main.py"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
skim
Token-efficient skim-then-expand I/O for agentic models (Claude Code / desktop Claude).
Independent community project — not affiliated with, endorsed by, or sponsored by Anthropic. No telemetry; runs entirely on your machine. See Trademarks, privacy & license.
Instead of reading a whole large file into context, the model calls skim_open(path) and gets a
compact skeleton — structure, signatures, and (for logs/data) preserved critical values like ids,
numbers, dates, and error codes — plus anchor ids. It reads the skeleton cheaply, then calls
skim_expand(handle, anchors=[...]) to pull only the exact spans it needs, verbatim and lossless.
Compression is lazy, not lossy: nothing is paraphrased or destroyed, only deferred. Expansion is always one call away — which is what makes it safe for a closed model that can't ingest latent vectors.
What it does that other tools don't
The mainstream tools are lossy in context — repo-maps and --compress drop function bodies;
summarizers and compression models paraphrase. The closest neighbors either cover code only, or show
the model a transformed view and keep originals in a side cache. skim's line is stricter: whatever
lands in context is verbatim source, and everything not shown is one anchored expand away — an agent
can edit code from what it read without re-reading. That holds everywhere:
Files — Python (
ast) + ~17 languages (tree-sitter); bodies folded, oneexpandaway.Whole repos —
skim_repobuilds a ranked, token-budgeted map; expand exact code from any file.Command output —
skim_runcompresses verbose test / build / log output, fully recoverable.Data & logs — a generic path with a retention guarantee (ids, numbers, error codes, negations are promoted into the skeleton, never silently dropped) and dedup of repeated blocks.
See DESIGN.md for the architecture and verified prior-art positioning.
Related MCP server: graphpilot
Falsifiable, not claimed
A reduction percentage is marketing until you can check it. skim ships the checker:
uv run skim-verify path/to/your/gnarliest_file.py # any file at all; exit code tells CIFive invariants, verified on your files, locally: every non-blank line recoverable, expands
byte-exact, anchors in-bounds, reconstruction equal to the decoded file, deterministic output. The
test suite enforces the same contract with Hypothesis fuzzing on every path; a reproducible FAIL
on any readable file is a bug — please report it. Summarize-first tools cannot ship this command,
because for them the equivalent check fails by design.
The cost-vs-correctness question has its own open yardstick — eval/ACCURACY.md prices every eval question under a full read vs skim (including the rows where skim loses), and any other context tool can be scored under the same protocol.
Built to be audited
Under 2,000 lines of stdlib Python for the whole package (the reading engine is ~1,200) — no ML models to download, no framework, no telemetry, dependency surface of one (
mcp, plus optionaltiktoken/tree-sitter extras). An afternoon's security review covers all of it: SECURITY.md is the threat model.A kill switch for every surface that isn't read-only:
SKIM_RUN_DISABLED=1removes the shell tool,SKIM_PATCH_DISABLED=1removes the file editor; the readers keep working.Windows is a first-class platform, not a port: command output decoded as UTF-8 (no cp1252 mojibake), process trees actually killed on timeout (
taskkill /F /T), CRLF preserved byskim_patch, and CI runs the full suite onwindows-latestalongside Ubuntu.
Try the core (no install)
python demo.py path/to/file.py # measured before/after token counts
python demo.py # demo on examples/sample.log (retention + dedup)Results (hard data)
Every number below is generated live by uv run python benchmarks.py — full reproducible tables in
BENCHMARKS.md. Measured on the running interpreter's standard library (real code);
token counts via tiktoken cl100k_base (a proxy for Claude's tokenizer; ratios are tokenizer-robust).
Token savings on real code — 60 Python stdlib files: 387,911 → 122,660 tokens (68% fewer, 3.16×); per-file 1.5×–11×; 100% lossless, deterministic; ~linear runtime (~4 ms / 1k lines); pure CPU, no GPU, no network, no model calls.
Multi-language (tree-sitter, [lang] extra) — the same lossless engine on JS / TS / Go / Rust /
Java / C / C++ / Ruby / PHP / C# and more. Example: a 481-line JavaScript module → 6.6× / 85% saved, lossless.
1:1 before/after on a real task (distribution-level) — "read the largest function in this module"; the model opens the file, reads the skeleton, expands exactly the one function it needs. Same answer, full skim cost (skeleton + expand) counted, across 24 large modules:
file | lines | function read | full read | skim (skeleton+expand) | saved |
| 3,032 |
| 25,180 | 8,906 | 65% |
| 1,682 |
| 12,830 | 5,610 | 56% |
| 1,436 |
| 11,242 | 5,421 | 52% |
| 921 |
| 7,279 | 3,243 | 55% |
| 864 |
| 5,824 | 3,615 | 38% |
24-file total | 176,897 | 71,877 | 59% |
Per-task savings: median 51%, mean 51%, range 30–91% across 24 tasks — the honest distribution, not a cherry-picked best case. The win shrinks when you need most of a file.
Head-to-head — same 30 files (compare.py + real Repomix via npx):
approach | tokens | % of full | lossless? |
full read (Claude | 184,277 | 100% | yes |
skim | 64,043 | 34.8% | yes (lazy-expand) |
Repomix | 105,963 | 57.5% | no (bodies dropped) |
signatures-only (Aider/Basemind mechanism) | 20,276 | 11.0% | no |
skim is the only lossless option and uses 40% fewer tokens than Repomix --compress. The repo-map
approach is ~3× smaller but discards bodies/docstrings/comments irreversibly. (Basemind is pure Rust and
wasn't installed; its row reproduces the signatures-only mechanism — see COMPARISON.md.)
Correctness: 0 of 54,215 non-blank lines unrecoverable across 80 files; 202 tests / ~80% coverage with
Hypothesis property fuzzing of both paths; an ~18,000-case adversarial campaign (every bug found is fixed
and regression-locked). Reproduce: uv run python bench.py / pytest / benchmarks.py.
Run as an MCP server
The one-liner (installs from PyPI on first run, tree-sitter languages included):
claude mcp add skim -- uvx --from "skim-mcp[lang,tokens]" skim-mcpOr from source:
git clone https://github.com/helloderekg/skim-mcp.git && cd skim-mcp
uv sync --extra lang # MCP SDK + multi-language (tree-sitter); drop --extra lang for Python-onlyRegister with Claude Code (use the repo's absolute path; forward slashes work on Windows):
claude mcp add skim -- uv run --directory /abs/path/to/skim-mcp skim-mcpOr Claude Desktop — add to claude_desktop_config.json (%APPDATA%\Claude\ on Windows,
~/Library/Application Support/Claude/ on macOS), then restart:
{
"mcpServers": {
"skim": {
"command": "uv",
"args": ["run", "--directory", "/abs/path/to/skim-mcp", "skim-mcp"]
}
}
}(If uv isn't found, use its full path from where uv / which uv.)
Tools
skim_open(path, query="")→ compact skeleton + anchor ids (read the skeleton; ids are in itsexpand("aN")markers). Passqueryto also getmatches(line + covering anchor) in the same call, no search round-trip.skim_expand(handle, anchors=[...])→ exact verbatim spans. Items are anchor ids ("a7") or literal line ranges ("L120-180") for when a grep already gave you line numbers.skim_search(handle, query)→ which anchors/lines contain a string, without reading them.skim_run(command)→ run a shell command, get a compact expandable view of its output (tests / builds / logs).skim_repo(path, query)→ a lossless, ranked, token-budgeted map of a whole repo; expand exact code from any file. Ranked by query match when you pass one, else by import-graph centrality (PageRank over which files import which), so the load-bearing modules surface first.skim_patch(handle, anchor, new_text)→ replace exactly one expanded span on disk, drift-safe: refused if the file changed sinceskim_open, LF/CRLF preserved, result re-verified from disk, fresh handle returned. Because expands are verbatim, an edit built from one applies safely — read 8% of the file, edit it anyway. (SKIM_PATCH_DISABLED=1turns it off.)Spans are also MCP resources:
@skim:skim://doc/<handle>/span/<anchor>pulls a span by reference.
What it looks like in practice
Fix a bug in a big module you barely need. The task: "why does _proc_pax mishandle pax
headers?" in tarfile.py (3,032 lines, 25,180 tokens). Claude calls skim_open, reads a
skeleton with every signature, spots _proc_pax, expands that one anchor, and answers from the
exact 119-line body. Measured cost: 8,906 tokens including the skeleton and the expand. Same
answer, 65% fewer tokens (see the benchmark table — median across 24 such
tasks is 51%).
Get your bearings in an unfamiliar repo. skim_repo(".", query="rate limit") returns the
most relevant files' skeletons, ranked, inside one token budget, each with its own handle. Claude
reads the map, expands the two functions that matter from two different files, and starts editing
with the rest of the repo still unread but reachable.
A red CI run with 400 lines of noise. skim_run("pytest -q") returns the exit code plus a
compact view: repeated boilerplate collapses to "identical to a3" pointers, and the retention
layer promotes the load-bearing literals (error codes, file paths, counts) into view so the
failure is visible without expanding anything. When Claude needs the full traceback, it expands
that one block.
When not to skim (honesty). A 40-line config file, or a file you're about to rewrite wholesale: just read it. The skeleton wrapper costs more than it saves on tiny inputs, and the meter will show those rows as negative rather than hiding them. skim's win is the everyday case where you need 40 lines out of 2,000.
Getting Claude to use skim
Mounting skim makes the tools available — it does not make Claude use them. Claude picks a tool per
task, and its default for "read/review this file" is the built-in Read, not skim_open. Smaller
models (e.g. Haiku) are especially unlikely to reach for an MCP tool on their own. So skim saves tokens
only when it's actually invoked. Two ways to get there:
1. Ask for it, per task:
Use skim to review
src/big_module.pyMap this repo withskim_repobefore you start Run the tests throughskim_run
2. Make it automatic — add a rule to your CLAUDE.md (a project one, or global ~/.claude/CLAUDE.md)
so Claude reaches for skim without a reminder every turn:
When the skim MCP tools are available, prefer skim_open (files) and skim_repo (directories/repos) over
the built-in Read for anything larger than ~300 lines, and skim_run for verbose command output. Expand
only the spans you need — skim is lossless, so skimming first is never risky, only cheaper.skim also ships a "prefer skim" instruction to the model, but models don't reliably act on server-level
instructions — the CLAUDE.md rule is what pulls hard enough, especially for smaller models. You can
confirm it's wired up any time: tell a session "use skim to open <a big file>" and watch the
meter tick.
Or let skim do both steps — registration and the rule — in one idempotent command:
uv run skim-mcp install # from a source checkout (project ./CLAUDE.md rule)
uvx --from "skim-mcp[lang,tokens]" skim-mcp install # from PyPI
skim-mcp install --rule global # write the rule to ~/.claude/CLAUDE.md instead
skim-mcp install --print-only # show what it would do, change nothingRe-running never duplicates the rule; if the claude CLI isn't on PATH it prints the exact manual
command and the Claude Desktop JSON instead.
See your savings live
Mount skim, then run the meter in a second terminal — a tiny localhost dashboard (pure stdlib, no
network, no deps) that reads the same skim_calls.jsonl the server writes and refreshes every second:
uv run skim-meter # -> http://127.0.0.1:17321
uv run skim-meter --once # one-shot text snapshot instead of the web view
uv run skim-meter --price-per-mtok 3 # optional: also show ~dollars saved at YOUR rateIt shows, in real time: tokens in (what reading those files / running those commands in full would
have cost), tokens out (what skim actually put into context — skeletons plus every expand/search),
and % saved = 1 - out/in, broken down by session. It's honest — expands eat into the number,
and a skim_run on a tiny output can even net negative.

Per session: every skim server process stamps a session id on each call, and Claude Code spawns one
process per session — so the dashboard lists every session (even before it has used skim), sorted by
last activity. Each row is labeled by your SKIM_SESSION_LABEL if you set one, else by the first
file/repo that session touched (else idle), alongside its start time and short id so you can tell
them apart. A Clear button (or skim-meter --clear) archives the log to a timestamped ghost file and
resets the meter to zero — nothing is lost. (MCP doesn't tell the server which sub-agent issued a call,
so per-connection/session is the finest split available server-side.)
Tests
uv sync --extra dev
uv run pytest # unit + property-based fuzzing of the invariants (202 tests, ~80% coverage)
uv run python bench.py # invariant sweep + compression over the standard library
uv run python check_invariant.py <file> # check one file against the invariantsThe suite enforces six invariants for any input — lossless, round-trip-exact, reconstruction-exact
(full_text equals the decoded file byte-for-byte), in-bounds, deterministic, never-crash — via
hand-written edge cases, the real standard library, and Hypothesis fuzzing of both the code and
generic paths.
Measure the expand-loop yourself: eval/QUESTIONS.md is a 7-question
under-fetch eval (every answer hidden behind an anchor, locked by a test);
uv run python eval/score_expand_loop.py scores a real session's log against it, and
eval/ACCURACY.md prices each question (full read vs skim, negatives included) —
the accuracy-vs-cost yardstick other context tools are invited to run against.
Limitations (honest)
Code skeletons cover Python (
ast) + ~17 languages via tree-sitter — JS, TS, Go, Rust, Java, C, C++, Ruby, PHP, C#, Kotlin, Swift, Scala, Bash, Lua, R. Install the optional[lang]extra; other text falls back to the generic (lossless) block path. The long tail of ~300 tree-sitter grammars is incremental (each language's folding is verified against real parses before it ships).Dense repetitive logs get Drain-style templates (
~412x GET /api/<*> took <*>ms) so the skeleton shows what repeats; structured JSON/CSV skeletons are still roadmap, so compression there is modest.It depends on the model calling
expand. If the model answers from the skeleton when it needed a collapsed body, it can be wrong. A steering hint mitigates this;skim_calls.jsonllets you measure it.Functions defined inside
if/tryblocks aren't shown as signatures (still lossless and expandable).skim_runruns shell commands on your machine (to capture and compress their output), with the privileges of the server process — the same capability class as an agent's Bash tool. Mount skim only where you'd let an agent run commands; a prompt-injected model could invoke a destructive command. SetSKIM_RUN_DISABLED=1to mount skim read-only (the shell tool refuses, the readers keep working). Full threat model in SECURITY.md.Handles live in the server process's memory. They last the session (Claude Code runs one skim process per session); after a restart an old handle returns a clean
unknown handleerror — re-open. Handles are content-hashed, so a re-opened changed file gets a new handle and stale anchor ids can never silently point at different lines.Savings depend on usage: large on big files you read part of, a wash on small files or when you need most of a file. Token counts use tiktoken (a proxy for Claude's tokenizer); ratios are robust.
Status & roadmap
Shipped: Python ast + multi-language tree-sitter code skeletons (~17 languages, each verified
against real parses), a generic block path with retention + dedup + Drain-style templating for dense
logs, skim_run (lossless command/test-output compression with process-tree-safe timeouts),
skim_repo (whole-repo lossless map, ranked by query match or import-graph PageRank), spans as MCP
resources, an under-fetch eval harness, and skim-meter (a live token-savings dashboard) — all behind
an airtight test suite.
Roadmap: a structured-data skeleton for JSON/CSV (schema + value stats), the long tail of tree-sitter languages, a hybrid push mode (auto-expand the top relevance-ranked anchor) if the under-fetch eval shows models leaving answers on the table, and runner adapters so other context tools can be scored on the accuracy-vs-cost yardstick.
Contributing, security, changelog
CONTRIBUTING.md has the five invariants every change must keep (lossless, round-trip exact, in-bounds, deterministic, never-crash) and how to add a language. SECURITY.md is the threat model and how to report privately. CHANGELOG.md tracks releases; RELEASING.md is the release process.
Trademarks, privacy & license
Independent project. skim is a community open-source project, not affiliated with, endorsed by, or sponsored by Anthropic PBC, OpenAI, or any other company. "Claude", "Claude Code", and "Anthropic" are trademarks of Anthropic, PBC; "Model Context Protocol" / "MCP" are used descriptively to indicate protocol compatibility; "Aider", "Basemind", and "Repomix" are trademarks of their respective owners. All marks are used nominatively, for identification and comparison only, and imply no endorsement. No third-party logos are used.
Benchmarks. Figures in this repo are measurements under the documented conditions (tool versions, flags, corpus, token counter, date), reproducible via the published scripts — not guarantees under other conditions. Comparative figures for Aider, Basemind, and Repomix were produced with their then-current public releases; corrections welcome via an issue.
Privacy & telemetry. skim runs entirely on your machine. It makes no network requests and collects,
transmits, or sells no data. The only data written is a local skim_calls.jsonl log (skim tool calls —
file paths and span anchors — for your own debugging); it never leaves your computer. Delete it anytime, or
set SKIM_LOG_FILE to redirect it. It may contain paths/snippets from your own files; treat it like any local log.
License. MIT. Runtime deps mcp (MIT, © Anthropic PBC) and tiktoken (MIT, © OpenAI) — see
NOTICE. The dev-only test dep hypothesis is MPL-2.0, used unmodified and never bundled.
mcp-name: io.github.helloderekg/skim-mcp
Available Tools
6 toolsskim_expandA
Return exact, verbatim source lines for one or more anchor ids from a skim_open result.
Items can be anchor ids ("a7") or literal line ranges ("L120-180", 1-based inclusive) - ranges work even for lines shown in the skeleton, e.g. when a grep gave you line numbers.
| Name | Required | Description | Default |
|---|---|---|---|
| handle | Yes | ||
| anchors | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It only states it returns exact verbatim lines and that ranges work for skeleton lines. It does not disclose error behavior, prerequisites beyond a handle, or idempotency. Minimal behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences: the first states the core purpose, the second adds details on input types. Every sentence is necessary, no fluff. Front-loaded with key information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (2 string parameters, no output schema). The description covers what the tool returns and acceptable inputs, but lacks details on handle validity, error handling, or ordering. It is adequate but not fully complete for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description explains the 'anchors' parameter can be anchor ids or literal line ranges, adding meaning beyond the schema. However, the 'handle' parameter is not described (only implied from context), and schema coverage is 0%, so the description partially compensates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns exact verbatim source lines for anchor ids from a skim_open result. It specifies the verb 'return' and resource 'source lines', and distinguishes from siblings by mentioning skim_open as the source.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool should be used after skim_open by referencing 'from a skim_open result', and explains acceptable input types (anchor ids or line ranges). However, it does not explicitly state when not to use it or mention alternatives like skim_search.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
skim_openA
Open a large file and return a compact skeleton + expandable anchor ids (not the full text).
Returns handle, report (token counts + compression ratio), skeleton (read this), and anchors
(ids you can expand). Use instead of reading a whole large file when you only need parts.
Collapsed bodies are NOT in the skeleton - expand the anchor when the answer needs the body.
Pass query to also get matches (which lines/anchors contain it) in the same call,
saving a skim_search round-trip when you already know what you're looking for.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| query | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, description fully discloses behavior: returns handle, report (token counts + compression ratio), skeleton, anchors; notes collapsed bodies not in skeleton; explains query usage for matches.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise two-paragraph description with front-loaded purpose. Every sentence adds value: purpose, return values, usage advice, collapsed bodies clarification, query optimization. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 2 parameters, no output schema, and no annotations, description is highly complete: covers return values, behavior, usage, query optimization, and distinguishes from siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but description adds meaning: path is file path, query is optional to get matches in same call. Could be more explicit but sufficient for agent understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it opens a large file and returns a compact skeleton with expandable anchor ids, not full text. Distinguishes from sibling tools like skim_expand (expand anchors) and skim_search (search).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to use instead of reading whole large file when only parts needed. Suggests passing query to avoid extra round-trip to skim_search. Provides clear when-to-use and when-not-to guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
skim_patchA
Replace exactly one anchored span (or literal "L-" range) of a skimmed file on disk.
This is what verbatim-in-context buys: the span you expanded IS what the file contains, so an edit built from it applies safely. Expand the span first, edit that exact text, then patch. The write is refused if the file on disk no longer matches this handle's snapshot (drift -> clean error; re-open and rebuild the patch). Newline style (LF/CRLF) is preserved, the result is re-skimmed and verified, and a fresh handle for the new content is returned. Set SKIM_PATCH_DISABLED=1 to turn this tool off for read-only mounts.
| Name | Required | Description | Default |
|---|---|---|---|
| anchor | Yes | ||
| handle | Yes | ||
| new_text | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses drift detection, newline preservation, re-skimming verification, fresh handle return, and the disable flag. This is comprehensive for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise yet thorough. First sentence immediately states purpose, followed by workflow, conditions, and behavioral details. No superfluous sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and moderate complexity, description covers error conditions (drift), side effects (newline preservation, re-skimming), and returned handle. Also mentions the environment variable for disabling. Very complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so description must compensate. It partially explains 'anchor' as 'anchored span (or literal range)', but handle and new_text are not explicitly described beyond context. Could be improved with direct parameter explanations.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description explicitly states the action: 'Replace exactly one anchored span (or literal range) of a skimmed file on disk.' It clearly distinguishes from sibling tools like skim_open, skim_expand, etc., by specifying it is for patching a specific span after expansion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit workflow guidance: 'Expand the span first, edit that exact text, then patch.' Also explains when the tool refuses (drift) and how to handle it ('re-open and rebuild the patch'), plus the environment variable to disable it for read-only mounts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
skim_repoA
Build a LOSSLESS, ranked, token-budgeted map of a whole repo/directory.
Returns each code file's skeleton (signatures + structure, bodies folded), ranked by relevance to
query (or by size if no query), trimmed to budget_tokens. Every file gets a handle, so
skim_expand(handle, anchors=[...]) returns exact code from any file. Files that didn't fit are listed
by name so you can skim_open them individually. Use to understand a codebase cheaply, then expand.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| query | No | ||
| max_files | No | ||
| budget_tokens | No |
TDQS
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 that the tool returns skeletons (bodies folded), ranks by query or size, trims to budget_tokens, and lists excluded files. This gives a good understanding of behavior without contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, about four sentences, with the main purpose front-loaded. Each sentence adds meaningful information without fluff, earning its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations, no output schema, and 0% schema coverage, the description provides a decent overview but lacks details on supported file types, error handling, or output format. It is minimally viable but has gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must explain parameters. It mentions query and budget_tokens implicitly but does not define them clearly. 'max_files' is not mentioned at all. Path is implied but not explained. The description adds minimal value beyond the schema structure.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool builds a lossless, ranked, token-budgeted map of a repo/directory. It specifies the output (skeleton of files, handles for expansion) and distinguishes from siblings like skim_expand and skim_open.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly advises using this tool to understand a codebase cheaply, then expand with skim_expand. It mentions using skim_open for files not included, providing clear context for when to use this tool vs alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
skim_runA
Run a shell command and return a COMPACT, expandable view of its output instead of the full dump.
For verbose commands (test runs, builds, npm/pip, big logs): the skeleton shows the shape with critical lines (errors, codes, numbers) preserved and repeated blocks deduped; skim_expand(handle, ...) pulls exact output spans. Nothing is lost. Returns exit_code + a token report. Runs on your machine.
| Name | Required | Description | Default |
|---|---|---|---|
| command | Yes | ||
| timeout | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully explains behavioral traits: output is compact, deduped, nothing lost, returns exit_code and token report, and runs on the user's machine. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is fairly concise but could be tighter. It has two paragraphs with useful information, though some redundancy exists (e.g., 'compact' repeated).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no annotations, the description covers the main purpose and behavior but lacks parameter details and output structure beyond exit_code and token report. Error handling or security considerations are omitted.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%; the description does not add meaning to the parameters. It mentions 'command' but lacks details on format or timeout, leaving the agent uninformed about parameter specifics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool runs a shell command and returns a compact, expandable view. It distinguishes from siblings like skim_expand, which is mentioned for expanding output.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives guidance for verbose commands (test runs, builds, npm/pip, big logs) and mentions skim_expand for expansion, but does not explicitly state when not to use this tool or provide alternative tools for non-verbose cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
skim_searchA
Find which anchors/lines contain query (case-insensitive) without reading the whole file.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| handle | Yes | ||
| max_results | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. Mentions case-insensitive search and efficiency, but omits details like result format (e.g., line numbers) or max_results behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, 10 words, front-loaded with purpose. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, yet description does not indicate what results contain (e.g., matched lines, positions). Missing guidance on interpreting output, essential for a search tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description only adds value for 'query' parameter. 'handle' and 'max_results' are not explained, leaving significant gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the verb 'find' and the resource 'anchors/lines' with the specific behavior 'case-insensitive' and efficiency 'without reading the whole file'. Distinguishes from sibling tools like skim_open and skim_expand.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implicitly suggests use for quick searches without reading full file, but lacks explicit when-to-use or when-not-to-use statements. Sibling names provide some context for alternatives.
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. Dates show when Glama detected each change.
6 tool updates
v0.1.1- First observed
skim_expand - First observed
skim_open - First observed
skim_patch - First observed
skim_repo - First observed
skim_run - First observed
skim_search
TDQS
Each tool targets a distinct operation: opening files with skeleton, expanding anchors, searching, running commands, mapping repos, and patching. No functional overlap exists.
All tools follow a consistent 'skim_verb' pattern using snake_case, making the set predictable and easy to navigate.
With 6 tools, the server is well-scoped for its purpose of compact file/repo exploration and editing. Each tool adds clear value without redundancy.
The core workflow (open, search, expand, run, map, patch) is covered, though a tool to close/discard handles is missing—minor gap for an otherwise complete surface.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Memory that reasons: continual learning for stateful agents. Better context, fewer tokens.
Token-efficient search for coding agents over public and private documentation.
Shared distillation cache for AI agents — every fetch ~73-89% fewer tokens via a shared cache.
Long-term memory for AI agents: durable records, observable retrieval, governed context assembly.
Related MCP Servers
- AlicenseBqualityCmaintenanceMaximizes AI agent context window by enabling compact code reading and editing, reducing tokens by 40% for deeper codebase understanding.19203MIT
- AlicenseAqualityBmaintenanceStructural memory for coding agents — 60% fewer tokens, refactor-safe, runs entirely on your machine.43815Apache 2.0
- AlicenseNot gradedqualityDmaintenanceVirtual Infinite Context for Agents and LLMs - maintains a continuous rolling context window, surfacing relevant memories while respecting token budgets.6MIT
- FlicenseNot gradedqualityAmaintenanceLocal-first code retrieval for AI agents — cuts codebase context from thousands of tokens to a few hundred, with zero hallucinated file paths.3-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/helloderekg/skim-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server