OpenRouter launches Armor beta to screen agent tool calls before execution
OpenRouter’s Armor beta uses Jev to check tool calls against rules and user intent before execution. Agents can enable it as a plugin, including for Claude Code auto permissions with other models.

TL;DR
- Armor is OpenRouter’s new beta for screening agent tool calls before execution, using TypeSafe’s Jev model, according to OpenRouter’s announcement.
- User intent affects permission decisions: OpenRouter’s example allows
git pushafter the user asks to push their work. - Claude Code auto permissions extend to other OpenRouter models through Ori, as OpenRouter’s setup post demonstrates.
- Jev 1.13 led accuracy and cost on OpenRouter’s internally generated tool-call test, according to the benchmark post.
Armor uses match thresholds of 0.7 for allow rules and 0.6 for deny rules, after looser exceptions cleared force pushes and repository deletions in testing. It also treats “don’t push until I review” as a built-in soft deny, even without a custom rule.
Rules and user intent
Armor adds a separate policy check between model inference and tool execution.
The documented evaluation flow has four steps:
- OpenRouter holds the proposed tool call instead of forwarding it immediately.
- The decision model receives the call, rules and conversation context.
- It returns a match probability for each rule.
- Armor combines those matches into a
flaggedornot_flaggedverdict.
Policies have three tiers:
hard_deny: A matching action is blocked. Neither user consent nor an allow rule clears it.soft_deny: A matching action is blocked unless an allow rule matches or the user requested that exact operation on that exact target.allow: An exception that clears a soft deny. It never blocks an action itself.
“Clean up the old drafts” does not authorize rm -rf /; explicit consent to delete ./reports/drafts can clear a soft deny for that directory. The documentation’s hard-deny example blocks git push origin main even when the user explicitly requests it.
Claude Code auto permissions
Cross-model auto permissions are the beta’s best trick. OpenRouter’s launch example runs Claude Code with Kimi K3:
Armor reads Claude Code’s safeguards entry and returns the verdict format its auto mode already expects. This path requires no plugins entry, according to the Claude Code integration documentation.
On Anthropic endpoints supporting the safeguard beta, OpenRouter passes through Anthropic’s classifier verdict. Armor evaluates calls on other endpoints.
Custom-agent plugin
Other agents enable Armor through the request’s plugins array, with policies nested under classifier_context.auto_mode.
The configuration schema accepts rules as strings or objects. A request fragment can define a trusted repository and prohibit credential transfers outside it:
environment supplies facts the classifier treats as true. A rule referring to a trusted repository depends on that repository being identified correctly; stale environment facts reduce rule precision.
Claude Code-compatible defaults also differ by API:
- Messages:
use_cc_style_default_rulesdefaults totrue. - Chat Completions and Responses: It defaults to
false.
When enabled, custom rules augment the built-in set and cannot remove its rules.
Benchmarks and evaluation
OpenRouter says Jev 1.13 achieved the highest accuracy and lowest cost on an internally generated tool-call test set, compared with other Decisions models and Claude Code’s use of Sonnet 5.
A separate September classification study measured the same Jev version against Claude Opus 5 on 3,080 Banking77 support utterances. For Opus 5 → Jev 1.13, its published table reports:
- Accuracy: 84.4% → 81.0%, -3.4 points using the rounded table values.
- Median round-trip latency: 2,266 ms → 175 ms, -2091 ms.
- Cost per 1,000 requests: $2.42 → $0.11, -95.5%.
Both models received the same descriptions of 77 banking intents. Opus ran with reasoning disabled, structured output enabled and its shared system prompt cached; latency included the client-observed round trip at eight concurrent requests.
Those measurements describe banking classification, not Armor’s tool-call overhead or plugin pricing.
Blocked-call responses
The blocked-call contract changes with the API and output_mode:
text: The default for Chat Completions and Responses removes the call and inserts an<openrouter_armor_blocked>marker into assistant text.custom_item: Responses replaces the call with anopenrouter:armor_blockeditem containing its identity, arguments and blocking rule.claude_code_compatibility: Messages retains thetool_useand recordsflaggedinsafeguard_results. The client is responsible for declining execution.
A Messages client that ignores safeguard_results can execute a flagged call. In streaming responses, that verdict arrives in the final message_delta event.
For custom_item, the next request echoes the blocked item back unchanged. OpenRouter reconstructs the failed call and its error result for the model’s history; the application does not supply a separate function_call_output for it.
Limitations
Armor’s debugging and failure documentation distinguishes several cases that affect enforcement:
- Audit mode releases every call. It reports the same verdicts without blocking and cannot be combined with
claude_code_compatibility. Enforcement is the default mode. - Classifier failures default to blocking. Timeouts, errors or oversized requests produce an
unavailableresult; the defaulton_error: "block"prevents execution and tells the model evaluation failed. - Provider-native tools can be skipped.
safeguard_resultsusesskippedfor a provider-native tool that ran on the provider’s side. - The response contract is still beta. OpenRouter says configuration fields,
safeguard_resultsand theopenrouter:armor_blockeditem type may change.