Launching today

shim-cli
See what your coding agent sends. Mask what you can.
194 followers
See what your coding agent sends. Mask what you can.
194 followers
An open-source hook and local proxy for Claude Code, Codex, Copilot CLI and VS Code. In Claude Code it masks secrets and personal data in tool results before the model reads them, and shim watch shows what a session sent and cost. No account, no telemetry.











Masking secrets in tool results before the model ever sees them solves the thing that always made me nervous about letting Claude Code run loose, and a local proxy with no telemetry is exactly how I want to audit it.
@karimbenkeroum Thanks, that's the exact use case we had in mind! For auditing, shim audit and shim ledger show keep everything on your machine, and shim watch -- claude gives you a local proxy view of each session. How do you usually run Claude Code: interactive, or with broader permissions on longer tasks? That changes a lot about what we should catch first.
saw the 70ms median hook cost for the interpreter start.
are you intercepting the tool execution locally before the api call
or just proxying the whole network request for claude?
@mohsinproduct Good eye! Yes, most of that cost is interpreter startup, since every hook runs as its own short-lived process.
It's the first one: local interception at the tool boundary. shim installs as Claude Code hooks, so it runs before a tool call (to check what's going out) and right after it (to mask what came back). The masked result is what Claude Code then puts into the next API request. Nothing sits in the network path between you and Anthropic.
That's also why it sees the built-in tools like Read, Bash, Grep and WebFetch, not just MCP servers, which is where a lot of secrets actually show up.
The only proxy is optional and separate: shim watch -- claude runs a loopback proxy on your machine to count tokens and cost per session. It's observation only, the masking doesn't depend on it.
Would a long-running hook process to skip the interpreter start be worth it for you, or is the per-call cost fine at your volume?
Congrats Mertcan and the shim team on the launch. Being upfront about what it can't mask, like typed prompts and failed command output, makes me trust the rest more. When a tool result gets <SECRET_1> instead of the key and the agent then writes that placeholder into a config file or a curl call, does shim swap the real value back on the way out, or does the agent just end up with a broken file?
@genedai Thank you, that means a lot. Being clear about the limits was a deliberate choice.
Short answer: no, shim doesn't swap the real value back. If the agent writes <SECRET_1> into a config file or a curl call, that's what ends up there, so yes, you'd get a broken file or a failed request.
That's on purpose, for two reasons. First, shim never rewrites what goes out through Write, Edit or a shell command, because changing a command or a file payload changes what actually runs on your machine. Second, swapping values back would mean shim keeps your real secrets around to restore them later, and we don't store detected values anywhere.
What works well in practice is having the agent reference the variable (for example $API_KEY or reading it from the environment) instead of inlining the value. Then the model never needs the secret at all.
Have you run into this in a real session, or is it something you're thinking ahead about? I'm curious if a warning when a placeholder shows up in a write would help.