Keep big MCP responses out of your context window. Query them.
Project description
Sift
Artifact gateway - Structured memory for AI agents. Keeps context usable in multi-step workflows.
AI agents break when their tools return too much data. A single MCP call or CLI command can return 30-100 KB of JSON. That is roughly 8,000-25,000 tokens spent before the agent can do the next step. After a few calls, the model starts dropping details or making bad calls. See Why Sift exists for research and open issues behind this pattern.
Sift stores tool output as artifacts, infers a schema, and returns a compact reference with field types and sample values. The agent can see the data shape without carrying full payloads in context. When it needs details, it runs focused Python queries against stored artifacts.
Sift works with MCP clients (Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, Zed) and CLI agents (OpenClaw, terminal automation). Same artifact store, same query interface, two entry points.
┌─────────────────────┐
MCP tool call ──────────▶│ │──────────▶ Upstream MCP Server
CLI command ──────────▶│ Sift │──────────▶ Shell command
│ │
│ ┌─────────────┐ │
│ │ Artifacts │ │
│ │ (SQLite) │ │
│ └─────────────┘ │
└─────────────────────┘
│
▼
Small output? return inline
Large output? return schema reference
Agent queries what it needs via code
Quick start
MCP agents
pipx install sift-gateway
sift-gateway init --from claude
Restart your MCP client. Sift mirrors upstream tools, persists outputs as artifacts, and returns either the full payload (for small responses) or a schema reference (for large responses). The agent can query stored artifacts with artifact(action="query", query_kind="code", ...).
--from shortcuts: claude, claude-code, cursor, vscode, windsurf, zed, auto, or an explicit path.
CLI agents (OpenClaw, terminal automation)
pipx install sift-gateway
sift-gateway run -- kubectl get pods -A -o json
Large output is stored and returned as an artifact ID plus compact schema. Example:
sift-gateway code <artifact_id> '$.items' --code "def run(data, schema, params): return {'rows': len(data)}"
Another capture example:
sift-gateway run -- curl -s api.example.com/events
For OpenClaw, see the OpenClaw Integration Pack.
Example workflow
You ask an agent to check what is failing in prod:
datadog.list_monitors(tag="service:payments")
Without Sift, 70 KB of monitor configs and metadata can go straight into context. That is about 18,000 tokens before the next tool call.
With Sift, the agent gets a schema reference:
{
"response_mode": "schema_ref",
"artifact_id": "art_9b2c...",
"schemas_compact": [{"rp": "$.monitors", "f": [
{"p": "$.name", "t": ["string"]},
{"p": "$.status", "t": ["string"], "examples": ["Alert", "OK", "Warn"]},
{"p": "$.type", "t": ["string"]},
{"p": "$.last_triggered", "t": ["datetime"]}
]}],
"schema_legend": {"schema": {"rp": "root_path"}, "field": {"p": "path", "t": "types"}}
}
The agent can then run a focused query:
artifact(
action="query",
query_kind="code",
artifact_id="art_9b2c...",
root_path="$.monitors",
code="def run(data, schema, params): return [m for m in data if m.get('status') == 'Alert']",
)
In this example, two calls use about 400 tokens and still leave room for follow-up steps.
How it works
Sift runs one processing pipeline for MCP and CLI:
- Execute the tool call or command.
- Parse JSON output.
- Detect pagination from the raw response.
- Redact sensitive values (enabled by default).
- Persist the artifact to SQLite.
- Map the schema (field types, sample values, cardinality).
- Choose response mode:
full(inline) orschema_ref(compact reference). - Return the artifact-centric response.
Response mode selection
Sift chooses between inline and reference automatically:
- If the response has upstream pagination: always
schema_ref. - If the full response exceeds the configured cap (default 8 KB):
schema_ref. - If the schema reference is at least 50% smaller than full:
schema_ref. - Otherwise:
full(inline payload).
Pagination
When upstream tools or APIs paginate, Sift handles continuation explicitly.
MCP:
artifact(action="next_page", artifact_id="art_9b2c...")
CLI:
sift-gateway run --continue-from art_9b2c... -- gh api repos/org/repo/pulls --after NEXT_CURSOR
Each page creates a new artifact linked to the previous one through lineage metadata. The agent can run code queries across the full chain.
Code queries
Both MCP and CLI agents can analyze stored artifacts with Python.
MCP:
artifact(
action="query",
query_kind="code",
artifact_id="art_123",
root_path="$.items",
code="def run(data, schema, params): return {'count': len(data)}",
)
CLI:
# Function mode
sift-gateway code art_123 '$.items' --code "def run(data, schema, params): return {'count': len(data)}"
# File mode
sift-gateway code art_123 '$.items' --file ./analysis.py
Multi-artifact query example:
artifact(
action="query",
query_kind="code",
artifact_ids=["art_users", "art_orders"],
root_paths={"art_users": "$.users", "art_orders": "$.orders"},
code="""
def run(artifacts, schemas, params):
users = {u["id"]: u["name"] for u in artifacts["art_users"]}
return [{"user": users.get(o["user_id"]), "amount": o["amount"]}
for o in artifacts["art_orders"]]
""",
)
Import allowlist
Code queries run with a configurable import allowlist. Default allowed import roots include math, json, re, collections, statistics, heapq, numpy, pandas, jmespath, datetime, itertools, functools, operator, decimal, csv, io, string, textwrap, copy, typing, dataclasses, enum, fractions, bisect, random, base64, and urllib.parse. Third-party modules are usable only when installed in Sift's runtime environment.
Install additional packages:
sift-gateway install scipy matplotlib
Security
Code queries use AST validation, an import allowlist, timeout enforcement, and memory limits. This is not a full OS-level sandbox.
Outbound secret redaction is enabled by default to reduce accidental leakage of API keys from upstream tool responses.
See SECURITY.md for the full security policy.
Configuration
| Env var | Default | Description |
|---|---|---|
SIFT_GATEWAY_DATA_DIR |
.sift-gateway |
Root data directory |
SIFT_GATEWAY_PASSTHROUGH_MAX_BYTES |
8192 |
Inline response cap |
SIFT_GATEWAY_SECRET_REDACTION_ENABLED |
true |
Redact secrets from tool output |
SIFT_GATEWAY_AUTH_TOKEN |
unset | Required for non-local HTTP binds |
Full reference: docs/config.md
Documentation
| Doc | Covers |
|---|---|
| Why Sift Exists | Research and ecosystem context |
| Quick Start | Install, init, first artifact |
| Recipes | Practical usage patterns |
| OpenClaw Pack | OpenClaw skill, quickstart, templates |
| API Contracts | MCP + CLI public contract |
| Configuration | All settings and env vars |
| Deployment | Transport modes, auth, ops |
| Errors | Error codes and troubleshooting |
| Observability | Structured logging and metrics |
| Architecture | Design and invariants |
Development
git clone https://github.com/lourencomaciel/sift-gateway.git
cd sift-gateway
uv sync --extra dev
uv run python -m pytest tests/unit/ -q
uv run python -m ruff check src tests
uv run python -m mypy src
See CONTRIBUTING.md for the full development guide.
License
MIT - see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sift_gateway-0.2.7.tar.gz.
File metadata
- Download URL: sift_gateway-0.2.7.tar.gz
- Upload date:
- Size: 252.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8398f967d72f98c8e93922e15a2447962a784e46eaf9573e7e31645f7a6cbd23
|
|
| MD5 |
ce3429a634d60424b17e8c8c166c9d92
|
|
| BLAKE2b-256 |
1ffeb80a2730244ff430c12ad354060d5b407c836583dbd69438b5174995d60c
|
Provenance
The following attestation bundles were made for sift_gateway-0.2.7.tar.gz:
Publisher:
release.yml on lourencomaciel/sift-gateway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sift_gateway-0.2.7.tar.gz -
Subject digest:
8398f967d72f98c8e93922e15a2447962a784e46eaf9573e7e31645f7a6cbd23 - Sigstore transparency entry: 975092952
- Sigstore integration time:
-
Permalink:
lourencomaciel/sift-gateway@283cd5a1213b818bd508fb5a5518ade7273622c0 -
Branch / Tag:
refs/tags/v0.2.7 - Owner: https://github.com/lourencomaciel
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@283cd5a1213b818bd508fb5a5518ade7273622c0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sift_gateway-0.2.7-py3-none-any.whl.
File metadata
- Download URL: sift_gateway-0.2.7-py3-none-any.whl
- Upload date:
- Size: 324.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df0f940081ed4533da92592f820a2694bd0f426bb98bfdb05534029b730cf207
|
|
| MD5 |
7cf77748a23c362f3a0f776e31c52005
|
|
| BLAKE2b-256 |
852e273cc6d6635f9539563a18dd662732c8f7c44e1d557f8917a3ea3becfec0
|
Provenance
The following attestation bundles were made for sift_gateway-0.2.7-py3-none-any.whl:
Publisher:
release.yml on lourencomaciel/sift-gateway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sift_gateway-0.2.7-py3-none-any.whl -
Subject digest:
df0f940081ed4533da92592f820a2694bd0f426bb98bfdb05534029b730cf207 - Sigstore transparency entry: 975092957
- Sigstore integration time:
-
Permalink:
lourencomaciel/sift-gateway@283cd5a1213b818bd508fb5a5518ade7273622c0 -
Branch / Tag:
refs/tags/v0.2.7 - Owner: https://github.com/lourencomaciel
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@283cd5a1213b818bd508fb5a5518ade7273622c0 -
Trigger Event:
push
-
Statement type: