How MCP Shrink Middleware Works with Caveman: A Complete Technical Guide
Caveman's MCP shrink middleware acts as a transparent proxy that intercepts list responses from any upstream MCP server and compresses prose fields using a token-efficient algorithm while preserving functional identifiers, URLs, and code tokens.
The caveman-shrink middleware is a specialized component in the JuliusBrussee/caveman repository that reduces token usage in Model Context Protocol (MCP) communications. It sits between your AI client and any upstream MCP server, automatically rewriting descriptive text in tools/list, prompts/list, and resources/list responses without altering the underlying functionality or API contracts.
Architecture and Proxy Flow
The middleware operates as a pure Node.js proxy that spawns the target MCP server as a child process. Located in src/mcp-servers/caveman-shrink/index.js, the core implementation handles request forwarding and selective response transformation through three distinct stages.
Spawning the Upstream Server
When you invoke caveman-shrink, the middleware uses src/mcp-servers/caveman-shrink/spawn-options.js to construct the proper child_process.spawn configuration. It takes the upstream command (e.g., npx @modelcontextprotocol/server-filesystem /path/to/project) and creates a child process with stdio pipes connected directly to the parent.
// Conceptual flow from index.js
const spawn = require('child_process').spawn;
const options = require('./spawn-options.js');
const child = spawn(command, args, options);
This architecture ensures that the client sees a seamless MCP server while the middleware maintains full control over the data stream.
Intercepting List Responses
The middleware parses each line of JSON output from the upstream server, identifying specific MCP method calls:
tools/listprompts/listresources/list
For each object returned by these methods, index.js checks for fields matching the CAVEMAN_SHRINK_FIELDS environment variable (defaulting to description). When matching fields are found, the middleware extracts the text and passes it to the compression module before forwarding the modified payload to the client.
The Compression Pipeline
The actual token reduction happens in src/mcp-servers/caveman-shrink/compress.js. This module implements the same compression algorithm used by the main Caveman skill, which:
- Preserves identifiers, URLs, file paths, and code-like tokens
- Strips filler words, hedging language, and pleasantries
- Maintains the semantic meaning of the description
When CAVEMAN_SHRINK_DEBUG=1 is set, the middleware logs delta information showing the original and compressed text lengths for each processed field.
Configuration and Environment Variables
The middleware behavior is controlled through two environment variables that require no code changes to adjust.
CAVEMAN_SHRINK_FIELDS
This comma-separated list defines which JSON fields get compressed. By default, only description is processed, but you can target multiple fields:
CAVEMAN_SHRINK_FIELDS=description,summary,notes npx caveman-shrink npx @modelcontextprotocol/server-filesystem /my/repo
CAVEMAN_SHRINK_DEBUG
Enable verbose logging to see compression statistics in real-time:
CAVEMAN_SHRINK_DEBUG=1 npx caveman-shrink npx @modelcontextprotocol/server-filesystem /my/repo
This outputs the token count reduction for each processed field, helping you tune the compression settings for your specific use case.
Practical Implementation Examples
You can integrate the shrink middleware into any MCP client configuration. Here are the most common deployment patterns.
Claude Code Configuration
Add the middleware to your MCP server configuration by wrapping the original command:
{
"mcpServers": {
"fs-shrunk": {
"command": "npx",
"args": [
"caveman-shrink",
"npx",
"@modelcontextprotocol/server-filesystem",
"/path/to/project"
]
}
}
}
This configuration maintains full filesystem access while automatically compressing all tool and resource descriptions before they reach the language model.
Command Line Usage
Run the proxy directly from your terminal to test the compression:
npx caveman-shrink npx @modelcontextprotocol/server-filesystem /my/repo
The terminal will display the upstream server's stderr, while stdout flows through the compression pipeline to any connected MCP client.
Custom Field Compression
To compress non-standard fields provided by custom MCP servers:
CAVEMAN_SHRINK_FIELDS=description,documentation,help_text npx caveman-shrink node ./my-custom-server.js
This flexibility allows the middleware to work with any MCP-compliant server, regardless of whether it uses standard or extended field names.
Summary
- Transparent Proxy:
src/mcp-servers/caveman-shrink/index.jsspawns upstream MCP servers and pipes stdio without modifying request bodies or tool execution. - Selective Compression: Only
tools/list,prompts/list, andresources/listresponses are processed, targeting fields specified inCAVEMAN_SHRINK_FIELDS. - Algorithm Safety: The
compress.jsimplementation preserves code identifiers, URLs, and file paths while removing prose filler words. - Zero Code Changes: Configuration happens entirely through environment variables, making it compatible with any existing MCP server.
- Debug Visibility: Set
CAVEMAN_SHRINK_DEBUG=1to monitor compression ratios and field transformations in real-time.
Frequently Asked Questions
How does the MCP shrink middleware affect tool execution performance?
The middleware adds minimal latency because it only processes list responses, not actual tool calls or request bodies. The compression happens in-memory using local JavaScript string operations, typically adding less than 1ms per processed item according to the Node.js event loop behavior in index.js.
Can I use caveman-shrink with custom MCP servers?
Yes. The middleware is server-agnostic and works with any MCP-compliant server. Since it intercepts responses at the protocol level rather than requiring server modifications, you can wrap existing servers like @modelcontextprotocol/server-filesystem or your own custom implementations without changing their source code.
What fields are safe to compress with CAVEMAN_SHRINK_FIELDS?
You should only compress human-readable prose fields like description, summary, or documentation. Never compress fields containing code, JSON schemas, identifiers, or functional data. The default description field is safe because the compression algorithm in compress.js specifically preserves code-like tokens and structural elements.
How do I verify that compression is working correctly?
Set CAVEMAN_SHRINK_DEBUG=1 before running the command. The middleware will output the original and compressed text lengths for each processed field to stderr, allowing you to verify that descriptions are being shortened while URLs and file paths remain intact.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →