1. Conduid
  2. Science
  3. Actionfence
MCP server · Science

Actionfence

Embeddable AI action firewall for MCP servers and APIs with JSON policies, signed receipts, spend caps, and simulation mode

37Low

Scored 5 months ago · breakdown

About Actionfence

Actionfence is an MCP server in the Science category: embeddable AI action firewall for MCP servers and APIs with JSON policies, signed receipts, spend caps, and simulation mode.

Install

Claude Code
claude mcp add actionfence -- npx -y actionfence
npx
npx -y actionfence

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Ask AI

✦

Ask AI about Actionfence

Powered by Claude · Grounded in docs

I know everything about Actionfence. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

  • ✓README presentThe repository ships documentation.

5 checks have not been run yet.

README

ActionFence

AI Action Firewall for MCP servers and APIs.

One line of code. Signed receipts. Simulation mode.

CI Node.js

Why ActionFence?

AI agents can now book flights, send emails, and delete records in your system — often without you knowing until the invoice arrives. ActionFence lets you define exactly what they're allowed to do, and proves every decision with a signed receipt.

It sits in front of your MCP tools or HTTP routes and decides whether an incoming agent action is allowed before your real handler runs.

It gives you:

  • Policy enforcement from guard-policy.json
  • Identity tiers: anonymous, token, verified
  • Built-in verified JWT support via JWKS
  • Capability scope checks from JWT capabilities
  • Per-action spend caps plus session/day spend limits
  • Request and transaction rate limiting
  • Signed, hash-chained receipts in SQLite
  • Simulation mode for dry-run previews

Install

npm install actionfence

Quick Start

MCP Server

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { withGuard } from 'actionfence';

const server = new McpServer({ name: 'my-server', version: '1.0.0' });

withGuard(server, {
  policy: './guard-policy.json',
  identityReaderOptions: {
    jwksUri: 'https://issuer.example/.well-known/jwks.json',
    issuer: 'https://issuer.example',
    audience: 'bookflight-mcp',
  },
});

server.registerTool('search_flights', {}, async () => {
  return { content: [{ type: 'text', text: 'results...' }] };
});

Express / Fastify

import express from 'express';
import { guard } from 'actionfence';

const app = express();
app.use(express.json());

app.use(
  guard({
    policy: './guard-policy.json',
    identityReaderOptions: {
      jwksUri: 'https://issuer.example/.well-known/jwks.json',
      issuer: 'https://issuer.example',
      audience: 'bookflight-api',
    },
    actionResolver: (toolName) => {
      if (/^GET \/bookings\/[^/]+$/.test(toolName)) {
        return 'GET /bookings/:id';
      }
      return toolName;
    },
    spendExtractor: (params) => {
      const body = (params as { body?: { amount?: number } })?.body;
      return body?.amount ?? null;
    },
  }),
);

CLI

npx actionfence init
npx actionfence validate guard-policy.json
npx actionfence simulate guard-policy.json --action book_flight --identity verified --spend 250

Using an AI Coding Assistant?

Copy this prompt into Claude, Cursor, Copilot, or any LLM and let it handle the setup:

Install and integrate the "actionfence" npm package into my current project. Read the full integration guide at https://raw.githubusercontent.com/saifeldeen911/actionfence/main/llms-full.txt then: install the package, create a guard-policy.json for my use case, and wire up the middleware.

Storage

ActionFence stores signed receipts in SQLite by default (zero-config). For serverless or horizontally-scaled deployments, use PostgreSQL:

PostgreSQL Setup

  1. Install the pg driver:

    npm install pg
    
  2. Configure storage in your guard setup:

    withGuard(server, {
      policy: './guard-policy.json',
      storage: {
        adapter: 'postgres',
        connectionString: process.env.DATABASE_URL,
      },
    });
    

ActionFence auto-creates the actionfence_receipts table on first use.

Policy File

guard-policy.json defines what agents can do in your system.

{
  "$schema": "https://raw.githubusercontent.com/saifeldeen911/actionfence/main/schemas/guard-policy.schema.json",
  "service": "BookFlight.com",
  "version": "1.0",
  "default_rule": "deny",
  "actions": {
    "search_flights": {
      "allowed": true,
      "identity": "any"
    },
    "book_flight": {
      "allowed": true,
      "identity": "verified",
      "max_spend": 500,
      "currency": "USD",
      "requires_human_approval": true
    },
    "bulk_booking": {
      "allowed": false
    }
  },
  "rate_limits": {
    "requests_per_minute": 30,
    "transactions_per_day": 5
  },
  "spend_limits": {
    "session_max": 1000,
    "daily_max": 2500,
    "currency": "USD"
  },
  "regulations": ["EU_AI_Act_Art50"]
}

Policy Reference

Field Type Required Notes
service string Yes Service name
version string Yes Policy version
default_rule "allow" | "deny" No Defaults to "deny"
actions object Yes Action rules keyed by action name
rate_limits object No Request and transaction limits
spend_limits object No Global session/day spend limits in major units
regulations string[] No Stored (persisted) in v0.1.0 but not enforced

Action Rule Fields

Field Type Default Notes
allowed boolean - Required
identity "any" | "token" | "verified" "any" Minimum identity tier
max_spend number - Per-invocation cap in major units
currency string - ISO 4217 currency code
requires_human_approval boolean false In 0.1.0: flags the decision in the receipt and fires the onDecision callback so you can build your own approval flow. Built-in approval workflow is planned for a future release.

Identity Tiers

Tier Meaning
anonymous No credentials presented
token Bearer token present but not signature-verified
verified JWT passed JWKS verification

Verified identity is built in when you configure identityReaderOptions.jwksUri and JWKS lookup succeeds from cache or the remote endpoint. If JWKS retrieval or network access fails, ActionFence may fall back to token identity; invalid signatures, wrong issuers or audiences, unknown kids, and other cryptographic verification failures stay anonymous or rejected.

Scope Enforcement

If a decoded or verified token includes a capabilities claim, ActionFence treats it as an exact allowlist of policy action names. A request that passes policy checks but is not listed in capabilities is blocked.

Simulation Mode

Simulation mode runs the full policy pipeline without executing the handler or storing a receipt.

MCP

withGuard(server, {
  policy: './guard-policy.json',
  simulate: true,
});

Express

app.use(
  guard({
    policy: './guard-policy.json',
    simulate: true,
  }),
);

CLI output

actionfence simulate guard-policy.json --action book_flight --identity verified --spend 250

SIMULATION - actionfence

  Action:          book_flight
  Tool:            book_flight
  Identity:        verified
  Status:          PASS
  Spend:           250.00
  Session total:   250.00
  Daily total:     250.00
  Human approval:  required
  Rate limit:      29/30 remaining

Action Receipts

Every enforced decision stores a signed receipt in SQLite.

receipt_id:     a1b2c3d4-...
timestamp:      2026-05-07T14:02:11Z
agent_id:       agt_7x9f2k...
action:         book_flight
status:         PASSED
payload_hash:   0x8f3a...
prev_hash:      0x7e2d...
receipt_sig:    0x4f9b...

Receipts are:

  • Hash-chained
  • HMAC-SHA256 signed
  • Append-only
  • Verifiable with ReceiptStore.verifyChain()

Note: Receipts are stored in a local SQLite file (.actionfence/receipts.db) by default. This works perfectly for single-instance deployments. If you run multiple server instances, use the postgres storage adapter to maintain a single global receipt chain.

Signing key resolution order:

  1. options.secret
  2. ACTIONFENCE_SECRET
  3. .actionfence/key

API Reference

withGuard(server, options)

const guardInstance = withGuard(server, {
  policy: './guard-policy.json',
  simulate: false,
  silent: false,
  secret: process.env.ACTIONFENCE_SECRET,
  identityReaderOptions: {
    jwksUri: 'https://issuer.example/.well-known/jwks.json',
    issuer: 'https://issuer.example',
    audience: 'bookflight-mcp',
  },
  actionResolver: (toolName, params) => toolName,
  spendExtractor: (params) => null,
  onDecision: (decision) => {},
  watchPolicy: true,
});

guardInstance.dispose();

guard(options)

const middleware = guard({
  policy: './guard-policy.json',
  identityReaderOptions: {
    jwksUri: 'https://issuer.example/.well-known/jwks.json',
  },
});

GuardOptions

Option Type Default Notes
policy string | GuardPolicy - Required
simulate boolean false Dry-run mode
silent boolean false Suppress console output
secret string - HMAC secret override
identityReaderOptions IdentityReaderOptions - Built-in JWKS verification config
identityReader IdentityReaderLike - Full custom identity resolution override
actionResolver (toolName, params) => string - Map tool names to policy actions
spendExtractor (params) => number | null - Extract spend in major units
transactionResolver (toolName, params, decision) => boolean - Override transaction classification
onDecision (decision) => void - Metrics, logging, hooks
watchPolicy boolean false Hot-reload file-backed policies
storage StorageConfig - Storage backend (SQLite/PostgreSQL)

IdentityReaderOptions

Field Type Notes
jwksUri string Remote JWKS endpoint
issuer string | string[] Optional issuer check
audience string | string[] Optional audience check

Current Limitations

  • Capability checks are exact string matches only
  • No APoP / LAS-WG adapters yet
  • No wildcard scope patterns or path-policy DSL
  • requires_human_approval flags the receipt and fires onDecision — no built-in approval workflow yet (use the callback to build your own)
  • Money is major-unit only; mixed-currency accounting is out of scope for one policy
  • SQLite storage is single-instance only (use the postgres adapter for multi-instance deployments)

CLI Reference

actionfence init

actionfence init
actionfence init --service MyAPI
actionfence init --output ./policies/guard-policy.json

actionfence validate <path>

actionfence validate guard-policy.json

actionfence simulate <path>

actionfence simulate guard-policy.json --action search_flights
actionfence simulate guard-policy.json --action book_flight --identity verified --spend 250

Examples

Development

git clone https://github.com/saifeldeen911/actionfence.git
cd actionfence
npm install
npm run typecheck
npm run lint
npm test
npm run build

License

MIT (c) Saifeldeen

README copy captured when this server was indexed; it may lag the repository. The original is authoritative.

Questions

About Actionfence

How do I install Actionfence?

Run claude mcp add actionfence -- npx -y actionfence, then add the server to your MCP client's configuration.

Is Actionfence safe to use with an AI agent?

Its trust score is 37 out of 100 (low). It passes 1 of the 1 static security checks run so far. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Actionfence still maintained?

Conduid hasn't recorded a commit date for this repository yet. Check the repository directly for recent activity.