Skip to main content
Glama
slymnysr

sift

by slymnysr

sift

Runs your command, then gives the model only the lines that matter.

A test suite prints 4,000 lines and eleven of them are the failure. A build prints a progress bar that redraws 900 times. An install lists every package it touched. All of it lands in the context window, and — this is the part that costs — it is re-sent in full on every turn that follows.

sift is an MCP server and a command line for that problem. It runs the command itself, keeps every byte on disk, and hands the model a view: the failures, the summary, the lines a reader would actually stop on. The rest is marked, not deleted.

Two numbers, both measured, both reproducible from this repository. Running this project's own test suite prints 652 lines — 21,392 tokens, as the model's own tokenizer counts them. What comes back is 8 lines and 208 tokens: 99% fewer (python test/kazanc.py). Removing almost everything is the easy half. Over a 22-sample corpus of real build and test output, the default budget keeps 138 of the 140 lines a reader could not do without (python test/budget.py).

$ sift run -- pytest
FAILED test/test_auth.py::test_expired_token - assert 401 == 200
  ...
─ 3,914 lines not shown · sift peek 9f2c41ab for any of them ─
=== 1 failed, 212 passed in 18.4s ===

A file you did not produce — a log, a saved CI transcript, a crash dump — gets the same treatment without being run:

$ sift digest ci-run-8812.log
2026-09-02T04:11:07 Building 214 targets
─ 38,904 lines not shown · sift peek ci-run-8812.log for any of them ─
ERROR: //src/parser:parse_test failed in 4.1s
─ 1,022 lines not shown · sift peek ci-run-8812.log for any of them ─
FAILED: 1 of 214 targets

A list is not read in lines. A JSON array written for a machine often has no newlines at all, and there is nothing in a line of one worth choosing, so the record becomes the unit and the same rules hold:

$ sift digest export.json
{"id": 3, "status": "failed", "error": "connection refused"}
─ 412 records not shown · sift peek export.json for the text they came from ─
{"id": 416, "status": "ok"}

The same question, asked about source code instead, is a table of contents:

