tooltrim
Provides an optional integration for LangChain, allowing tool outputs to be compressed before entering the agent's context, reducing token usage while preserving key information.
Provides an OpenAI-compatible proxy that compresses tool outputs in flight, enabling seamless integration with OpenAI-compatible clients with zero code changes.
Provides a Redis-backed storage option for full tool outputs, enabling lossless expand-on-demand retrieval via short references.
tooltrim
Drop-in compression for LLM agent tool outputs. Shrink bloated tool results
— fetched web pages, paginated JSON, log dumps, CSV exports, long documents —
before they re-enter your agent's context window. Keep the facts the model
needs, drop the boilerplate, and keep the full output one expand() away.
from tooltrim import compressed_tool
@compressed_tool(max_tokens=400)
def web_fetch(url: str) -> str:
... # returns a 3,000-token HTML page
# your agent now receives a compact, on-topic extract insteadZero dependencies in the core. Pure-stdlib, deterministic, reproducible.
Provider-agnostic. Works with OpenAI, Anthropic, local models, LangChain, LlamaIndex, OpenAI-Agents, MCP, raw function-calling — anything. It compresses strings, not APIs.
Lossless by reference. Compression is extractive, and the full output stays retrievable via a short
ref— so it's compression plus retrieval, not blind truncation.Content-aware. Separate compressors for HTML, JSON, tabular data, logs, and free text. Optionally query-aware (BM25) to keep what the agent is actually looking for.
Faithfulness-tested. A built-in harness measures whether the model still answers correctly on compressed output (with Wilson 95% CIs) — not just how many tokens you saved.
Deploy as a proxy. An OpenAI-compatible compression proxy trims
role:"tool"messages in flight, so any app/language adopts it with zero code changes — just abase_url.
Why
In a real agent loop, the prompt isn't what blows up your context — tool
outputs are. A single web_fetch returns thousands of tokens of nav bars and
footers; a REST call returns a 300-item paginated array; a log tool dumps
10,000 lines of INFO heartbeat. And because the agent's transcript is replayed
on every turn, you pay for that bloat again and again — slower responses,
higher bills, and a model that loses the thread.
Routers, caches, and prompt compressors don't touch this. tooltrim targets the
tool output directly, at the exact point it enters context.
Related MCP server: Refract
Benchmark
Realistic tool outputs compressed to a 400-token budget, exact tiktoken
(cl100k_base) counts. Each output contains one planted fact ("needle") that the
agent needs; tooltrim is given the task as its relevance query.
Reproduce with benchmark.py.
Tool output | before | after | saved | needle kept |
Web page (HTML) | 2,816 | 13 | 99.5% | yes |
REST response (JSON) | 15,119 | 325 | 97.9% | yes |
Server logs | 7,606 | 390 | 94.9% | yes |
CSV export | 7,895 | 373 | 95.3% | yes |
Long document (text) | 6,139 | 10 | 99.8% | yes |
Total | 39,575 | 1,111 | 97.2% | 5/5 |
39,575 → 1,111 tokens — a 35.6× smaller context, with the relevant fact kept in every case. (HTML/text collapse to the matching passage when the query pinpoints it; structured types keep a representative, schema-preserving sample.)
Does compression lose information? (it can help)
Throwing away 99% of the tokens is only safe if the model still answers
correctly. We measure that directly: for 62 curated (tool output, question, gold answer) cases across all five content types — including multi-fact
cases (the answer needs several facts from different parts of the output) and
distractor cases (a deprecated value sits next to the current one) — a model
is asked the question twice: once on the full output, once on the
tooltrim-compressed output. Accuracy is reported with Wilson 95%
confidence intervals. Reproduce with run_faithfulness.py
— it runs offline by default (no API key) and has adapters for
Claude / OpenAI / Groq / Ollama.
On small local models, compression doesn't just preserve accuracy — it improves it, because the model is no longer distracted by thousands of tokens of noise. The effect reproduces across two independent model families:
model | full | @128 (−98.6%) | @256 (−97.3%) | @400 (−96.5%) |
| 13% [7–23%] | 84% [73–91%] | 81% [69–89%] | 82% [71–90%] |
| 23% [14–34%] | 73% [60–82%] | 66% [54–77%] | 66% [54–77%] |
The compressed intervals don't overlap the full-context intervals — at n=62 this
is a significant improvement for both models, not noise. Full provenance,
per-case answers, and the cross-model table are saved as citable artifacts under
benchmarks/runs/ and benchmarks/COMPARISON.md.
Stated plainly: these are small 7–8B models. A frontier long-context model
handles the full context far better, so its baseline is higher and the accuracy
uplift shrinks — but the token/cost savings remain. The uplift is largest for
smaller/cheaper models and longer contexts. The harness is wired so a frontier
run (--model claude) drops a new row into the same table when an API key is
available; n=62 is a pilot, which is why the CIs are reported.
How does it compare to truncation and RAG?
Preserving accuracy vs full context only matters if it beats the obvious
alternatives. run_baselines.py scores tooltrim against
naive truncation, query-aware RAG top-k, RAG-embed, and
LLMLingua-2 on the same cases and budgets, with a paired McNemar
significance test. Retention (accuracy ÷ full-context accuracy), offline judge:
budget | truncate-head | truncate-tail | rag-topk | tooltrim |
128 | 1.8% | 1.8% | 100% | 100% |
256 | 3.6% | 3.6% | 100% | 100% |
800 | 12.5% | 14.3% | 100% | 100% |
Query-aware compression retains 100% of accuracy while cutting 94–99% of
tokens; blind truncation drops the needed fact and collapses (p < 0.001 at every
budget). The offline judge is itself lexical, so RAG top-k ties tooltrim here —
tooltrim's content-type structure advantage surfaces with a real-LLM judge on
structured output. Details, caveats, and the full grid:
benchmarks/BASELINES.md.
End-to-end: does it preserve task success? (tau-bench, multi-step)
Single-turn faithfulness isn't the whole story — in a real agent loop a
compressor can drop a field the agent only needs three turns later.
run_taubench.py measures that directly: it wraps
tau-bench's own environment so
every tool observation is compressed before it re-enters the agent's context,
while tau-bench's reward function, LLM user simulator, and agent stay untouched.
A compressor that shreds an output the agent needs later shows up as lower task
success — the outcome metric, not a proxy.
The harness reports task success with Wilson 95% CIs over all (task, trial) observations and a paired McNemar test vs tooltrim, sweeps multiple token budgets to trace the accuracy-vs-budget curve, and emits a reproducibility manifest (pinned tau-bench commit, resolved model snapshot, seeds) alongside raw per-task JSON so every number is re-derivable offline without re-spending on the API. It runs against any litellm-supported model for both the agent and the user simulator.
Status: harness implemented and under pilot on tau-bench retail with
gpt-4o-mini; results land in benchmarks/TAUBENCH.md.
One design note surfaced by the pilot: retail's native tool outputs are modest
(~130–650 tokens), so runs use a tight budget (≈128 tokens) where compression
actually engages rather than passing through.
Install
pip install tooltrim # zero-dependency core (heuristic token counts)
pip install tooltrim[tokens] # add tiktoken for exact token countsExtras: tooltrim[langchain], tooltrim[redis], tooltrim[s3].
CLI
tooltrim demo # 10-second self-contained savings tour
cat big.json | tooltrim compress -q "refund status" --stats # pipe in, compressed out
tooltrim compress page.html -q "rate limits" -m 400
tooltrim proxy --upstream https://api.openai.com/v1 # run the proxyUsage (library)
1. Decorate a tool
from tooltrim import compressed_tool
@compressed_tool(max_tokens=400)
def read_file(path: str) -> str:
return open(path).read()2. Make it query-aware
Pull the relevance query from the call arguments…
@compressed_tool(max_tokens=400, query_from=lambda query, **_: query)
def web_search(query: str) -> str:
...…or set the agent's current goal ambiently, so every tool call this turn keeps what's relevant to it:
from tooltrim import query_scope
with query_scope("find the customer's refund status"):
result = run_agent_step() # all @compressed_tool calls inside use this query3. Imperative API + expand-on-demand
from tooltrim import ToolCompressor
tc = ToolCompressor(max_tokens=400)
res = tc.compress(huge_json_response, query="refund status for customer C-1007")
res.text # compact text to feed back to the model
res.saved_tokens # e.g. 14794
res.saved_ratio # e.g. 0.979
res.ref # e.g. "a1b2c3d4"
full = tc.expand(res.ref) # get the original back
slice_ = tc.expand(res.ref, start=0, length=2000)By default the compressed output ends with a small footer the model can act on:
…compressed extract…
[tooltrim: compressed 15119->325 tokens (saved 14794); full output ref=a1b2c3d4]Expose an expand(ref) tool to your agent and it can pull the full output back
whenever the extract isn't enough — turning aggressive compression into a safe
default. tooltrim hands you both the tool schema and the handler:
tools = my_tools + [tc.expand_tool_spec(style="openai")] # or style="anthropic"
# when the model calls expand_tool_output(ref=..., start=..., length=...):
result_text = tc.handle_expand(ref, start=start, length=length) # paged, safeSee examples/04_expand_tool.py for a full wiring.
Extractive compressors also keep neighbor context (a line/sentence around each
match) so the model gets context, not just the bare matching line.
4. Optional: LLM distillation (any provider)
The deterministic compressors need no LLM. When you want summarization instead of extraction, plug in any model with a one-line completion function — use a small/cheap one; distilling 15k → 300 tokens once saves your expensive model from re-reading the blob every turn.
from tooltrim import LLMDistiller
def complete(prompt: str) -> str:
# wrap OpenAI / Anthropic / local — your choice
return my_client.responses(prompt)
distiller = LLMDistiller(complete, max_tokens=300)
summary = distiller.compress(huge_output, query="refund status")5. Drop into LangChain — one line per tool
Already have LangChain tools? Wrap any of them and you get back a tool with the same name, description, and argument schema, so the agent calls it unchanged — but its (string) output is compressed before it lands in the scratchpad. The relevance query comes from the tool's own arguments.
pip install tooltrim[langchain]from tooltrim.integrations import compress_langchain_tool, compress_langchain_tools
fetch = compress_langchain_tool(my_tool, max_tokens=400,
query_from=lambda query, **_: query)
# or wrap the whole toolset at once (sharing one compressor + expand store):
tools = compress_langchain_tools(my_tools, max_tokens=400)See examples/03_langchain_tool.py.
6. Or LlamaIndex — same one-liner
pip install tooltrim[llamaindex]from tooltrim.integrations import compress_llamaindex_tool, compress_llamaindex_tools
fetch = compress_llamaindex_tool(my_tool, max_tokens=400,
query_from=lambda topic: topic)
tools = compress_llamaindex_tools(my_tools, max_tokens=400)A LlamaIndex tool returns a ToolOutput; only its content (what the LLM reads)
is compressed — the structured raw_output is preserved. See
examples/05_llamaindex_tool.py.
7. Or the OpenAI Agents SDK — same one-liner
pip install tooltrim[openai-agents]from tooltrim.integrations import compress_openai_agents_tool, compress_openai_agents_tools
fetch = compress_openai_agents_tool(my_tool, max_tokens=400,
query_from=lambda url: url)
tools = compress_openai_agents_tools(my_tools, max_tokens=400)Only the tool's on_invoke_tool is wrapped — name, JSON schema, and guardrails
are preserved. See examples/06_openai_agents_tool.py.
8. Or at the MCP boundary — a compressing gateway
MCP tool results (tools/call) are exactly
the bloated outputs tooltrim targets. Run a gateway in front of any MCP server and
point your MCP client (Claude Desktop, an IDE, an agent) at it — every result is
compressed in flight, no code change:
pip install tooltrim[mcp]
tooltrim mcp -- npx -y @modelcontextprotocol/server-filesystem /pathOr wrap the result-handling in your own server:
from tooltrim.integrations import compressing_call_tool, compress_tool_result
# wrap an upstream call_tool coroutine...
call = compressing_call_tool(session.call_tool, max_tokens=400)
# ...or compress a single CallToolResult (errors / non-text pass through)
result = compress_tool_result(result, compressor=tc, query=query)See examples/08_mcp_gateway.py.
8b. Or expose tooltrim itself as an MCP server
Want compression as a tool your agent can call directly — no upstream server to
front? Run tooltrim as a standalone MCP server. It exposes two tools over stdio:
compress(text, query=None, max_tokens=None) and expand_tool_output(ref).
pip install tooltrim[mcp]
tooltrim serveIt's published to the MCP Registry as
io.github.nac7/tooltrim, so an MCP-aware client can launch it with no clone:
uvx --from tooltrim[mcp] tooltrim serve9. Or run it as a proxy — zero code changes
Point your client at the tooltrim proxy; every tool result is compressed (using
the latest user message as the relevance query) before being forwarded upstream.
Both wire formats are understood, routed by request path — you only change
base_url.
python run_proxy.py --upstream https://api.openai.com/v1 # OpenAI-compatible
python run_proxy.py --upstream https://api.anthropic.com/v1 # Claudefrom openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8800/v1", api_key="<upstream key>")
from anthropic import Anthropic
client = Anthropic(base_url="http://127.0.0.1:8800")/v1/chat/completions compresses OpenAI role:"tool" messages; /v1/messages
compresses Anthropic tool_result blocks. The proxy is stdlib-only and fails
open: if anything goes wrong it forwards the original request untouched, so it
never breaks a production call.
Online, it also keeps you under provider rate limits. Against a live hosted
model (Groq free tier, 6,000-tokens-per-request cap), 45% of raw tool outputs
are rejected (HTTP 413) but 100% of tooltrim-compressed calls fit — a 14,415-token
result is compressed to 26 tokens in flight and the call succeeds. See
benchmarks/ONLINE_GROQ.md.
10. Scale out — shared expand-store + metrics
The default expand-store is in-process, fine for one worker. To run multiple
workers/replicas behind a load balancer, the store must be shared — otherwise
a ref minted by one worker can't be expanded by another. Swap in a backend
(all are content-addressed, so writes dedup automatically):
from tooltrim import ToolCompressor, FileStore, RedisStore, S3Store
tc = ToolCompressor(store=FileStore("/mnt/shared/tooltrim")) # zero-dep, shared volume
tc = ToolCompressor(store=RedisStore(url="redis://cache:6379/0", # pip install tooltrim[redis]
ttl_seconds=86_400))
tc = ToolCompressor(store=S3Store(bucket="my-bucket")) # pip install tooltrim[s3]The proxy exposes Prometheus metrics at GET /metrics (tokens in/out/saved,
messages compressed, fail-open count, upstream errors, latency) — scrape it to
quantify savings fleet-wide:
tooltrim_tokens_saved_total 14389
tooltrim_messages_compressed_total 1
tooltrim_fail_open_total 0How it works
Pass-through if the output already fits the budget (zero overhead).
Detect the content type (JSON / HTML / tabular / logs / text).
Compress with a type-specific strategy:
JSON — preserve structure; sample arrays (keeping the key schema), note
(+N more items), truncate long strings; tighten until it fits.HTML — extract readable text (drop
script/style/nav/footer), then fit the budget.Tabular — keep the header + a sample of rows +
(+N more rows).Logs — collapse repeated lines (
x42), always keep errors/warnings, fill with head/tail context.Text — query-aware extractive selection (BM25 or embeddings),
[…]elisions.
Stash the full output under a content-addressed
refforexpand().
With a query, every compressor keeps the most relevant parts; without one, it falls back to structure-preserving head/tail selection.
Semantic relevance (optional)
Scoring defaults to lexical BM25 (zero-dependency). For semantic matching —
so a query for "car" keeps a chunk about "automobiles" — pass an
EmbeddingScorer. It's provider-agnostic: give it any embed(texts) -> vectors
callable (OpenAI, Cohere, local), or let it load sentence-transformers
(pip install tooltrim[embeddings]). The scorer threads through every content
type:
from tooltrim import ToolCompressor, EmbeddingScorer
tc = ToolCompressor(max_tokens=400,
scorer=EmbeddingScorer(embed=my_client.embed))Streaming (bounded memory)
Some outputs are too big to hold in memory — a multi-GB log, a subprocess's
stdout, an HTTP stream. compress_stream consumes an iterable incrementally with
constant memory (bounded head/tail/top-K/important-line buffers), then fits
the survivors to the budget:
from tooltrim import compress_stream
text = compress_stream(open("huge.log"), max_tokens=400, query="disk error")How it's different
Tool class | What it optimizes | tooltrim |
Routers (RouteLLM…) | which model gets the call | orthogonal |
Semantic caches | repeated identical calls | orthogonal |
Prompt compressors (LLMLingua) | the prompt/instructions | different target |
Memory frameworks (MemGPT…) | conversation history, as a framework you adopt | tooltrim is a drop-in on the tool boundary |
tooltrim targets the tool-output boundary — the largest and most-ignored token sink in agentic apps — and works alongside all of the above.
Status
v0.2 — deterministic zero-dependency core, 104-test suite, reproducible token +
faithfulness benchmarks (with Wilson CIs, cross-model), a proxy speaking
both OpenAI and Anthropic wire formats with Prometheus /metrics,
LangChain, LlamaIndex, and OpenAI-Agents adapters, an MCP
compressing gateway, pluggable File/Redis/S3 expand-stores for horizontal
scale, optional embedding-based relevance, streaming compression for
outputs too big to hold in memory, a tooltrim CLI, a multi-step
task-success harness that compresses tool outputs inside tau-bench's own agent
loop (in-loop, McNemar vs baselines, reproducibility manifest), and citable run
artifacts under benchmarks/. Published on
PyPI.
Roadmap: frontier-model faithfulness runs, the scaled tau-bench task-success sweep (multi-budget, multi-trial) and its benchmark release, and native streaming passthrough in the proxy.
Contributions and benchmark cases welcome. MIT licensed.
Available Tools
2 toolscompressA
Compress a bloated tool output or long text so it fits a token budget while keeping what's relevant to an optional query. Returns a compact extract; the full output stays retrievable via the ref in its footer — call expand_tool_output with that ref to read it back.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | the tool output / long text to compress | |
| query | No | optional relevance query — keep what's on-topic for this | |
| max_tokens | No | token budget (default 512) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the responsibility of behavioral disclosure. It explains that the result is a compact extract with a footer ref, that the full output remains retrievable via that ref, and how to use the sibling tool to retrieve it. This goes beyond a simple one-liner and gives the agent a clear mental model of the tool's side effects.
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 establishes purpose and the second explains the return format and retrieval path. It is front-loaded with the key action, contains no filler, and every clause earns its place. Perfectly sized for a tool of this complexity.
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 three parameters, no output schema, and one sibling tool, the description adequately explains what the tool returns ('a compact extract'), how to access the full output (via ref in footer), and how that connects to expand_tool_output. It does not mention edge cases or validation rules, but for a straightforward compression tool it is sufficiently 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 description coverage is 100%, so each parameter is described in the schema. The description itself adds little new meaning: it reiterates 'optional query' and 'token budget' but does not provide additional context beyond what the schema already specifies. Baseline 3 is appropriate given the high schema coverage.
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 verb ('Compress'), the resource ('a bloated tool output or long text'), and the specific goal ('fits a token budget while keeping what's relevant'). It also distinguishes from the sibling tool by explaining the ref mechanism and pointing to expand_tool_output for retrieval.
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 clear context for use (when output is bloated or needs to fit a token budget) and references expand_tool_output as the complementary tool for reading the full output. It lacks explicit exclusions or 'when not to use' but covers the primary usage scenario well.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
expand_tool_outputA
Retrieve the full, uncompressed tool output behind a tooltrim reference (shown in a compressed result's footer as ref=XXXX). A compressed observation may have omitted fields you need — ids, amounts, individual list items, statuses. IMPORTANT: before you answer the user or take an action that depends on a compressed result, if any detail you need is not clearly present in it, call this tool with that ref to read the full output first. Returns a page of characters; use start/length to page through more.
| Name | Required | Description | Default |
|---|---|---|---|
| ref | Yes | the ref id, e.g. a1b2c3d4 | |
| start | No | character offset to start from (default 0) | |
| length | No | max characters to return (default: one page) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations available, the description carries the full burden. It discloses the pagination behavior (returns a page of characters, start/length for more), the nature of the output (full, uncompressed tool output), and the dependency on a ref. It does not explicitly state side effects, but 'Retrieve' strongly implies a read-only operation. It lacks edge-case details like invalid ref behavior, but for a simple retrieval tool this is sufficient.
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 three sentences with zero filler. The first sentence states the primary action, the second provides usage context and importance, and the third explains paging. It is front-loaded with the core purpose and every sentence 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?
For a tool with no output schema, the description adequately covers the return value by stating it returns the 'full, uncompressed tool output' and is paginated as 'a page of characters.' It also addresses why this tool matters (omitted fields in compressed results) and how to retrieve all data. The examples of missing fields provide practical context, making the tool's purpose and usage fully understandable.
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 100% with clear descriptions for all three parameters. The description adds value by explaining the relationship between start and length ('use start/length to page through more'), which synthesizes the parameters into a usage pattern. It also clarifies the ref's origin (shown in the compressed result's footer), which is not in the schema. This meaningfully supplements the schema.
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 opens with a specific verb+resource: 'Retrieve the full, uncompressed tool output behind a tooltrim reference.' It clearly distinguishes itself from the sibling compress by focusing on decompression/retrieval. The reference format (ref=XXXX) is explicitly explained, leaving no ambiguity about what the tool does.
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 provides explicit when-to-use guidance: 'before you answer the user or take an action that depends on a compressed result, if any detail you need is not clearly present in it, call this tool with that ref.' It also explains the contextual trigger (compressed observation may have omitted fields) and gives concrete examples of missing data (ids, amounts, list items, statuses). While it doesn't mention the sibling tool by name, the usage context is unambiguous.
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.
2 tool updates
v1.0.0- First observed
compress - First observed
expand_tool_output
TDQS
Compress and expand_tool_output have clearly opposite purposes: one reduces output, the other restores it. No overlap or ambiguity exists between them.
Both names use imperative verbs, but 'compress' lacks the object that 'expand_tool_output' includes. Minor style deviation, but the pattern is still predictable and readable.
Two tools is exactly the right scope for a compression/expansion utility. Each tool serves a distinct, necessary role, and the pair is well-scoped.
The tool surface covers the full lifecycle: compress output and expand it back via reference. No critical missing operations for the stated purpose.
Maintenance
Related MCP Connectors
MCP server for progressive tool usage at any scale (see https://klavis.ai)
Deterministic AI agent microtools, no accounts/API keys. fetch_extract: 98% token cut. 38 tools.
MCP server for Clipkit — gives AI agents a video toolbox via the Clipkit schema.
The OpenRouter for tools. One MCP connection gives any AI agent 254 hosted tools, pay per call.
471
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn adaptive tiny-model layer that sits between an LLM and its MCP tools, compressing verbose tool outputs to reduce token usage by up to two orders of magnitude.1Apache 2.0
- AlicenseAqualityBmaintenanceMCP proxy that compresses tool schemas on the fly. Up to 98% token reduction, 100% signal preserved verified after every compression. Zero LLM calls, fully deterministic.54MIT
- AlicenseAqualityAmaintenanceMCP server and local proxy that compresses LLM prompts, tool output, and replies to cut token cost, with a quality gate that reverts any step that does not save. Exposes llmtrim_compress, llmtrim_compress_text, and llmtrim_stats.3225Mozilla Public 2.0
- AlicenseAqualityAmaintenanceAggregator MCP proxy that collapses N downstream MCP servers into 4 meta-tools with progressive tool discovery, and compresses large tool outputs (HTML→Markdown, JSON summarization) with full-output retrieval via read_more and a per-session token-savings report.4842MIT
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/nac7/tooltrim'
If you have feedback or need assistance with the MCP directory API, please join our Discord server