Back to MCP Servers

Arai

Policy enforcement for AI coding agents derived from existing instruction files (CLAUDE.md, .cursorrules, .windsurfrules, .github/copilot-instructions.md) — no separate YAML to maintain. Rules with prohibitive predicates (`never`, `forbids`, `must_not`) emit `permissionDecision:…

securitygithubaiagent
By taniwhaai
5Updated 2 weeks agoRustApache-2.0

Installation

npx -y arai

Configuration

{
  "mcpServers": {
    "arai": {
      "command": "npx",
      "args": ["-y", "arai"]
    }
  }
}

How to use

  1. Run the installation command above (if needed)
  2. Open your Claude Code settings file (~/.claude/settings.json)
  3. Add the configuration to the mcpServers section
  4. Restart Claude Code to apply changes

Arai

Arai enforces AI coding assistant instruction files (CLAUDE.md, AGENTS.md, .cursorrules, and others) via native hooks. Rules derived from prohibitive language block the tool call outright; advisory rules inject the relevant constraint at the point it applies.

Arai blocking a forbidden command at the PreToolUse hook

Quick Start

curl -sSf https://arai.taniwha.ai/install | sh

cd your-project
arai init

That's it. Arai discovers your instruction files, extracts the rules, classifies their intent, scans your codebase for context, and sets up native hooks so guardrails fire at the right moment.

What It Does

When your AI coding assistant (Claude Code or Grok TUI) is about to do something your rules cover, Arai injects the relevant guardrail — right when it matters. Rules derived from prohibitive predicates (never, forbids, must_not) actually block the tool call instead of just advising.

You: "Create a new database migration"

  PreToolUse: Write migrations/versions/001_add_users.py
  → Arai: deny
    reason: "Alembic never: hand-write migration files"
            [from your rules:12, layer-1 imperative]

Assistant: "I should use alembic revision --autogenerate instead..."

Rules only fire when relevant. No noise on ls. No repeating principles already in your instruction files.

Every firing is written to a local audit log, and every PostToolUse is correlated with the matching PreToolUse to produce a compliance verdict — so you can measure whether the model actually honours the rules you wrote.

How It Works

  1. Discovers instruction files in your project and home directory
  2. Extracts rules by pattern-matching imperative language ("never", "always", "don't", "must")
  3. Classifies each rule's intent — what action it governs, which tools it applies to, when it should fire
  4. Scans your codebase with tree-sitter to understand which tools own which directories
  5. Tracks session state — knows if you've already run tests before pushing
  6. Fires only relevant rules at the right moment via native hooks (where supported)

Supported Instruction Files

FileToolEnforcement
CLAUDE.mdClaude CodeHooks (block + advise)
AGENTS.md / Agents.mdGrok TUI (native)Hooks (block + advise)
~/.claude/CLAUDE.mdClaude Code (global)Hooks (block + advise)
~/.grok/ AGENTS.* filesGrok TUI (global)Hooks (block + advise)
.cursorrules / .cursor/rulesCursorMCP (advise)
.windsurfrulesWindsurfMCP (advise)
.github/copilot-instructions.mdGitHub CopilotIngest only

Rules from every file are parsed, classified, and stored the same way — but enforcement strength depends on what surface the assistant exposes.

  • Claude Code and Grok TUI both support real PreToolUse hooks, so Arai can issue deny decisions and actually block tool calls.
  • Cursor and Windsurf are MCP clients today — they get strong advisory enforcement via the MCP server.
  • GitHub Copilot currently has no live enforcement surface; the file is still ingested for arai stats, arai diff, and the audit log.

Arai hooks several more events alongside the standard tool-call events (when the assistant supports them) so the rule set stays accurate to the live working tree:

  • FileChanged + InstructionsLoaded — when an instruction file (CLAUDE.md, rules-dir, memory file, ...) is edited on disk or loaded into context, Arai spawns an arai scan in the background. The next tool-call hook sees the updated guardrails — no manual rescan.
  • CwdChanged — when Claude cds into a different directory (monorepo navigation), Arai re-scans rooted at the new directory so the next tool call matches against the right project's rules.
  • PostToolBatch — when Claude does a batch of parallel tool calls, Arai correlates each call individually against any PreToolUse firings in the same session, so per-rule compliance verdicts (Obeyed / Ignored / Unclear) stay accurate on parallel workloads.

Smart Matching

Arai doesn't just do keyword matching. It understands your rules:

  • Intent classification — "never hand-write migration files" only fires on Write, not Edit (editing existing migrations is fine)
  • Code graph — writing to migrations/versions/ triggers alembic rules even if the file doesn't mention alembic, because sibling files import it
  • Content sniffing — detects from alembic import op in file content being written
  • Session awareness — "never push without running tests" suppresses after tests have been run
  • Timing routing — domain rules fire on tool calls, principles stay silent (already in CLAUDE.md)
  • Broad imperative coverage — recognises never/always/don't/must, should/shouldn't, cannot/refuse, make sure/be sure, consider/recommend, bare No X prohibitions, conditional shapes (When X, do Y / Before X: do Y / If X → do Y), and the section-aware Use X style-guide pattern. Severity mapping mirrors grammatical weight: should is Inform (soft), should not is Block (the writer chose to call out a specific prohibition).

Compliance & audit

Beyond firing rules, Arai produces a tamper-evident local record of every guardrail decision and correlates it with what the model actually did. This is what tech leads and compliance reviewers want to see — the trail behind the enforcement.

  • Local JSONL audit log — one line per firing at ~/.taniwha/arai/audit/<project>/<YYYYMMDD>.jsonl. Append-only, day-bucketed, queryable with arai audit (filters: --since, --tool, --event, --outcome, --rule). Owner-only on disk (0700 dir / 0600 file on Unix; icacls-pinned on Windows).
  • Hash-chained — actually tamper-evident — every line carries prev_hash and hash (SHA-256 over canonical bytes); the chain is anchored per-day in a .head.YYYYMMDD sidecar. arai audit --verify walks the chain across every day-bucket and exits non-zero on any tamper / reorder / deletion — drop it in a cron or pre-archive job to gate evidence integrity.
  • Retention controlsarai audit --purge --older=90 drops day-buckets older than 90 days; arai audit --purge --project=<slug> wipes a specific project (offboarding / decommission). Today's bucket is always preserved and whole files are deleted (never individual lines), so the hash chain on retained days stays valid. Pair with --dry-run (and --json) for a pre-purge review, or wire into a scheduled job for time-based retention policy.
  • Derivation trace per firing — each rule entry records source file, line number, and parser layer (from CLAUDE.md:42, layer-1 imperative). Auditors can answer "why did this rule fire?" without code spelunking.
  • Compliance verdicts — every PostToolUse is correlated against recent PreToolUse firings to produce Obeyed / Ignored / Unclear per rule. arai stats --by-rule rolls these up into per-rule ratios with a ⚠ flag on rules the model is routing around.
  • Graduated enforcement — severity tiers (Block / Warn / Inform) derive from rule predicate; arai severity pins individual rules so you can ship a rule set in advise mode and escalate one at a time. ARAI_DENY_MODE=off is the project-wide rollback path.
  • Regression-tested policyarai test replays scenarios through the live match_hook pipeline; arai record captures real firings as fixtures. Rule changes become CI assertions, not vibes.
  • No data egress — no network on the hook hot path. Anonymous opt-out telemetry is architecturally separate from the audit log; they share no code path. The audit data physically cannot leak via the telemetry channel. The telemetry queue is hard-capped at 2 MiB on disk.
  • Supply-chain hardened — every install path verifies the binary against published checksums.txt (SHA-256). arai:extends upstream policy fetches refuse loopback / RFC1918 / link-local / cloud metadata and disable redirects; cached upstream policies carry a SHA-256 sidecar so a tampered cache file is detected before its rules reach the parser.
  • MCP authentication — the agent-facing MCP server supports an optional shared-secret via ARAI_MCP_AUTH_TOKEN. When set, initialize must present a matching token (constant-time compare) before any tool call succeeds.

Designed to align with the SOC 2 Trust Service Criteria (CC6.1 logical access, CC6.6 supply-chain, CC7.2 monitoring, CC7.3 detection, CC8.1 change management, CC9.2 vendor management). Arai is not itself a certified product — it gives you the controls and the evidence trail; the certification is yours to pursue. A complete TSC mapping and enterprise / procurement-team feature inventory is in docs/arai-compliance-features.pdf. The Word source (.docx) is committed alongside it for editing.

Enrichment

Three tiers of rule understanding, each more accurate:

arai scan                  # Tier 1: Built-in verb taxonomy (free, instant)
arai scan --enrich         # Tier 2: Sentence transformer model (local, ~80MB download)
arai scan --enrich-llm     # Tier 3a: LLM classification via CLI
arai scan --enrich-api     # Tier 3b: LLM classification via API (no CLI needed)

Configure your LLM:

# Via CLI tool (shell-out)
ARAI_LLM_CMD="claude -p" arai scan --enrich-llm
ARAI_LLM_CMD="ollama run llama3" arai scan --enrich-llm

# Via API (OpenAI-compatible endpoints)
ARAI_API_KEY=sk-... arai scan --enrich-api                    # OpenAI (default)
ARAI_API_URL=http://localhost:11434/v1 arai scan --enrich-api  # Ollama (auto-detected)
ARAI_API_URL=https://api.groq.com/openai/v1 ARAI_API_KEY=gsk-... ARAI_API_MODEL=llama-3.3-70b-versatile arai scan --enrich-api

# Or in ~/.taniwha/arai/config.toml
[enrich]
llm_command = "llm -m gpt-4o-mini"       # for --enrich-llm
api_url = "https://api.openai.com/v1"     # for --enrich-api
api_key_env = "OPENAI_API_KEY"
model = "gpt-4o-mini"

Commands

arai init                  # Discover, extract, classify, scan, set up hooks
arai status                # Show what's being enforced
arai guardrails            # List all active rules
arai why "git push --force" # Explain which rules would fire (dry-run, no audit write)
arai scan                  # Re-scan instruction files
arai scan --code           # Also scan source code (tree-sitter AST)
arai scan --enrich-llm     # Enhance rules via LLM CLI
arai scan --enrich-api     # Enhance rules via API (OpenAI-compatible)
arai add "Never X"         # Add a rule manually
arai audit                 # Inspect the local log of rule firings
arai audit --outcome=ignored # Compliance verdicts where the model ignored a rule
arai audit --rule alembic  # Filter audit by rule subject/predicate/object substring
arai audit --verify        # Verify the SHA-256 hash chain across every day-bucket
arai stats                 # Aggregate audit log — top rules, compliance, token economics
arai stats --by-rule       # Just the per-rule compliance + token economics
arai severity alembic block # Pin a rule's severity (incremental deny rollout)
arai severity --reset alembic # Drop the override; severity reverts to predicate-derived
arai diff CLAUDE.md        # Preview rule-set delta before saving an edit
arai test scenarios.json   # Replay synthetic hook scenarios against rules
arai record --since=1h     # Capture recent firings as a scenario skeleton
arai lint CLAUDE.md        # Parse a file and preview extracted rules
arai trust                 # Manage URLs trusted for shared-policy extends
arai mcp                   # Run the MCP server (stdio) for agent-authored guards
arai upgrade --full        # Switch to full binary (with ONNX enrichment)

Deny mode — actually block bad actions

Starting in v0.2.3, Arai no longer j

View source on GitHub