Protect your agents
memnox protect # detects Claude Code and Cursor, installs both
memnox protect claude-code # or name one explicitly
memnox protect cursormemnox setup already did this. protect is for adding a surface later, or for
a machine where setup ran before the editor was installed.
The four surfaces
An agent has to be stopped somewhere, and where depends on what it is running inside. Four mechanisms, all asking the same runtime the same question.
Where the agent is caught
Claude Code
PreToolUse hookallowblockrequire approval — not available hereredact — not available here
Cursor
agent hooksallowblockrequire approvalredact — not available here
Any MCP client: Windsurf, Zed, Codex, …
@memnox/mcp-firewallallowblockrequire approvalredact
Custom loops: OpenAI Agents SDK, LangGraph, CrewAI
governTool / governToolsallowblockrequire approvalredact
One answer, four shapes
allowblockrequire approvalnot everywhereredactnot everywhereRead the struck-through words. A surface that cannot carry a verdict does not
ignore it, it refuses instead. Ask Claude Code's hook for an approval and it
denies, because exit 2 is the only "no" the hook has; ask either editor to mask
a payload and it denies, because neither can hand back a rewritten call. Refusing
is the safe direction, but it is not the behaviour the rule described, so a rule
that leans on redact belongs on a surface that can perform it.
Cursor is the closest fit of the two editors: its allow / deny / ask are
Memnox's allow, block, and require-approval exactly. Nobody engineered that
match, and it is why the integration is honest rather than approximated. Cursor
also fires afterFileEdit, which Memnox records but cannot act on: by the time
it arrives the edit has already landed.
The MCP firewall
An MCP server does two things for your agent: it offers a list of tools, and it runs the ones the agent picks. The firewall stands between the two.
Your client stops launching the server directly. It launches the firewall, and the firewall launches the server, so every message between them passes through Memnox on the way.
On the list, a denied tool is removed rather than left there to fail. The agent never learns it existed, so it never proposes it, argues for it, or works around it. A tool that fails when called teaches an agent to try something else; a tool that was never on the menu teaches it nothing.
On the call, the check runs again. A client can call a tool it was never offered, so the listing is not treated as a promise.
Point your client at the firewall instead of the server:
MEMNOX_AGENT_TOKEN=mnx_... memnox-mcp-firewall \
--name github -- npx -y @modelcontextprotocol/server-githubPart
MEMNOX_AGENT_TOKEN--name <server-name>--So the last part of that line is exactly what your MCP client used to run. The firewall runs it for you, and sits in front of it.
This is also the surface where redact genuinely works. Because the firewall
is holding the call rather than voting on it, it can rewrite the payload: mask
the secret, forward the rest. An editor hook has only yes and no, so the same
rule there comes out as a refusal.
Custom agent loops
import { MemnoxClient, governTools } from '@memnox/sdk';
const memnox = new MemnoxClient({
baseUrl: 'http://127.0.0.1:7466',
token: agentToken,
});
const tools = governTools(memnox, { readFile, writeFile, runShell }, {
sessionId: runId,
environment: 'production',
});Same signatures, same framework wiring, each call is now decided before it runs.
Or wrap a single dangerous operation:
await memnox.guard(
{ action: 'code.modify', target: 'payment/checkout.ts' },
async () => { await applyChanges(); },
);guard runs the callback only if the runtime allows it. check returns the
verdict for you to inspect instead.
The token, and why it is on disk
memnox setup writes the agent token to ~/.memnox/config.json, mode 0600.
That is deliberate. A GUI-launched editor inherits no shell environment, so
an exported MEMNOX_AGENT_TOKEN never reaches it, and a hook with no credential
allows everything, which looks exactly like being protected.
The environment still wins when it is set, which is how CI and the MCP firewall pass a token.
Registering agents
memnox agents register --name ci-deployer --kind custom
memnox agents list
memnox agents suspend <id>
memnox agents rotate <id>Part
--name <name>--kind <kind><id>register prints the agent's token once. Copy it then; there is no command
that shows it again, only rotate, which issues a new one.
Capabilities
Capabilities are the cheapest control in the product. They are wildcard action patterns checked before policy runs, so an agent registered to read cannot argue its way into a write regardless of what the policy file says. A denial here never consults your rules at all.
They are set when the agent is registered, and the CLI has no flag for them, so this is one of the few places you call the API directly:
curl -X POST http://127.0.0.1:7466/v1/agents \
-H "Authorization: Bearer $MEMNOX_ADMIN_TOKEN" \
-H "content-type: application/json" \
-d '{"name":"ci-deployer","kind":"custom","capabilities":["deploy.*","file.read"]}'capabilities is an array of patterns, where * stands for any remainder:
deploy.* covers deploy.service and deploy.worker, while file.read covers
that one action alone. Leave the field out and the agent may attempt anything,
which is rarely what you want. The route needs an admin credential, and it
returns the new agent's token in the response: the same once-only token
register prints.
Register narrowly. A CI agent that only deploys should not carry *.
Fail-open, and why
The hook has to reach the runtime. If the runtime is down, the hook fails open: a dead process never blocks development.
That is the right trade for a laptop and the wrong one for a server. In a
deployment where the gate is load-bearing, run the runtime supervised, alert on
GET /healthz, and use --default-effect block so an ambiguous state refuses
rather than permits.
CI
memnox ci # exits 1 on a blocking finding in the branch's diffRun it in the pipeline that already runs your tests. It scans the diff for secrets and personal data, so a leaked credential is caught by a person in review rather than by an agent at runtime.
It is a content scan, not a full policy evaluation. Policy still decides what
an agent may do; memnox ci decides whether what was written is safe to commit.

