AgentGuard plugin · 0.3.3

Tool policy for Claude Code,
Codex and ChatGPT Work.

Start with a record you keep. Add enforcement when you are ready.

Spawn 16 in 15 minutes. Stopped, recorded, and priced. Override once with a reason if you meant it.
Burn 0.2.6, included in the free workflow. A real local session report, re-rendered for readability. The fixed-prefix bucket totals 113,030 tokens across eight responses, or 86.0% of recorded usage. It includes the system prompt, tool schemas and initial user context, counted with the matching cached prefix on later turns.

Install from the public repository

Choose your host.

Codex and ChatGPT Work

  1. codex plugin marketplace add MerchantGuard/agentguard-codex-plugin
  2. codex plugin add agentguard@agentguard
  3. In the installed plugin root reported by Codex:

    npm ci

Use Node 22. Start a new session, open /hooks, inspect the commands and trust them. Codex 0.154 uses the compatibility installation selected by this marketplace.

Claude Code

  1. claude plugin marketplace add MerchantGuard/agentguard-codex-plugin
  2. claude plugin install agentguard@agentguard
  3. In the installed plugin root reported by Claude Code:

    npm ci

Complete the normal marketplace installation and workspace trust prompts in Claude Code. Use its read-only /hooks menu to inspect the configured plugin hooks. Dependency provisioning differs by host; see the installation details.

AgentGuard checks supported local tool calls against your policy: capability tiers, tool allowlists, ethical-wall denies and configured per-matter or per-agent budgets. Burn handles subagent fan-out and sustained usage. The plugin records signed, content-free decisions and outcomes on your machine, including input digests and sizes instead of document text.

Enforce is free for one machine.

Free · $0Solo · $19 per month, up to three machines
or $190 a year
Team · $199 per month, ten seats
or $1,990 a year
One machine, no account, full Enforce, local signed receipts and Burn. No license key needed.A license key for up to three machines, the dashboard, receipts export and email support.Ten seats, one org policy every seat runs, seats you add and revoke, one invoice. Team includes a 14-day card trial.

The same free and paid split applies in Claude Code, Codex and ChatGPT Work. The plugin uses the existing licenses. See plans and pricing. Activate a key with activate license <KEY> through the agentguard-policy skill.

A record you can inspect

One decision. Its linked outcome.

These are two real signed ledger rows produced by plugin 0.2.1 from synthetic tool events; the current release, 0.3.3, adds a host field to each record and is otherwise the same shape. No document service was called. The outcome describes the supplied test result. This historical receipt from plugin 0.2.1 records the old no-key shadow behavior. Free now defaults to Enforce; the signed example stays unchanged so its signature remains verifiable.

Signed decision

{
  "tool": "mcp__synthetic__get_document",
  "mode": "shadow",
  "action": "shadow",
  "capability": "read_only",
  "inputBytes": 16,
  "decisionId": "1c5e2484-a2a6-4bb0-9cbc-a8c7c9f137df",
  "entryHash": "3a449e32c44f8195074731aace847b31ec95dcd71bdf48841a1c15976f2ee007"
}
Read the complete signed row
{
  "sequence": 0,
  "decision": {
    "actor": {
      "tenantId": "synthetic-example",
      "agentId": "synthetic-example-agent",
      "sessionId": "synthetic-public-example",
      "provider": "synthetic"
    },
    "decisionId": "1c5e2484-a2a6-4bb0-9cbc-a8c7c9f137df",
    "timestamp": "2026-09-19T00:11:10.265Z",
    "action": "shadow",
    "triggeredCap": null,
    "triggeredScopeKey": null,
    "projectedCents": 0,
    "windowSpendBefore": 0,
    "windowSpendAfter": 0,
    "provider": "synthetic",
    "modelRequested": "get_document",
    "modelResolved": "get_document",
    "policyId": "agentguard-codex",
    "policyVersion": 1,
    "enforcementMode": "shadow",
    "reasons": [
      "license_required",
      "tool_policy_allowed"
    ],
    "costBasis": {
      "inputCentsPerKtok": 0,
      "outputCentsPerKtok": 0,
      "rateSource": "override:manual"
    },
    "plugin": {
      "schema": "agentguard.codex.v1",
      "requestId": "22e41f98-66a7-4959-b10c-9a19866c9362",
      "gate": "spend",
      "toolName": "mcp__synthetic__get_document",
      "toolUseId": "synthetic-public-call",
      "sessionId": "synthetic-public-example",
      "agentId": "synthetic-example-agent",
      "inputSha256": "bba2d36669004a3ef16764b0dfe370dfc0c22263976dfd3d896370b3fa39be0d",
      "inputBytes": 16,
      "inputKeys": 1,
      "startedAt": "2026-09-19T00:11:10.262Z",
      "event": "decision",
      "capabilityTier": "read_only",
      "unitCostCents": 0,
      "chargedCents": 0,
      "chargedWindows": [],
      "license": {
        "paid": false,
        "tier": "free",
        "seatsUsed": null,
        "seatLimit": 1,
        "expiresAt": null,
        "mode": "shadow",
        "reason": "license_required",
        "offlineGrace": false
      },
      "reasonCode": "license_required"
    }
  },
  "previousHash": "0000000000000000000000000000000000000000000000000000000000000000",
  "entryHash": "3a449e32c44f8195074731aace847b31ec95dcd71bdf48841a1c15976f2ee007",
  "signature": "6a349c4f635156a96a2b23e796c9091273215d871b2fcdc6290eb7fc8be106470814a6af07972b40727c9fceb214803663efbab5d0dbd84618ab93894c6f1e05",
  "signerFingerprint": "2bd736f15a24c521",
  "publicKeyHex": "454b0a9a00894c91c6a711d9aedb8f0af43648d8740565a3f49e588ece03ac38"
}

