MoorAI runs inside coding agents on developers’ laptops. The same engine runs in front of AI apps and APIs: as a decision API your code calls before a tool runs, as a hook inside an Agent SDK service, as a gateway in front of remote MCP servers, and as a proxy between an agent and its model API. This guide covers where each check sits, what it does, how to keep it out of the agent’s reach, and what has been tested with real clients.
Where the check happens
Each component runs next to the workload it protects. All of them are in the MoorAI agent, which is open source under MIT; the current release is v1.4.1.
| Where the AI acts | MoorAI component | What it checks |
|---|---|---|
| Any agent framework, before a tool runs | moorai-serve sidecar | The tool call your code asks about. A localhost HTTP decision API on 127.0.0.1:8790 answers allow or deny. |
| A service built on the Agent SDK | @moorai/agent-sdk | Every tool call, inside your service’s own process. |
| Remote MCP servers | moorai-mcp-gateway | Every MCP message between the agent and the server, including each tool call and each streamed event. |
| The model API | moorai-model-proxy | What the agent sends to the model and the tool calls that come back, on 127.0.0.1:8791, for Anthropic and OpenAI routes. |
| Coding agents | Hooks | Tool calls and prompts in Claude Code, Codex, Copilot CLI, Cursor and Gemini CLI. |
Which one you need
- Your service runs on the Claude Agent SDK: the in-process hook.
- Another framework, or your own agent loop: the sidecar.
- Your agent uses MCP servers that run somewhere else: the MCP gateway.
- You need to see or control what goes to the model API: the model proxy, in report-only mode first.
- Your developers use coding agents: the hooks, installed with the quick start.
They combine. A service can call the sidecar for its own tools, reach its MCP servers through the gateway and its model through the proxy.
The sidecar: a decision API for any framework
moorai-serve is a localhost HTTP decision API on 127.0.0.1:8790. Before your code runs a tool, it sends the call to the sidecar and gets back the decision MoorAI’s hook would make for that call. Your code does what the answer says. Any language or framework that can make a local HTTP request can use it.
Run it in the agent’s pod or compose network, so the agent reaches it on loopback and no port is opened to the outside. The quick start’s Run it as a sidecar section has the command, the endpoints and the compose and Kubernetes examples.
The Agent SDK hook: in process
For a service built on the Agent SDK, @moorai/agent-sdk registers MoorAI’s hooks inside your service’s own process. The check runs in your code path before each tool call. The model doesn’t decide whether it is consulted.
The MCP gateway: in front of remote MCP servers
moorai-mcp-gateway is an HTTP MCP guard. The agent connects to the gateway, and the gateway connects to the remote server. Every message passes through these checks:
- Staged validation. Each message is checked in order: JSON, JSON-RPC, structure, method, protocol version, schema. A malformed message is refused with
SCHEMA_INVALID. - One value per key. JSON with a repeated key, or with envelope or params keys that differ only in case, is refused. The value MoorAI checks is the value the server runs.
- Every streamed event. In an SSE response, every event is scanned.
- A size cap. A response over 4 MiB is refused with
RESPONSE_TOO_LARGE. - Workload profiles. A declared workload profile is enforced at the gateway.
- Per-tool usage. The gateway counts calls per tool.
- An optional cool-down. A per-client cool-down (
CLIENT_COOLDOWN) is available and off by default.
A tool call that policy denies is refused at the gateway and doesn’t reach the server. The gateway has run in front of a real remote MCP server, an AppCrane MCP endpoint with 62 tools. For the wider question of trusting MCP servers you don’t run, see MCP security.
The model proxy: between the agent and its model API
moorai-model-proxy listens on 127.0.0.1:8791 and serves Anthropic and OpenAI routes. The agent sends its model requests to the proxy, and the proxy forwards them to the provider.
- Report-only by default. Requests pass through byte-identical, and MoorAI reports what it finds.
- Enforce mode. The proxy refuses a request that policy denies or that it can’t scan, withholds denied tool calls, and refuses tool-call JSON that isn’t valid.
The proxy has been tested against a fake provider. It hasn’t yet been run with the providers’ own SDKs or against a real provider, which is why report-only is the place to start.
Keep them out of the agent’s reach
A guardrail the agent can edit isn’t a guardrail. The container image ghcr.io/gitayg/moorai-server holds all three server commands (moorai-serve, moorai-mcp-gateway and moorai-model-proxy), for amd64 and arm64, and runs as a non-root user (uid 1000). Run them in their own container and the agent process can’t edit their policy or files.
Routing is the other half. When your network policy forces the workload’s model and MCP traffic through the proxy and the gateway, the agent can’t route around them. MoorAI doesn’t set that up for you: the restriction is your own network policy.
For coding agents on servers and in CI, MoorAI’s hooks sit in Claude Code’s system-wide managed settings, which a repository can’t switch off. On a laptop the hook runs as the developer, so disabling it is detected, not prevented: an enrolled device sends a daily coverage heartbeat, and the console raises “agent active, no MoorAI hook traffic”. The full breakdown of what is prevented, what is detected and what is out of scope is in tamper resistance and the FAQ.
What leaves your environment
Prompts, code, files and secrets are checked where the agent runs. They aren’t sent anywhere to be checked. The console receives content-free signals about what fired, not the content that fired it. Trust lists what leaves and what stays.
What was tested
On 2026-10-06, on macOS, four real MCP clients ran through MoorAI’s stdio MCP proxy and its HTTP gateway, in front of a test MCP server:
- Handshake and tool list. Claude Code 2.1.284, cursor-agent 2026.05.27,
@modelcontextprotocol/sdk1.32.1 and MCP Inspector 2.9.0 each completed the handshake and listed the server’s tools through both. - Real tool calls, no model. The SDK and the Inspector each made a benign tool call and a denied one. The benign call was forwarded. The denied call was refused, never reached the server, and raised a Blocked alert.
- Live model runs. Three
claude -pruns: a benign call over stdio, a benign call over HTTP, and a denied call over stdio, refused with “MoorAI blocked this MCP tool call”.
Not tested yet
Claude Desktop, VS Code and the Cursor desktop app. Windows and Linux for these real-client runs. OAuth through the gateway. A live, model-driven denied call through the gateway. The model proxy with the providers’ own SDKs or a real provider: it has been tested against a fake provider only.
Questions to ask of any guardrail
Whichever product sits in front of your AI app, these questions separate a check from a log line:
- Where does the check run? In your environment, or in the vendor’s cloud with a copy of your prompts and code?
- Is a denied call stopped before it reaches the server, or recorded after it ran?
- Can the agent switch it off? Ask what is prevented, what is only detected, and on which kind of machine.
- Can the agent route around it? If the answer depends on your network policy, that should be said.
- Which real clients was it tested with, and which were not tested?
MoorAI is open-source (MIT) runtime guardrails for AI agents, apps and APIs. See also: Run it as a sidecar, MCP security, and The layer above the model.