Hi PH, Mertcan here, one of the makers.
shim-cli started with a question we couldn t answer: what does a coding agent actually send to the model? When Claude Code reads a .env or a customer CSV to debug something, the contents go straight into the request, and you never see that step.
So we built two things. In Claude Code, a local hook masks secrets and personal data in tool results before the model reads them. shim watch shows what a session sent and what it cost. Everything runs on your machine: no account, no telemetry. It s open source (Apache-2.0).
We launch here on October 18. Until then we ll post one short thread a day on how it works and where it falls short.
Haha no more "oops I saw your secret keys, please change them "
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.
The honest limits list is the reason I'd trust this. One question for teams: can enforce mode and the masking rules live in a config file committed to the repo, so every developer's Claude Code picks up the same policy, or is it set per machine? That's what would decide whether a security lead can roll it out to a whole team.
@mertcansaglam masking in the tool result before the model reads it is a clean place to hook in. For detection, is it regex patterns per secret type or an entropy check too? Curious how it treats git SHAs and base64 blobs that look a lot like keys.
masking what agents send is a real need for teams 🔒 usefull for compliance too?
@petrkovacik yes of course, but our company offers better tools for compliance oriented teams: https://getshim.tech/