$ sift outline src/parser.rs
pub struct Parser {
pub fn parse(input: &str) -> Result<Ast, Error> {
─ 34 lines not shown · sift peek src/parser.rs for any of them ─
impl Iterator for Tokens {

And a command that does not end — a dev server, a log tail, a build you want to keep working during — is started and then read a slice at a time:

$ sift run --background -- cargo build --release
9f2c41ab
$ sift follow 9f2c41ab
   warning: unused import: `std::fmt`
─ 212 lines not shown · sift peek 9f2c41ab for any of them ─
   error[E0308]: mismatched types
sift 9f2c41ab · running · new lines 1-247 · 2 shown · nemotron
$ sift follow 9f2c41ab          # only what has arrived since
$ sift follow --all --wait 30   # every run at once, holding for something new
$ sift stop 9f2c41ab            # ends it, and everything it started

Nothing is shown twice, and the numbers are the run's own: line 247 stays line 247 in sift peek for as long as the capture exists.

What decides

A free model does. sift sends it the numbered lines and asks one question: which numbers matter? It answers with numbers, and nothing else it says is used — the text you read above is printed from the local capture, byte for byte.

That is the whole trick, and it is why this is not a summariser. A summariser can be wrong about what a line said. sift cannot be: it never writes a line, it only chooses one.

It also means language coverage is not a list. A model reads Turkish, Japanese, Arabic and Hindi; it reads Rust, COBOL, Mojo and a language released last week. Nothing here enumerates them, so nothing here can be missing one.

Related MCP server: Interactive Shell MCP

Three rules

Nothing shown is invented. The judge returns line numbers. Text always comes from the local file.

Nothing is thrown away. sift peek <handle> returns the raw capture, unchanged. Every gap in a view says how many lines it covers.

Nothing can break your command. No API key, no network, an overloaded endpoint, a nonsense reply, a bug in the distiller, or a decision that nothing may leave this machine — every one of these falls back to rules that need none of them. The command still runs; you still get its output; you get its exit code.

What leaves the machine

One thing: the text of a question. Before it is sent, anything credential-shaped is replaced — tokens with a known prefix, JWTs, authorization headers, passwords in connection strings, the body of a PEM block.

That costs you nothing to read. The model is only ever asked for line numbers, and the lines are printed from your own file, so a line masked on the way out is still shown to you in full.

Three switches:

SIFT_MAX_CAPTURE=0  # keep everything a command writes, however much that is
SIFT_BASE_URL=... # ask your own endpoint instead, and no key is wanted
SIFT_MODELS=a,b   # which models to ask there, best first
SIFT_NO_MODEL=1   # never send anything; use the deterministic view
SIFT_MASK=0       # send unmasked
SIFT_CACHE=0      # ask again, even about text already answered
SIFT_EFFORT=low   # let the model think less, and lose some of what matters
SIFT_PATIENCE=0   # one quick pass only; do not wait out a busy hour

Masking is not complete and does not claim to be: a bare secret shaped like nothing in particular gets through. SIFT_NO_MODEL is the one that guarantees.

The fourth is a measured trade and is off by default. Asked which lines matter in a 404-line build, the model writes about 900 tokens of reasoning to produce a twelve-token answer, and you wait 15 seconds for it. At SIFT_EFFORT=low the same question takes 2.4 seconds — and over the corpus it loses 7.8% of the lines a reader could not do without, in exactly the places this tool exists for: a mainframe job's return code, a crash loop's diagnosis. Speed is available; it is not the default, and the price is written down.

The third is about not paying twice. An answer already given for exactly these bytes and exactly this question is used again instead of bought again — and what is kept is the numbers, never the view, so the text is still rendered from your own file and the gap still names your own capture. A view that cost no request says (remembered) where it would otherwise name the model.

Captured bytes never leave $SIFT_HOME (~/.cache/sift by default). Nothing is uploaded, nothing is logged elsewhere, and removing a capture directory removes everything that was ever kept about it.

One capture keeps at most a gigabyte. That is far past any real build log and a few seconds of a command stuck in a loop, which is the case it exists for: nothing is thrown away, and the disk somebody else needs is not filled either. Reading never stops — a pipe nobody drains would stop the command, and that is the one thing this will not do — so the command finishes, its exit code is its own, and the footer says kept the first 1,073,741,824 bytes of it rather than letting you believe you have the whole run. SIFT_MAX_CAPTURE=0 turns the ceiling off for anyone who would rather have the disk.

They also never go away on their own. Nothing here sweeps, expires or tidies in the background: sift gc [DAYS] is the only thing that deletes a capture, and it deletes when you type it and not before. What it leaves is one line per handle — when it went and how big it was, never the command — so that a gap marker read a fortnight later gets "removed on the 8th" instead of the answer it would give for a handle you made up.

Commands

sift run [--timeout SECONDS] [--shell] [--background] [--cwd DIR]
         [--budget LINES] [--keep PATTERN] [--] COMMAND...
sift follow [HANDLE] [--all] [--wait N]
                          what a background run has said since you last looked
sift stop [HANDLE]        end it, and everything it started
sift outline PATH|-       what a file declares, without its bodies
sift digest PATH...|-     what is in files somebody else produced
sift peek HANDLE|PATH [FIRST] [LAST]
sift hook                 answer one shell-command event on stdin
sift mcp                  speak the protocol on stdin, for a client
sift tools                which dense tools this machine has
sift tool NAME [ARGS...]  run one of them, distilled
sift memory [TERM]        what has been run here before, and how it went
sift list [COUNT]         what is running, and what has been run
sift stats [COUNT]        what the shortening cost, and what it saved
sift gc [DAYS]            remove captures older than that, and say what went

A path of - reads standard input, which is the other way somebody else's output turns up:

$ journalctl -u nginx --since yesterday | sift digest -
Sep 08 04:11:07 nginx[2114]: worker process 2119 exited on signal 11
─ 8,204 lines not shown · sift peek 7c1a04e9 for any of them ─
Sep 09 01:02:55 nginx[2114]: signal 15 (SIGTERM) received, exiting

What arrives on a pipe has no path anybody could type again, so it is kept as a capture of its own and the gap marker names that instead. The second rule is why: a view that left lines out and pointed at a scratch file would be pointing at nothing by the time somebody read it.

Several paths given to digest are asked about at the same time, and --all follows every running command in one go. Both are the same idea: the waiting is the cost, so do it once. --wait N holds until a run actually says something instead of answering that nothing has happened yet.

sift hook is the way to catch the shell commands a client runs on its own, without a proxy: point the client's pre-tool hook at it and every shell command comes here first. Everything is routed — nothing here guesses which commands are worth catching, because a list of those is a list of tools in disguise and how much a command prints is not knowable before it runs. Routing everything costs nothing: a view of twelve lines is twelve lines. It fails open, so a bug in it leaves your shell exactly as it was, and SIFT_HOOK=0 switches it off.

It is the part of this that pays most and the only part you have to turn on, so it offers itself rather than waiting to be found:

sift hook --install      # says what it gives and what it costs, then asks
sift hook --uninstall    # and takes it back out

It writes one line into your client's settings, keeps a copy of the file as it was, and touches nothing else that is in there. sift run mentions it once, ever, and then stops.

sift tool runs one of three programs that answer a question without opening the filesg (ast-grep) for structural search, diff (difftastic) for a diff that can tell a reindent from a change, loc (scc) for the size of a tree. Their output is large by nature, which is exactly why they belong here. No binaries ship with this package: sift tools says which of them this machine has and what each is called, and installing one stays your decision.

sift memory asks no model at all. The question is counting — how often, how it went, which command has never once worked here — and a model asked to count is slower, costs a request and is sometimes wrong. The model decides what cannot be computed, and nothing else.

sift stats says what the shortening saved and what it cost, and keeps those two apart: the share is this tool's own arithmetic over bytes it holds, so it is exact, while the cost is the endpoint's count of its own tokens, so it is measured. A run the endpoint did not count is left out and said so, rather than filled in with bytes divided by four.

--keep PATTERN shows every line matching it whatever else was chosen and whatever the budget says. It is your pattern, not one this tool guessed at — the only place a pattern decides anything here, and it decides nothing until you type it. --budget LINES is the ceiling for one view.

In an agent

The same answers are available over MCP, and that is where they pay most: a tool result is re-sent on every turn that follows it, so a build log kept out of a transcript goes on staying out of it.

uv tool install "sift-cli[mcp]"   # or pipx; see Installing
claude mcp add --scope user sift -- sift-mcp

The key is read from ~/.config/nvidia/api_key, so it does not have to be in the environment and does not have to be pasted anywhere. --scope user puts the server in every project rather than the one you happen to be in.

Then restart the client. MCP servers are connected when a session starts, so the session you ran that command in will not see this one.

Without a key the server starts and every tool that would need a model declines with an explanation, so the agent falls back to its own shell rather than being handed a worse answer it cannot tell apart from a good one.

Any client that speaks stdio will do. The command is sift-mcp, and sift mcp starts the same server — one word for a client that would rather run the package by its own name (uvx --from "sift-cli[mcp]" sift-cli mcp, which is what the MCP registry entry says). It offers run, follow, outline, digest, digest_many, tool and peek. list and stats are deliberately not offered: they would hand a model every command lately run on this machine, including the ones it never asked about, and the person at a terminal already has that access while a model connecting over a socket does not.

Because a client never sees stderr, the last line of every result says what you are looking at: which handle, how the command ended, and whether a model chose the lines or none could be reached.

Installing

uv tool install sift-cli            # the command line, no dependencies at all
uv tool install "sift-cli[mcp]"     # and the MCP server

pipx install does the same thing. Either puts sift and sift-mcp on your PATH in an environment of their own, which is what you want for a command-line tool: nothing here belongs in the Python you build with.

Plain pip install sift-cli works inside a virtualenv you have already activated. It does not work against the system Python on Debian, Ubuntu, or WSL — those ship a EXTERNALLY-MANAGED marker and pip refuses, by design:

error: externally-managed-environment
× This environment is externally managed

That refusal is right and the answer is not --break-system-packages. Use uv tool or pipx.

The package is sift-cli and the commands are sift and sift-mcp. The names differ because sift-mcp on PyPI belongs to somebody else's project — an unrelated MCP server about authorising agent actions. Nothing here is theirs and nothing there is this.

Python 3.12 or newer, and no dependencies for the command line.

You need a model — a key, or one of your own

sift asks a model which lines matter. There are two ways to give it one and you need exactly one of them.

A free key

Not shipped, and not shareable. The key has to be yours. It is free, and it takes a minute:

  1. Get a key at https://build.nvidia.com

  2. Put it anywhere sift looks:

export SIFT_API_KEY=nvapi-...            # or NVIDIA_API_KEY
# or, once and for good:
mkdir -p ~/.config/nvidia && echo 'nvapi-...' > ~/.config/nvidia/api_key

Or a model of your own, and no key at all

Point sift somewhere and it asks there instead. Nothing about the question changes; the endpoint is asked the ordinary OpenAI-shaped way, and no Authorization header is sent when there is no key to put in it.

export SIFT_BASE_URL=http://localhost:11434/v1   # Ollama
export SIFT_MODELS=qwen3:8b                      # what to ask, best first

The same two lines fit llama.cpp (--api), vLLM, LM Studio, LocalAI, a company gateway, or any other endpoint that speaks POST /v1/chat/completions. SIFT_MODELS takes a comma-separated ladder and is asked in order.

An address you typed is treated as a decision: nothing warns you about a missing key, and the MCP server does not decline. What that endpoint wants for credentials is between you and it.

Tested here as a shape rather than as a list: the suite proves that an endpoint of your own is asked, and asked without a key. Which local servers answer well is a question about the model you run, and the corpus in test/budget.py is how you can settle it for yours.

Without either of them

The two callers are answered differently, on purpose:

  • At a terminal everything still runs — the command, the bytes, the exit code, the third rule — and a loud banner says no model chose these lines and that you are looking at the ends of the output.

  • Over MCP the tools decline and say why, and tell the agent to use its own shell instead. A person can see a degraded view and judge it; a model is handed a short text with a footer it has no reason to distrust, and quietly worse is the one thing this will not do to a reader who cannot check.

If you want to run without a model, say so with SIFT_NO_MODEL=1. That is a decision rather than an oversight, everything works, and nothing lectures you.

How it was built

Twenty-four phases, each one closed before the next began, each with a note in notlar/ saying what was decided and what it cost. notlar/00-PLAN.md is the arc, including the things that were deliberately not built and why.

The tests are in test/. Beside them is test/mutations.py, which breaks each rule the code follows — 162 of them, one at a time — and checks that the suite notices. A green suite says the tests did not object to this version of the code, not that they would object to a worse one.

It also says what happens when that battery is interrupted, because it was: a break left on disk survived every ordinary test run and took the machine down six times before anybody looked. test/conftest.py repairs one now, and the rule it was breaking is kept twice over, so that no single edit anywhere can turn sift stop into a signal to everything you own. That is notlar/19.

License

MIT.

Available Tools

7 tools
digestDigest a fileB
Read-onlyIdempotent

Read a file and return a distilled view of what is in it instead of its text. This is for anything already written down that would flood the conversation if opened whole: a log, a saved build or CI transcript, a test report, a crash dump, a long JSON export. The server opens the file, so its contents never enter the conversation -- a 40,000-line log costs a screenful -- and every line shown is the file's own, byte for byte, with peek on the same path returning any range in full. Use outline instead when the file is source code and the question is what it declares.

ParametersJSON Schema
NameRequiredDescriptionDefault
keepNo
pathYes
budgetNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior4/5

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

Beyond the readOnly/idempotent annotations, the description says the server opens the file, output is limited to roughly a screenful, and any included line is copied byte-for-byte rather than paraphrased. This is useful behavioral context, though it does not cover errors or permission failures.

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 front-loaded with the purpose and includes necessary usage boundaries, but the closing sentence is long and convoluted, mixing output characteristics with a peek comparison. It could be tightened without losing meaning.

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

Completeness3/5

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

It gives good context about when to use the tool and what output behavior to expect, and an output schema exists, but the unexplained optional parameters and lack of error/edge-case guidance leave the description incomplete for full API usage.

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?

The schema has no parameter descriptions and the description explains only the path/file concept. The optional keep and budget parameters are never defined, so callers cannot know their accepted values or effect.

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 says the tool reads a file and returns a distilled view of its contents, with examples of file types. It distinguishes this from outline and peek, though the phrase 'distilled view' is slightly imprecise.

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 says to use digest for large textual files that would flood the conversation and explicitly says to use outline instead for source-code declarations. It also contrasts with peek for full-range reading, but does not mention digest_many for multi-file cases.

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

digest_manyDigest several filesA
Read-onlyIdempotent

Digest several files in one call, asked at the same time. Use it whenever there is more than one file to read: four logs cost four waits asked one by one and roughly one wait asked together, and come back as one tool result instead of four. Each file keeps its own last line saying which it is, and a file that cannot be read says so in its place rather than taking the others down with it.

ParametersJSON Schema
NameRequiredDescriptionDefault
keepNo
pathsYes
budgetNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior5/5

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

Beyond the annotations (readOnly, openWorld, idempotent), the description discloses additional behavior: per-file output ('Each file keeps its own last line') and partial failure handling ('a file that cannot be read says so in its place rather than taking the others down'). This enriches the annotation-only context.

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 somewhat wordy and repetitive, e.g., 'asked at the same time' and 'asked together' convey the same idea. It could be more concise while retaining the essential points.

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?

While the description covers high-level batching and error handling, it omits important context such as parameter meanings, output format details beyond a per-file line, and how 'budget' or 'keep' affect behavior. This leaves agents under-informed given the tool's complexity.

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?

The description provides no explanation of the parameters ('paths', 'keep', 'budget'). Schema coverage is 0%, and the description does not compensate; it only vaguely references file lists without naming or defining any parameter.

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: 'Digest several files in one call' with the verb 'digest' and resource 'files'. It differentiates from single-file alternatives by emphasizing batching, e.g., 'come back as one tool result instead of four'.

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?

Explicit usage condition: 'Use it whenever there is more than one file to read'. It also contrasts with multiple individual calls ('four logs cost four waits... roughly one wait') and describes error behavior for unreadable files, providing clear guidance.

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

followFollow a background runA
Destructive

Return what a background command has printed since the last time you asked, and nothing you have already been shown. Use it with the handle from a run call made with background. The lines keep the numbers they have in the whole run, so peek on any of them returns that same line; a stretch that was only progress comes back as a gap saying how many lines it stands for, and a quiet minute comes back as nothing at all rather than as filler. Set stop when you are done with the command: it ends it, and everything it started, and returns the last of the output. Always stop a command you are finished with -- a background command left alone keeps running. With everything it answers about every run still going in one call, which is what to use when you started three things and want to know where they are. With wait it holds until something is actually said rather than coming back empty: an empty answer is a tool result that stays in the conversation for the rest of it, so waiting once costs less than asking five times.

ParametersJSON Schema
NameRequiredDescriptionDefault
stopNo
waitNo
handleNo
everythingNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the annotations (destructiveHint: true), the description discloses specifics: `stop` 'ends it, and everything it started,' and a left-alone background command keeps running (openWorldHint). It also reveals the subtle consequence that an empty answer stays in the conversation for the rest of it, which is not captured by any annotation.

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 first sentence front-loads the core purpose, and the rest is dense, informative prose covering modes, parameters, and behavioral caveats rather than padding. It is longer than average, but the tool has four interacting modes and subtle edge cases, so the length is justified.

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

Completeness5/5

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

The description explains the return format (incremental output since last ask, preserved line numbers, gap summaries for progress-only stretches, last output on stop) and covers the tricky consequences (empty results persisting in the conversation, background commands continuing to run). With an output schema present and all four parameters addressed, the description is complete enough for correct invocation in the described scenarios.

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?

The schema has zero description coverage, so the description carries the full burden and does address all four parameters in prose: `handle` (from a `run` call with `background`), `stop` (ends the command and what it started), `everything` (answers for every run still going), and `wait` (holds until something is said). However, some details remain implicit: the units of the `wait` number and the behavior of a null `handle` with no other flags are not specified.

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 first sentence states a specific action (return what a background command has printed since last asked) on a specific resource (a background command from `run`), which clearly distinguishes it from siblings like `peek` (which fetches a specific line) and `run` (which starts a background command). The title and description align on the core purpose of following an ongoing background run.

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 ties the tool to a `run` call made with `background` and contrasts it with `peek`, explaining the conditions for each (lines keep their numbers, so `peek` returns the same line). It gives concrete when-to-use guidance for `everything` ('when you started three things and want to know where they are') and for `wait` (avoiding empty results that persist in the conversation), plus the imperative to `stop` a finished command.

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

outlineOutline a fileA
Read-onlyIdempotent

Return what a file declares -- its types, functions, exports, targets and settings -- without their bodies, so that reading a 2,000-line source file costs a page. This is the machine behind run asked a different question: it holds no table of languages and never reads the suffix, so it answers about Rust, Haskell, a Makefile, a config file with no extension, or a language that did not exist last year. Lines come from the file byte for byte, and peek on the same path returns any range of it in full.

ParametersJSON Schema
NameRequiredDescriptionDefault
keepNo
pathYes
budgetNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already cover readOnlyHint, idempotentHint, and openWorldHint. The description adds valuable behavioral details: 'it holds no table of languages and never reads the suffix', 'Lines come from the file byte for byte', and the comparison with `peek`. These go beyond the annotations and clarify the tool's universal applicability and reading behavior, though it does not mention auth or side effects, which are not needed for a read-only tool.

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 well-structured and front-loaded with the core purpose. Each sentence adds value: the first explains what it returns, the second clarifies its universal applicability and relationship to `run`, and the third gives a behavioral detail about reading and contrasts with `peek`. There is no wasted text; it is efficient and information-dense.

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?

While the purpose and behavior are thoroughly explained, the description lacks any guidance on the two optional parameters (`keep` and `budget`). Since the schema provides no descriptions for them, an agent cannot know what values to pass or how they affect the output. The output schema exists, but the description should still give enough context for correct invocation, which it does not.

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 explaining the parameters. It does not explain `keep` or `budget` at all, and only implies `path` by context. The description focuses on the tool's behavior but leaves the optional parameters unexplained, which is a significant gap for an agent trying to call the tool with appropriate arguments.

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 explicitly states the tool's function: 'Return what a file declares -- its types, functions, exports, targets and settings -- without their bodies.' It also clearly distinguishes it from siblings by explaining it is the machine behind `run` asked a different question and contrasts with `peek`, making its purpose unambiguous.

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 provides clear context on when to use the tool: it works on any language or file type, including those without extensions or unknown to the system, and it contrasts with `peek` for full content. It implies the tool is for structural summaries rather than full reads, but it does not explicitly state 'when not to use' or name the exact alternative for each scenario. However, the contrast with `run` and `peek` gives strong guidance.

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

peekPeek at a captureA
Read-onlyIdempotent

Return the exact original lines of a capture or a file, byte for byte, with the line numbers they had there. Use it with the handle at the end of a run result, or with any path, to open up a gap that a view left behind. A range reaching past the end is clamped rather than refused, and with no range at all it returns the whole thing. With grep it searches instead: every line matching your pattern comes back with a few lines of context around it, which is the way into a gap when you know the word you want but not the line number.

ParametersJSON Schema
NameRequiredDescriptionDefault
capNo
grepNo
lastNo
firstNo
aroundNo
handleYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior4/5

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

The description goes beyond the readOnly/idempotent annotations by explaining behavior such as range clamping, default return of whole content when no range is specified, and grep with context lines. These details are valuable for understanding side-effect-free behavior.

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 moderately concise but contains poetic redundancies like 'open up a gap that a view left behind' and 'the way into a gap when you know the word you want'. These add style but not substance, making it less crisp than necessary.

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 core behaviors and parameter basics, but the unexplained 'cap' parameter leaves a gap in the overall picture. Since no output schema is provided, the description is the only source of information about what the tool returns, and it is mostly sufficient 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 description explains handle, range (first/last), around (context), and grep. However, the 'cap' parameter is not mentioned at all, leaving its purpose ambiguous. Schema description coverage is 0%, so this omission is meaningful.

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 returns exact original lines of a capture or file with line numbers, which is a specific and distinct purpose. However, the flowery phrasing ('open up a gap that a view left behind') slightly obscures the directness.

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?

It provides some usage context (use with handle from run result or any path) but does not explicitly compare to sibling tools like outline or digest. The guidance is implied rather than explicit about when to prefer this tool over others.

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

runRun a commandA
Destructive

Run a shell command and return only the lines that mattered instead of all of its output. Every byte is kept on disk and never enters the conversation, so a 5,000-line test run costs a few dozen lines of context -- and goes on costing nothing on every later turn, because tool results are re-sent with the rest of the transcript. The lines shown are the command's own, byte for byte; each gap states how many lines it stands for, and peek with the returned handle brings any range back in full. Prefer this over a plain shell tool whenever the output may be long or noisy. When you already know what you are looking for -- a symbol, a test name, an error code -- pass it as keep and every line containing it comes back whatever else was chosen.

ParametersJSON Schema
NameRequiredDescriptionDefault
cwdNo
keepNo
budgetNo
commandYes
timeoutNo
backgroundNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior5/5

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

The description discloses significant behavioral traits beyond the annotations: it explains the output filtering mechanism (only relevant lines shown, gaps quantified), the persistence of full output on disk, the re-sending of results with the transcript, and the integration with `peek` for retrieving arbitrary ranges. It also clarifies the `keep` parameter's behavior. This exceeds what annotations (readOnlyHint=false, destructiveHint=true) already convey and does not contradict them.

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 well-structured and front-loaded: it states the core purpose first, then explains the mechanism, then gives usage guidance. Every sentence adds value—there is no filler or repetition. Despite its length, it remains dense and useful, prioritizing the most critical information for an agent deciding whether and how to call the tool.

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 six parameters and no schema descriptions, the description is incomplete. It covers the output-handling behavior thoroughly but leaves the semantics of `cwd`, `timeout`, `background`, and `budget` unspecified. An agent cannot fully understand the tool's capabilities or constraints without additional inference. The presence of an output schema helps with return values, but parameter completeness is still lacking.

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 six parameters. It provides detailed semantics for `keep` ('every line containing it comes back whatever else was chosen') and mentions `peek` with a returned handle, but it says nothing about `cwd`, `timeout`, `background`, or `budget`. This leaves a large gap in parameter understanding, especially for a tool with destructive potential.

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 a specific verb and resource: 'Run a shell command and return only the lines that mattered.' It distinguishes itself from a generic shell tool by emphasizing filtered output, and it names the sibling 'peek' as a companion. However, it does not directly differentiate itself from the listed siblings (follow, outline, digest, tool, digest_many), relying instead on the general notion of a 'plain shell tool'.

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 gives explicit guidance: 'Prefer this over a plain shell tool whenever the output may be long or noisy.' It also provides a concrete usage pattern: 'When you already know what you are looking for -- a symbol, a test name, an error code -- pass it as `keep`.' This tells the agent when to use the tool and how to tailor its invocation, leaving little to inference.

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

toolRun a dense toolC
Destructive

Run one of three dense tools and return a distilled view of what it printed: sg (ast-grep) for structural search, diff (difftastic) for a diff that can tell a reindent from a change, loc (scc) for the size of a tree. Each of them answers a question without opening the file -- reach for sg instead of reading candidates to find where a shape occurs, and loc instead of listing a directory to size it. Their output is large by nature and is distilled like anything else, so a 4,000-line structural search costs a screenful with every byte still reachable through peek. A tool this machine does not have says so and says what it is called; nothing is installed for you.

ParametersJSON Schema
NameRequiredDescriptionDefault
argsNo
nameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.6/5.0
Behavior2/5

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

Despite the annotation destructiveHint=true, the description makes no mention of potential side effects or modifications to the environment. It only references error handling ('a tool this machine does not have says so'), omitting any disclosure about destructive behavior, which is a significant transparency gap.

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

Conciseness2/5

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

The description is verbose and meandering, using awkward metaphors like 'a 4,000-line structural search costs a screenful' and redundant phrasing. Its single-paragraph structure lacks clear organization, making it harder to parse the essential information quickly.

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

Completeness2/5

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

The output format is only vaguely described as 'a distilled view of what it printed', without concrete details on structure or content. It mentions that output is 'reachable through peek' but does not explain the full response shape or error scenarios beyond a cryptic reference to unavailable tools, leaving gaps for an agent.

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?

The schema includes two parameters (name and args) with zero description coverage. The description does not explain what 'name' refers to (presumably the tool name among sg/diff/loc) or how 'args' should be structured, leaving the agent without any guidance on how to populate these fields.

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 runs one of three specific tools (sg, diff, loc) and returns a distilled view, which distinguishes it from generic tools. The phrase 'reach for sg instead of reading candidates' and similar clarify the intended use cases, though the description is convoluted and could be more direct.

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 provides guidance for when to use the underlying tools (sg for search, loc for sizing) and mentions distillation of large output. However, it does not explicitly compare this tool to sibling tools like 'run' or state when to prefer this over alternatives, leaving the choice partially implicit.

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.

  1. 7 tool updatesv1.0.2
    • First observeddigest
    • First observeddigest_many
    • First observedfollow
    • First observedoutline
    • First observedpeek
    • First observedrun
    • First observedtool

TDQS

A3.7/5.0

Scored across 7 tools

Disambiguation4/5

Each tool has a distinct role — execute, follow background output, outline declarations, distill file contents, batch-digest, and peek into gaps — and the descriptions explicitly cross-reference one another to prevent confusion. The boundary between `run` and `tool` is subtle since both execute commands and distill output, and `digest`/`outline` share the same distill-then-peek pattern, which is why this isn't a perfect 5.

Naming Consistency4/5

Six tools use crisp, lowercase imperative verbs (run, follow, outline, digest, peek) with `digest_many` as a readable compound variant. `tool` breaks the pattern as a generic noun instead of a verb, which is the only real inconsistency.

Tool Count5/5

Seven tools sits squarely in the ideal 3–15 range for a focused output-distillation server. Each tool adds distinct capability — `digest_many` covers batching, `tool` covers specialized analyzers — so none feels redundant.

Completeness5/5

The set covers the full inspection lifecycle: execute (`run`), monitor and control background work (`follow` with wait/stop/everything), summarize files (`digest`/`outline`/`digest_many`), and retrieve exact bytes (`peek` with grep support). Every view leads back to the source via `peek`, so there are no dead ends or missing core operations.

Maintenance

ActivityMaintained
ResponsivenessNo issues

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

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Monitors development commands and exposes terminal output to Claude in real-time, allowing AI assistants to see errors, logs, and stack traces without copy-pasting.
    7
    3
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    Enables LLMs to create and manage persistent, interactive shell sessions with full terminal emulation and PTY support. It allows for sequential command execution and supports interactive programs like vim or htop through specialized streaming and snapshot output modes.
    4
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    Enables AI agents to launch, monitor, and manage long-running terminal processes with real-time log capture and search functionality. It features automatic log rotation and graceful process termination to ensure system stability.
    5
    16
    5
    MIT

Latest Blog Posts

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/slymnysr/sift'

If you have feedback or need assistance with the MCP directory API, please join our Discord server