
Skim Mcp
io.github.helloderekg由 GitHub 帳號 helloderekg 發布v0.1.1更新於 Oct 24, 2026
Lossless skim-then-expand reading of big files, repos, and command output with far fewer tokens
概覽
本機 MCP 伺服器,讓助理先把大型檔案、程式碼庫和指令輸出壓縮成骨架概覽,再按需無損展開所需片段,大幅減少 token 用量
- 可以做什麼
- 開啟檔案取得帶錨點 ID 的精簡骨架,可在同一次呼叫中附帶查詢比對結果,再依錨點或行範圍展開逐字原文,並可在控制代碼中搜尋字串出現在哪些錨點而不必全部讀取。把整個程式碼庫對應成依 token 預算排序的骨架,每個檔案各有控制代碼,依查詢比對或匯入圖中心度排序。執行 shell 指令並取得可展開的精簡輸出檢視,重複區塊去重、關鍵字面值保留。替換磁碟上某一個已展開片段,若檔案自開啟後已變更則拒絕,保留換行符號並重新驗證結果。片段也可作為 MCP 資源依參照取得。
- 適用情境
- 適合助理處理大型檔案、陌生程式碼庫或冗長的測試、建置與日誌輸出,希望在減少 token 用量的同時仍能取回原文的情境。README 指出,對很小的檔案或需要讀取檔案大部分內容時收益很小甚至為負,且模型必須主動選用這些工具而非內建的檔案讀取。
- 執行需求
- 以本機程序在使用者機器上執行,可從 PyPI 用 uv 安裝或從原始碼檢出安裝;README 的一行指令使用 uvx 並帶 lang 與 tokens 附加元件。僅限桌面端,未宣告驗證或環境變數。選用附加元件提供多語言解析和 token 計數。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Skim Mcp,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
skim
[CI] [PyPI] [Python 3.11+] [License: MIT]
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.
Falsifiable, not claimed
A reduction percentage is marketing until you can check it. skim ships the checker:
Five 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)
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:
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):
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):
Or from source:
Register with Claude Code (use the repo's absolute path; forward slashes work on Windows):
Or Claude Desktop — add to claude_desktop_config.json (%APPDATA%\Claude\ on Windows,
~/Library/Application Support/Claude/ on macOS), then restart:
(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:
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:
Re-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:
It 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
The 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
來源:README.md,提交 c98c058
工具
0版本歷史
1- v0.1.1最新Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分