Spill:把超大的 MCP 返回结果移出上下文,存入本地 DuckDB
原文标题:Keep large MCP results out of context
Spill 是一个 Apache-2.0 开源工具,通过 Hook 拦截超过 32 KiB 的 MCP 工具返回,将其存为本地 DuckDB 表(~/.spill/spill.duckdb),智能体只拿到一个紧凑描述符,再用 SQL 查询而不是读入 5 万 token 的原始 JSON。
Spill 把超大 MCP 返回落到本地 DuckDB,让智能体用 SQL 取数,为上下文窗口紧张提供了一种可复用的思路。
Open source · Apache-2.0
Keep large MCP results
out of context
Spill intercepts oversized MCP tool responses and stores them as local DuckDB tables. Your AI agent gets a compact descriptor and runs SQL instead of reading 50,000 tokens of raw JSON.
GitHub MCP → 18,412 issues → Spill → DuckDB table → compact descriptor
↑
spill.query('SELECT state, COUNT(*) GROUP BY state')
Why Spill
Everything stays local, nothing changes in your workflow
⚡
Automatic interception
Hook fires on every MCP PostToolUse event. Payloads under 32 KiB pass through untouched.
🗄️
Local DuckDB storage
Rows land in ~/.spill/spill.duckdb. No cloud account, no embeddings, no infrastructure.
🔍
SQL over any result
Filter, aggregate, join. DuckDB runs read-only with external access disabled.
🔒
Read-only by design
Keyword validator + connection-level read-only mode. Mutations are blocked at two layers.
🔌
Three clients
Cursor, Codex, and Claude Code. One install command per client, fully reversible.
📦
Homebrew tap
One-line install. No separate tap repo needed — this repo doubles as the tap.
Installation
Up and running in two commands
Homebrew builds Spill from source with embedded DuckDB. The first build takes a few minutes; upgrades are instant.
$ brew tap spill-ai/spill https://github.com/spill-ai/spill $ brew trust --formula spill-ai/spill/spill $ brew install spill $ spill install cursor
Restart your client after install to load the MCP server and hooks.
Use spill uninstall cursor to remove — unrelated config is never touched.
| Client | MCP config | Hook config |
|---|---|---|
| Cursor | ~/.cursor/mcp.json |
~/.cursor/hooks.json |
| Codex | ~/.codex/config.toml |
~/.codex/hooks.json |
| Claude Code | ~/.claude.json |
~/.claude/settings.json |
How it works
What gets spilled
Serialized tool output must be at least 32 KiB and contain a nonempty array of JSON objects. Three payload shapes are supported:
Direct JSON array
MCP text block containing a JSON array
structuredContent array
Errors — pass through
Binary / mixed blocks — pass through
Under 32 KiB — pass through
Columns are inferred as BOOLEAN, BIGINT, DOUBLE, or VARCHAR. Nested objects, arrays, and mixed types are stored as JSON text. Missing values become SQL NULL.
-- Agent receives a compact descriptor, then queries directly SELECT state, COUNT(*) AS n FROM spill_list_issues_a81f32 GROUP BY state ORDER BY n DESC;
Query policy
Only SELECT, WITH, SHOW, DESCRIBE, and EXPLAIN are allowed.
A SQL tokenizer rejects mutations, multiple statements, and semicolons mid-query.
Independently, DuckDB opens in read-only mode with external access and
extension loading disabled.
500 row cap
32 KiB output cap
No network calls at runtime
No daemon or background service
CLI Reference
Commands
# Dataset management spill list spill describe spill_list_issues_a81f32 spill sql 'SELECT state, count(*) FROM spill_list_issues_a81f32 GROUP BY state' # Hook and MCP server (normally launched by the client) spill hook cursor # also: codex, claude — reads one JSON event from stdin spill mcp # stdio MCP server # Install / uninstall spill install cursor spill uninstall cursor
The MCP server exposes query, list, and describe.
Query responses have columns and rows in column order.
Full documentation →
来源:Hacker News · MCP · spill-ai.github.io