Inspiration
As AI coding agents become more autonomous, they consume massive amounts of their context window by continuously re-reading the same files or re-running the same commands (like cargo test). Every redundant byte fetched pushes out valuable historical context and reasoning.
I was inspired to solve this by creating a Model Context Protocol (MCP) gateway, a proxy that sits between the agent and the system, to manage the state of the context the coding agent ingests, and minimize the repeating tokens that an agent has to spit out. By intercepting tool calls, keeping a runtime memory of what the agent has already seen, and returning compact diffs (or simple "unchanged" signals) and reusable commands, we can drastically reduce token usage, keeping the agent's context window clean and focused on the actual work.
What it does
Loop-Whole is a Rust-based MCP server that exposes workspace-scoped read, write, edit, and bash tools. Instead of just executing these commands blindly, it intercepts them to perform context optimization:
- Read Optimization: If an agent requests a file it has already seen and it hasn't changed, Loop-Whole intercepts the payload and returns an
unchangedsignal. If the file changed, it calculates a token-efficient unified diff. - Command Optimization: When an agent re-runs a build or test command, Loop-Whole captures and fingerprints the canonical output. If the result is exactly the same as the last run, it returns a minimal confirmation rather than dumping thousands of lines of terminal output back into the context window.
- command edit: we observed that agents are very good at, and love to, use one time Python scripts. So we found a way to let coding agents build on top of their Python scripts without needing to recompute every single token of a Python script to use it again, whether for the same task or for a different one. We used the edit tool to do this for in memory structs of the Bash command Python scripts. Best of both worlds!
- Token Accounting & Observability: It runs a concurrent HTTP API that tracks exact metrics on how many tokens were saved during the session, writing a comprehensive JSON dump on shutdown.
How we built it
We built the project in Rust, leveraging Tokio for asynchronous process management and filesystem operations.
The gateway runs over stdio to communicate with the MCP client, while simultaneously exposing a local HTTP polling API for observability. At the core of the optimization engine is the SessionStore, an in-memory repository (wrapped in Arc<RwLock<_>>) that tracks tool-call evidence, baselines, and performs token accounting.
For token accounting, we estimated because we did not have time to attend to nor access to the exact tokenizers of each and every model:
$$ \text{Tokens} = \left\lceil \frac{\text{Character Count}}{4} \right\rceil $$
To calculate the overall context window savings across the session, Loop-Whole tracks the sum of original versus intercepted outputs:
$$ \text{withoutRuntimeTokens} = \sum \text{inputTokens} + \sum \text{originalOutputTokens} $$ $$ \text{withRuntimeTokens} = \sum \text{inputTokens} + \sum \text{interceptedOutputTokens} $$ $$ \text{savedTokens} = \text{withoutRuntimeTokens} - \text{withRuntimeTokens} $$ $$ \text{savingsPercent} = \left( \frac{\text{savedTokens}}{\text{withoutRuntimeTokens}} \right) \times 100 $$
To make diffs work, we used the similar crate to generate unified text diffs. For command execution, rather than spawning arbitrary raw shells, Loop-Whole uses an allowlist (cargo, npm, git, grep) and carefully drains stdout and stderr in 8KB chunks, applying a 256KB retention budget so that massive log dumps don't crash the system.
Challenges we ran into
- Canonicalization and Security: Ensuring that all file paths and
bashworking directories stay strictly within the--rootworkspace boundary was complex. Handling symlink escapes safely required careful lexical resolution and upward traversal for missing files. - Diffing Partial Views: For the
readtool, we had to implement safeguards to prevent massive files from overwhelming the system (truncating at 2,000 lines or 50KB), plus storing them in memory. Generating valid diffs against these partial views required storing the exact prior result text alongside full-file hashes. - Not using a DB: We initially tackled this as a web app but then we realized: we don't need a DB, because we only need tool calls per session, and we wouldn't do anything with them after storing them. So we went back to the drawing board on the first night, reassessed requirements, and built this for devs, by devs.
- Command Streaming & Lifecycle: Capturing
stdoutandstderrconcurrently, enforcing execution timeouts, cleaning ANSI escape sequences, and managing Unix process group kills to prevent zombie processes required deep dives into process management. Furthermore, detecting changes hidden in truncated command outputs required hashing the raw byte stream continuously while retaining only a safe head and tail for the actual output. - Atomic Concurrency: Serializing concurrent file edits and writes resolving to the same path required a process-local
tokio::Mutexmap to ensure the agent wouldn't corrupt files with race conditions. - Setting up and figuring out evals was hard.
Accomplishments that we're proud of
- Building a Custom MCP Server from Scratch: The Model Context Protocol is still incredibly new, and I am proud to have successfully built a fully functioning MCP server in Rust that natively hooks into the stdio layer to communicate with AI agents.
- The "Smart Proxy" Optimization Engine: I didn't just build basic tools; I built an intelligent proxy that actively computes unified text diffs and content hashes on the fly to drastically reduce the context window load for LLMs. Proving that this actually saves tokens was a huge win!
- Robust Process Management in Rust: Safely capturing
stdoutandstderrstreams concurrently, handling execution timeouts, and managing Unix process group kills to prevent zombie processes is notoriously difficult. I am incredibly proud of getting thebashexecution tool to be safe and memory-efficient. - Dual-Architecture Concurrency: I successfully engineered the system to run the MCP JSON-RPC protocol over
stdiowhile simultaneously running a concurrent HTTP polling API out of the exact same in-memory state. Balancing theRwLockandMutexlocks so neither system blocks the other was a major architectural success. - We managed to set up SWEBench and made our tool pass!! Big W
What we learned
This project pushed our understanding of Rust's tokio ecosystem to the next level, especially around async I/O, child process handling, and stream draining.
We also gained a deep understanding of how dev tools work; they are very different from building regular software and requires a lot of figuring out how the things you use and interact with every day as a developer actually work. There was not a single boring moment, although the path to project submission, like many other projects here, was definitely not smooth and linear!
What's next for Loop-Whole
We plan to open source this and improve it further after stress testing, especially testing more use cases and benchmarks and see how well it holds up. Many thanks to HT6 and sponsors, we had so much fun building this!
Log in or sign up for Devpost to join the conversation.