MoorAI for AI Servers: tech specs
Guardrails for the AI apps, agents, RAG pipelines and APIs you ship, running next to each workload. MoorAI runs inside your Agent SDK process, as a localhost sidecar any framework can call, between your agent and its model API, in front of remote MCP servers, and on the connections the workload opens, so prompts, code, files and secrets are not sent anywhere to be checked. All of it is in the MoorAI agent, which is open source (MIT).
The short version is on the MoorAI for AI Servers page.
One engine, at each place the AI acts
Scroll sideways →
| Where the AI acts | MoorAI component | What it checks |
|---|---|---|
| A service built on the Claude Agent SDK | @moorai/agent-sdk | Every tool call, inside your service’s own process |
| Any agent framework, before a tool runs | moorai-serve sidecar | The tool call your code asks about, on 127.0.0.1:8790 |
| The model API | moorai-model-proxy | What the agent sends and the tool calls in the model’s response, on 127.0.0.1:8791 |
| Remote MCP servers | moorai-mcp-gateway | Every MCP message, including each tool call and each streamed event |
| Every other connection | moorai-egress-proxy | The connections routed through it, against your declared egress rules |
| A kernel sandbox | Generated network policy | The same egress rules, as the sandbox’s network policy |
| A retrieval index | Scan before embed | Each chunk, before it is embedded |
They combine. A service can call the sidecar for its own tools, reach its MCP servers through the gateway, its model through the model proxy, and everything else through the egress proxy.
When a component cannot reach a decision (an engine error, its time budget, content past a scan cap), the administrator chooses what happens, per surface: the model proxy, the MCP guard and gateway, and the Inference hooks server each fail open or fail closed, set in the signed policy or the root-owned machine config. Each fail-closed refusal raises a content-free FAIL_CLOSED alert.
One trace across the components. Every agent session is one W3C trace, and a valid incoming traceparent always wins. The model proxy sends traceparent and tracestate on to the provider, the MCP stdio guard puts them in params._meta on each tools/call, the HTTP MCP gateway sends them upstream, and the egress proxy passes a valid one through on plain HTTP or adds one. A tracestate that breaks the grammar or has more than 32 members is discarded whole, and none goes on without a valid traceparent. Each alert and allow-trail record carries traceId, spanId and parentSpanId, so an OTLP backend shows a session’s spans as one trace, and the console’s trace view draws the tree, listing a surface that sent nothing as not reported. With the allow trail on, the model proxy adds one record per forwarded model request with its provider and model. Only hex ids and an agent name leave; the proxies add about 2 to 4 µs per request.
Input and documents coming in; model calls, tool calls and MCP both ways; connections and output going out — each with the MoorAI control at that boundary.
- Placeholder credentials
- Echoed secret masked
- @moorai/agent-sdk, in process
- moorai-serve sidecar
- moorai-model-proxy
- moorai-mcp-gateway
- moorai-egress-proxy
- Tool poisoning in tools/listAML.T0110
- Tool drift: rug-pull, shadowing
- Egress proxy: egress rules
- Sandbox network policy
The open knowledge base of real-world adversarial tactics and techniques used against AI systems — ATT&CK, for AI. A control with an id links to the ATLAS technique its MoorAI rule is mapped to. A control with no id has no mapped rule.
What each one does
Agent SDK, in process
@moorai/agent-sdk returns hooks for the Claude Agent SDK’s query(), so each tool call gets MoorAI’s decision in your code path. Prompts and tool results are scanned; enforce mode blocks a denied prompt.
import { moorAIHooks } from "@moorai/agent-sdk";
query({ prompt, options: { hooks: moorAIHooks({ serviceId: "invoice-agent" }) } })
The moorai-serve sidecar
A localhost decision API for any other agent loop: OpenAI Agents SDK, LangGraph, CrewAI or your own. Your code sends each tool call to POST /v1/tool-call before running it. Verdicts never contain the submitted text.
The model proxy
Point the model SDK’s base URL at moorai-model-proxy. It scans what the agent sends, tool results included, and decides every tool call in the model’s response before the framework runs it. Report-only by default; enforce mode refuses denied requests and tool calls. Hosted APIs and local servers (Ollama, LM Studio, vLLM). Money, bulk-data, identity, destructive and delegation calls alert by default; policy sets allow, ask or block.
File scanning before the model
Optional, off until an administrator sets the policy’s fileScan. The model proxy then checks every inline file, document and image a request carries (Anthropic image and document blocks, OpenAI Chat and Responses image, file and audio parts, Gemini inline data, Ollama images) with MetaDefender Cloud or VirusTotal before it goes upstream, and moorai-serve offers the same check at POST /v1/file-scan. Hash mode sends only the SHA-256; upload mode, a separate opt-in, sends the file the hash lookup did not know (VirusTotal uploads are shared with its community, so keep confidential files off that mode). A malicious file blocks the request or alerts; an unknown one follows onUnknown; a provider error follows the model proxy’s fail mode. A file field is read under every key case Ollama’s parser accepts, and in enforce mode a request that repeats a JSON key or gives one field two case variants is refused. Keys come only from the admin binding, a root-owned key file or the server’s environment, never the signed policy. Alerts are content-free: provider, verdict, engine counts, MIME class, a size bucket and a keyed hash (threat #17).
Task-bound tool calls
Two deterministic checks of a tool call against the person’s task, in the model proxy (a tool call in the model’s reply, before the framework runs it), moorai-serve’s /v1/tool-call and the Agent SDK. Object check (intentArgs): for a high-impact call (a tool the policy names, an MCP write, a money, bulk-data, identity, destructive or delegation function, or a function whose name carries a write verb such as send_email or transfer), every value in its object fields (the keys the policy lists, else recipients, accounts, destinations, paths, URLs, repositories and buckets) must be named in the task, by its whole token, its words, a URL’s host or a path’s file name, or a synonym the policy lists; a number passes when the task names it or it is at or under its cap. A miss is object-not-in-task, decided by intentAlignment: report (the default), ask or block. Task allowlists (taskAllowlists): when a session’s task matches an entry, by keywords or by a task id the service sets over POST /v1/task or the SDK’s setTaskId, only the tools and argument values the entry lists pass (exact strings, globs, numbers and {min, max} ranges, compared as the tool receives them), an argument the entry does not list is denied, and anything else is held at the entry’s "deny" or "ask". A task id only adds entries, and when several apply the strictest wins. A value with a .. segment, a control character or a malformed escape is never allowed. Both read only the signed policy and the root-owned admin binding and fail closed: an entry that cannot be read denies what it would have covered and raises a Task-bound policy invalid alert. Misses alert as Action outside the stated task (threat #64) with the class, the entry’s name and a reason token, never an argument or the task; the task is held in memory as keyed hashes of its words, phrases, tokens and numbers. The endpoint hook runs the same checks on MCP tool calls.
"intentArgs": { "send_email": ["to"], "transfer": ["to_account", "amount"],
"caps": { "transfer.amount": 100 } }
Model provenance pinning
The administrator lists the SHA-256 of each approved model file (modelPins) with modelPinMode report, ask or block, in the root-owned admin binding or the signed policy, never a user file. moorai-model-scan --pin <sha256> (or --policy with modelPins) marks every unpinned file not-approved and exits 1 on one, so a build or deploy step can refuse it; a pin never overrides a static finding. On a device or runner where an agent works under the MoorAI hook, its llama-server -m, vllm serve, ollama run or ollama create, and Python loads of a local path are checked before they run. A pin proves which file runs, not that the file is free of a backdoor; task-bound tool calls check what it then does.
The MCP gateway
An HTTP guard in front of remote MCP servers. Every message is validated and scanned, streamed events included, and a denied tool call is refused before the server sees it.
The egress proxy
Applies your declared egress rules to the connections the workload actually opens: host, port, method and path for HTTP; host and port for HTTPS. Rules come only from the signed policy or the root-owned config.
Sandbox network policy
The same rules become the network policy of a kernel sandbox (Windows MXC, macOS Seatbelt, open-source agent sandboxes), so one rule set drives both layers.
Placeholder credentials
Opt-in. The agent holds a placeholder; the proxy or gateway, out of the agent’s reach, swaps in the real key only on its bound route.
Scan before embed
Each chunk is scanned for injected instructions before it is embedded: in the Agent SDK, on the sidecar’s /v1/index-scan, and in vector-store writes the MCP proxy and gateway see. Reports by default; policy can block.
const addDocs = guardEmbed((docs) => vectorStore.addDocuments(docs), { source: "kb/handbook" });
await addDocs(docs); // under "block", denied documents never reach addDocuments
Out of the agent’s reach, and the only way out
A guardrail the agent can edit isn’t a guardrail. The container image ghcr.io/gitayg/moorai-server holds moorai-serve, moorai-mcp-gateway, moorai-model-proxy and moorai-egress-proxy, for amd64 and arm64, and runs as a non-root user. Run them in their own container and the agent process can’t edit their policy or files.
Routing is the other half. MoorAI’s Kubernetes and docker-compose examples make MoorAI the workload’s only way out:
- Kubernetes (
deploy/k8s/moorai-egress.yaml): the egress proxy, the model proxy and the MCP gateway run in their own pod, and the agent pod’s NetworkPolicy lets it reach only that pod and cluster DNS. They are not sidecars, because a NetworkPolicy selects pods, not containers: a policy that lets a sidecar out would let the agent out too. - docker-compose (
deploy/compose/docker-compose.yml): the agent sits on an internal network, and only the MoorAI containers have a second, outside network.
In both, the agent gets the proxy variables. A tool that ignores them (a raw socket, nc, ssh, a library that dials directly) tries to connect directly and the network drops it: it fails closed. Alerts from the sidecar, the model proxy and the MCP gateway carry the workload’s pod, namespace and node, set through the Kubernetes downward API, so a SIEM can join MoorAI verdicts with host and container sensor events.
Content stays where the AI runs
Prompts, code, files and secrets are checked where the workload runs. The console receives content-free signals about what fired (the category, the risk level, the deciding rule and a keyed one-way hash), never the content that fired it, and alerts carry the workload identity rather than a person. With file scanning turned on, the file’s SHA-256, or in upload mode the file itself, goes to the provider you chose. Every rule is mapped to the OWASP Top 10 for Agentic Applications 2026 and to the OWASP MCP Top 10, still a beta list, with partial credit and its reason recorded. What leaves and what stays: trust.
Everything in MoorAI for AI Servers
For the servers that run models and agents behind your apps: a sidecar container next to model servers and agent services. Built from components of the open-source MoorAI agent (MIT). Priced per server; contact us. Pricing →
- MCP gateway — in front of remote MCP servers: every message validated and scanned, a denied tool call refused before the server sees it
- Model proxy — what the agent sends to the model API, and every tool call in the model’s response, checked before the framework runs it; hosted APIs and local model servers
- Task-bound tool calls — a high-impact call’s target must be named in the request, and a listed task allows only its listed tools and argument values; in the model proxy,
moorai-serveand the Agent SDK - Model provenance pinning — only model files whose SHA-256 an admin approved;
moorai-model-scan --pinexits 1 on any other - File scanning before the model — optional: inline files, documents and images checked with MetaDefender Cloud or VirusTotal, by hash or by opt-in upload, in the model proxy and at
moorai-serve’s/v1/file-scan - Agent SDK and server mode — in-process hooks for Claude Agent SDK services; server mode for agents in CI and containers, where an ask with no approver is denied
- The
moorai-servesidecar — a localhost decision API for any agent framework - Knowledge-base and RAG checks — scan before embed, the index-scan endpoint and MCP vector-store writes, with untrusted business-value claims reported, held or blocked
- One container image for amd64 and arm64, running as a non-root user, out of the agent’s reach
- Content-free records to the Management Server, carrying the workload’s identity (container, pod, namespace and node, where detected)
Guard the AI you ship,
where it runs.
MoorAI for AI Servers is priced per server. Every component runs in your environment, and each ships in the open-source MoorAI agent (MIT).