Signed outcome receipt

{
  "status": "completed",
  "durationMs": 1,
  "outputBytes": 11,
  "originalDecisionId": "1c5e2484-a2a6-4bb0-9cbc-a8c7c9f137df",
  "entryHash": "c19c32a89ca46b22e6fa5fb720467a5ec7fa08985d66aecfea7f907be01affa1"
}
Read the complete signed row
{
  "sequence": 1,
  "decision": {
    "decisionId": "473fad1b-d62b-4057-8c41-5b344becdbf4",
    "timestamp": "2026-09-19T00:11:10.268Z",
    "action": "allow",
    "triggeredCap": null,
    "triggeredScopeKey": null,
    "projectedCents": 0,
    "windowSpendBefore": 0,
    "windowSpendAfter": 0,
    "provider": "unknown",
    "modelRequested": "outcome-runtime",
    "modelResolved": "outcome-runtime",
    "policyId": "agentguard-codex",
    "policyVersion": 1,
    "enforcementMode": "shadow",
    "reasons": [
      "license_required",
      "Outcome runtime metadata receipt recorded locally"
    ],
    "entryType": "outcome",
    "outcomeReceipt": {
      "flow": "codex-tool",
      "decisionId": "1c5e2484-a2a6-4bb0-9cbc-a8c7c9f137df",
      "status": "completed",
      "durationMs": 1,
      "outputBytes": 11,
      "totalCostCents": 0
    },
    "originalDecisionId": "1c5e2484-a2a6-4bb0-9cbc-a8c7c9f137df",
    "actor": {
      "tenantId": "synthetic-example",
      "agentId": "synthetic-example-agent",
      "sessionId": "synthetic-public-example",
      "provider": "synthetic"
    },
    "plugin": {
      "schema": "agentguard.codex.v1",
      "requestId": "6312891e-b0af-4c52-9400-06f83b9639ce",
      "gate": "receipt",
      "toolName": "mcp__synthetic__get_document",
      "toolUseId": "synthetic-public-call",
      "sessionId": "synthetic-public-example",
      "agentId": "synthetic-example-agent",
      "inputSha256": "bba2d36669004a3ef16764b0dfe370dfc0c22263976dfd3d896370b3fa39be0d",
      "inputBytes": 16,
      "inputKeys": 1,
      "startedAt": "2026-09-19T00:11:10.268Z",
      "outputBytes": 11,
      "success": true,
      "durationMs": 1,
      "durationSource": "host",
      "event": "outcome",
      "decisionId": "1c5e2484-a2a6-4bb0-9cbc-a8c7c9f137df",
      "license": {
        "paid": false,
        "tier": "free",
        "seatsUsed": null,
        "seatLimit": 1,
        "expiresAt": null,
        "mode": "shadow",
        "reason": "license_required",
        "offlineGrace": false
      },
      "reasonCode": "license_required"
    }
  },
  "previousHash": "3a449e32c44f8195074731aace847b31ec95dcd71bdf48841a1c15976f2ee007",
  "entryHash": "c19c32a89ca46b22e6fa5fb720467a5ec7fa08985d66aecfea7f907be01affa1",
  "signature": "1f1d4c21716588ec838c86929eb57838ee3fcbd71763eb9f64d59d7828f5af78870c26a8a3fcdeeb375baf9aac14562c164b8c06da4f59e50773613cc983040e",
  "signerFingerprint": "2bd736f15a24c521",
  "publicKeyHex": "454b0a9a00894c91c6a711d9aedb8f0af43648d8740565a3f49e588ece03ac38"
}

The public fixture verifies as a two-entry chain. Signatures protect the recorded fields; they do not independently attest to an external action. The fixture contains identifiers, digests and sizes, with no tool input or output text.

Coverage and limits.

Hooks cover the local tool calls each supported host sends through its hook path, including plugin MCP tools. Claude Code WebSearch and WebFetch are hookable tools. In Codex and ChatGPT Work, hosted tools such as WebSearch are outside the hook path. Web ChatGPT is unsupported. In Codex, continuing an approved shell session does not create a new pre-tool decision, and some specialized tool paths can opt out.

Hooks are fail-open: an internal error or timeout allows the call and warns when possible. Disabled or untrusted hooks do not govern calls. The plugin is an additional policy layer; service-side authorization remains the boundary for access to documents or payments.

The worker signs and writes a row before replying, then syncs it asynchronously. An unconfirmed tail can be lost on power failure; restart records a signed integrity event when evidence survives. Read the runtime and durability details.

Install a reviewed policy across a firm.

The Codex enterprise guide covers reviewed trust configuration, private marketplaces and managed hook delivery through MDM. Managed delivery does not turn fail-open hooks into fail-closed authorization.