{
  "markdown": "<!-- mcp-name: io.github.AIops-tools/ai-guardian -->\n\n# AI Guardian\n\n> **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by Ollama, IGEL, or any AI-security vendor.** Product and trademark names belong to their owners. MIT licensed.\n\nGoverned **observability + governance for on-endpoint local LLMs**. It lets you\n**observe + audit what your local models are actually fed, and gate what leaves in\na prompt** — the complement to **IGEL AI Armor**. AI Armor governs *whether* a\nlocal model may run on the endpoint; ai-guardian records *what it did* and gates\n*what goes into the prompt* (secrets, PII, source, jailbreaks) plus *which model*\nmay serve it. Self-contained: it talks to each runtime's REST API and needs\nnothing beyond `httpx` and the MCP SDK. v0.1 provides opt-in route-through\ncontent governance, plus a transparent capture proxy for clients that did not opt in.\n\n### Supported runtimes\n\nOne tool, several **local** runtimes, selected per target by a `runtime` field in\n`config.yaml` (the `init` wizard asks). Ollama uses its native API; the other three\nshare one OpenAI-compatible transport (`/v1/models` + `/v1/chat/completions`).\n\n| Runtime | `runtime` | Default port | List / policy | Scan + route-through guard | Provenance |\n|---------|-----------|:---:|:---:|:---:|-----------|\n| **Ollama** | `ollama` | 11434 | ✅ | ✅ | **digest** (content hash — strong) |\n| **llama.cpp** (`llama-server`) | `llamacpp` | 8080 | ✅ | ✅ | **props** — `/props` model path/size → pinnable id |\n| **LM Studio** | `lmstudio` | 1234 | ✅ | ✅ | **id only** — weaker; pins report `unverifiable` |\n| **vLLM** (local single-node) | `vllm` | 8000 | ✅ | ✅ | **id only** — weaker; pins report `unverifiable` |\n\nThe allow/deny model policy, the deterministic prompt scanner, the route-through\nguard (`guarded_generate` / `observe_chat`), provenance drift, and `doctor` work\nacross **all** runtimes. **Model lifecycle writes** (`pull` / `remove` / `unload`)\nare Ollama-only — the OpenAI-compatible servers load a model at startup and expose\nno lifecycle endpoint, so those writes are refused with a clear message.\n\nProvenance honesty: only Ollama (content digest) and llama.cpp (a `/props`-derived\npath/size identity) expose something to pin. LM Studio and vLLM expose only a model\n**id**, so a pinned digest is reported `unverifiable` rather than a false `DRIFT`.\n\n> **vLLM here is a LOCAL endpoint-guarding use case.** GPU inference-**cluster**\n> operations (autoscale, drain, Ray Serve/Jobs, model lifecycle at fleet scale)\n> belong to a different tool in the line — **GPU cluster ops → inference-aiops**.\n\n## What it does\n\nOllama persists **no queryable prompt/response history** — conversational context\nis client-supplied on every request. So ai-guardian observes on two fronts:\n\n- **Passive inventory / state auditing** — over `/api/tags`, `/api/ps`,\n  `/api/show`, `/api/version`: what models are installed and running, their VRAM\n  residency, license/params/capabilities, and their **provenance digests**. Every\n  model is annotated with an allow/deny **policy verdict**, so shadow\n  (unsanctioned) models show `allowed: false`.\n- **Opt-in route-through content governance** — callers send a prompt *through*\n  ai-guardian (`guarded_generate` / `observe_chat`). It **scans** the text\n  (secrets / PII / source / jailbreak), **checks the model** against policy,\n  **records** the interaction to its own usage log (`~/.ai-guardian/usage.db`),\n  and **only then** calls Ollama — blocking when the risk band is too high or the\n  model is disallowed. The raw prompt is never stored (only its length + redacted\n  findings).\n\n> **Now available** (`ai-guardian proxy serve`): a transparent capture proxy that\n> applies the same scan + model policy + recording to traffic from clients that\n> never opted in — point them at the proxy instead of the runtime. It inspects\n> **requests** and streams responses through untouched, and it is a\n> **chokepoint, not an enforcement boundary**: a client that can still reach the\n> runtime's real port bypasses it entirely. `proxy_guidance` returns the command\n> and that caveat; the CLI prints it on every start.\n\n## Key features\n\n- **Deterministic, offline prompt scanner** — no I/O, no network, so it is fully\n  testable offline. Flags **secrets** (AWS `AKIA`, private-key blocks,\n  GitHub / Slack / OpenAI / Google tokens, JWTs, assigned `api_key=…`, high-entropy\n  fallback), **PII** (email, US SSN, credit card **with a Luhn check**),\n  **source/config-leak** heuristics, and **jailbreak / prompt-injection**\n  signatures — rolled up into a **weighted risk band** (low / medium / high /\n  critical; any critical dominates). Findings are **redacted** — the scanner never\n  re-emits the secret it caught.\n- **Model allow/deny policy** (shell-glob patterns) so shadow / unsanctioned\n  models surface as `allowed: false`, plus **provenance digest pinning** to flag a\n  model whose digest drifted (re-pulled / tampered).\n- **Route-through guard** — `guarded_generate` / `observe_chat` scan + policy-gate\n  + record + run-if-allowed, blocking on risk-band >= `block_threshold` (default\n  `high`) or a disallowed model.\n- **Vendored governance harness** — audit log, token/runaway budget guard,\n  descriptive risk tiers, and undo-token recording, bundled in the package\n  (no external dependency).\n- **Highly self-testable** — Ollama is free + local for the API parts; the\n  scanner, policy, and risk-band are pure deterministic offline logic.\n\n## What this tool does, and does not, decide\n\nIt delivers local-LLM observability and operations — reads and writes —\naccurately, and records every one of them. It does **not** decide whether a\nwrite to the model estate is allowed to happen. That is the agent's judgement,\nor the permission of the host and account you run it under: point it at a\nruntime the account cannot administer — an Ollama daemon whose model store the\nuser can't modify, or an endpoint the agent reaches read-only — and the writes\nfail at the runtime, the place that actually owns the permission. Simplest of\nall, hand the connecting agent only the scan/observe tools.\n\nSo the harness has no read-only switch, no deny-rules file, and no approval gate\nto configure. (Content governance is a separate, product-level thing that stays:\nthe model allow/deny policy and the `guarded_generate` block threshold still\nscan and gate what a model is asked to do.) The one thing the harness guarantees\nis that nothing is silent: **every call, over MCP and over the CLI alike, lands\nan audit row** in `~/.ai-guardian/audit.db`, and destructive writes still capture\ntheir before-state and record an inverse where one exists.\n\n> Each tool declares a `risk_level`, kept in agreement with its `[READ]`/`[WRITE]`\n> documentation tag by a test, and carried into the audit row as a descriptive\n> tier — so a reviewer can see at a glance that a row was a high-risk delete. It\n> is a label, not a gate.\n\nRunning a smaller / local model? See\n[agent-guardrails.md](skills/ai-guardian/references/agent-guardrails.md) — it lists\nthe guardrails this tool now enforces for you (so you don't spend prompt budget\nrestating them) and gives a ready-made system prompt for what's left.\n\n## Capability matrix (21 MCP tools)\n\n### Reads (11)\n\n| Tool | Risk | What it returns |\n|------|:----:|-----------------|\n| `list_models` | low | installed models, each with the allow/deny verdict (shadow → `allowed:false`) |\n| `running_models` | low | loaded models: VRAM footprint + residency expiry |\n| `model_details` | low | license / parameters / capabilities for one model |\n| `server_status` | low | Ollama reachability + version |\n| `vram_usage` | low | total VRAM used by loaded models; flag over-budget |\n| `policy_view` | low | current allow/deny policy + provenance digest pins |\n| `model_provenance` | low | each installed digest vs its pin; flag **drift** |\n| `scan_prompt` | low | pure text scan → findings + weighted risk band (**no model call**) |\n| `usage_events` | low | query the observed-usage log |\n| `anomaly_report` | low | rollup: shadow models, digest drift, high-risk + blocked prompts |\n| `proxy_guidance` | low | the `proxy serve` command + the client change, and the explicit caveat that the proxy is a **chokepoint, not an enforcement boundary**; writes nothing, starts nothing |\n\n### Writes (8)\n\n| Tool | Risk | Undo / safety |\n|------|:----:|---------------|\n| `pull_model` | medium | refused if it violates policy |\n| `remove_model` | **high** | dry-run + undo (re-pull) |\n| `unload_model` | medium | evict from VRAM (`keep_alive:0`) |\n| `set_model_allowlist` | medium | undo → prior allowlist |\n| `set_model_denylist` | medium | undo → prior denylist |\n| `pin_model_digest` | medium | pin a model's expected provenance digest |\n| `guarded_generate` | medium | the route-through guard: scan + policy-gate + record + run-if-allowed |\n| `observe_chat` | medium | same, for `/api/chat` messages |\n\n### Undo (2)\n\n| Tool | Risk | What it does |\n|------|:----:|--------------|\n| `undo_list` | low | list recorded undo tokens |\n| `undo_apply` | medium | replay a recorded inverse descriptor |\n\nRisk-band gating: `guarded_generate` / `observe_chat` **block** when the prompt's\nrisk band `>= block_threshold` (default `high`) **or** the model is disallowed.\nBlocked calls never reach Ollama and are recorded as blocked in the usage log.\n\n## Quick start\n\n### As a Claude Code plugin\n\nOne install gives an agent both the skill and the MCP server:\n\n```\n/plugin marketplace add AIops-tools/marketplace\n/plugin install ai-guardian@aiops-tools\n```\n\nThe MCP server is fetched with [uv](https://docs.astral.sh/uv/) and pinned to the\npackage version this plugin declares, so an audit row can be traced back to the\ncode that wrote it. Credentials are still configured with `ai-guardian init` — see below.\n\n### As a CLI or standalone MCP server\n\n```bash\nuv tool install ai-guardian-aiops          # or: pipx install ai-guardian-aiops\nai-guardian doctor                   # Ollama reachability + policy summary (works zero-config)\nai-guardian overview                 # models installed/running, shadow count, usage stats\nai-guardian model list               # installed models with allow/deny verdicts\nai-guardian guard scan \"my key is AKIAIOSFODNN7EXAMPLE\"   # deterministic scan → risk band\n```\n\nRoute a prompt through the guard (scan + policy-gate + record + run-if-allowed) via\nMCP:\n\n```\nguarded_generate(model=\"llama3.2:3b\", prompt=\"…\", block_threshold=\"high\")\n```\n\nRun as an MCP server (stdio) — the full 21-tool surface; the CLI is a convenience\nsubset:\n\n```bash\nexport AI_GUARDIAN_AIOPS_MASTER_PASSWORD=...   # only if a target has a stored token\nai-guardian mcp                                # or: ai-guardian-mcp\n```\n\n## Governance\n\nEvery operation — MCP **and** CLI — passes through the bundled `@governed_tool`\nharness. It records; it does not authorize (see above).\n\n- **Audit** — every call (params, result, status, duration, risk tier, and any\n  operator-supplied approver/rationale) is logged to `~/.ai-guardian/audit.db`\n  (relocatable via `AI_GUARDIAN_AIOPS_HOME`). This is **separate** from\n  `~/.ai-guardian/usage.db`, which holds the observed local-LLM usage.\n- **Runaway guard** — a safety backstop, not an authorization gate: the same\n  call hammered in a tight loop trips a circuit breaker so a stuck agent can't\n  burn unbounded calls/time. Disable with `AI_GUARDIAN_RUNAWAY_MAX=0`; optional\n  hard ceilings via `AI_GUARDIAN_MAX_TOOL_CALLS` / `AI_GUARDIAN_MAX_TOOL_SECONDS`.\n- **Undo recording** — reversible writes record an inverse descriptor built from\n  the fetched before-state.\n- **Risk tier** — a descriptive label on the audit row derived from\n  `risk_level`; it gates nothing.\n\n## Supported scope + limitations\n\n- **Scope**: on-endpoint **local LLMs** — Ollama plus the OpenAI-compatible\n  llama.cpp / LM Studio / local single-node vLLM — single-endpoint local-LLM\n  observability + content governance. Not GPU inference-cluster ops\n  (→ inference-aiops).\n- **v0.1** = passive inventory/state auditing **plus opt-in route-through content\n  governance**. A **transparent capture proxy** for other clients' traffic is\n  **v0.2 roadmap**, not v0.1.\n- **IGEL AI Armor interop** is **doc-level** positioning today (complementary\n  roles), not a wired integration.\n- **Validation status** — the scanner, policy, and risk-band are pure\n  deterministic offline logic and are exercised as such by the test suite. The\n  core Ollama route-through (real generation + policy deny + undo capture) was\n  exercised against a live Ollama 0.24.0 on 2026-07-13; the rest of the Ollama\n  surface and the OpenAI-compatible dialects (llama.cpp / LM Studio / local\n  vLLM) are still covered by mocked responses only. `ai-guardian doctor` is the\n  fastest live check; see [`docs/VERIFICATION.md`](docs/VERIFICATION.md) for\n  exactly which boxes are ticked.\n\n## Missing a capability?\n\nWant a passive capture proxy, another scanner signature, a richer policy model, or\nan AI Armor hook? **Open an issue or PR — feedback and contributions welcome.**\n",
  "bytes": 13125,
  "sha": "f6a9e602620abbbdfe88e75da82725d3fefcddbadc164e2fa70a55fea07610d5",
  "repo_slug": "aiops-tools/ai-guardian",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_aiops_tools_ai_guardian_a9ea2d4b/readme"
}