AdvancedAgent Policy

Agent Policy

Coming Soon: @t402/agent-policy is not yet released. This page describes planned functionality and APIs are subject to change. Follow the GitHub repository for release announcements.

The Agent Policy Engine enables fine-grained control over autonomous AI agent payment authorizations. It provides spending limits, time-based rules, merchant restrictions, network policies, and multi-approver workflows.

Features

  • Spending Limits - Per-transaction, hourly, daily, weekly, and monthly limits
  • Time Rules - Allowed time windows and blocked periods
  • Merchant Rules - Whitelist/blacklist recipient addresses
  • Network Rules - Restrict payments to specific blockchain networks
  • Category Rules - Classify and restrict payments by category
  • Approval Workflow - Threshold-based multi-approver payment approvals
  • Webhook Notifications - HTTP webhooks for approval workflow events
  • MCP Integration - Full Model Context Protocol support for AI agents

Installation

npm install @t402/agent-policy

Quick Start

As MCP Server

Run the MCP server for Claude Desktop or other MCP clients:

# With demo mode (no real state changes)
AGENT_POLICY_DEMO_MODE=true npx agent-policy-mcp
 
# With Redis storage (production)
AGENT_POLICY_REDIS_URL=redis://localhost:6379 npx agent-policy-mcp

Claude Desktop Configuration

Add to your Claude Desktop config:

Edit ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "agent-policy": {
      "command": "npx",
      "args": ["@t402/agent-policy"],
      "env": {
        "AGENT_POLICY_DEMO_MODE": "true"
      }
    }
  }
}

Programmatic Usage

import { AgentPolicyMcpServer, createServerWithRedis } from '@t402/agent-policy/mcp';
 
// In-memory storage (development)
const server = new AgentPolicyMcpServer({ demoMode: true });
 
// Redis storage (production)
const productionServer = await createServerWithRedis('redis://localhost:6379', {
  keyPrefix: 'my-app:agent-policy:',
  demoMode: false,
});

Policy Configuration

Spending Limits

Control how much an agent can spend across different time periods:

{
  limits: {
    perTransaction: { value: '100000000', decimals: 6, symbol: 'USDT' }, // 100 USDT max per tx
    hourly: { value: '500000000', decimals: 6, symbol: 'USDT' },         // 500 USDT/hour
    daily: { value: '1000000000', decimals: 6, symbol: 'USDT' },         // 1,000 USDT/day
    weekly: { value: '5000000000', decimals: 6, symbol: 'USDT' },        // 5,000 USDT/week
    monthly: { value: '10000000000', decimals: 6, symbol: 'USDT' },      // 10,000 USDT/month
  }
}

Time Rules

Restrict when payments can be made:

{
  timeRules: {
    // Allow payments Mon-Fri 9AM-5PM UTC
    allowedWindows: [
      { days: [1, 2, 3, 4, 5], startHour: 9, endHour: 17 }
    ],
    // Block payments during maintenance
    blockedPeriods: [
      {
        start: new Date('2026-01-20T00:00:00Z'),
        end: new Date('2026-01-21T00:00:00Z'),
        reason: 'Scheduled maintenance'
      }
    ],
    timezone: 'UTC'
  }
}

Merchant Rules

Control which addresses can receive payments:

{
  merchantRules: {
    // Only allow payments to these addresses
    whitelist: ['0xaddr1', '0xaddr2', '0xaddr3'],
    requireWhitelist: true,
    // Never allow payments to these addresses
    blacklist: ['0xbadaddr1']
  }
}

Network Rules

Restrict which blockchain networks can be used:

{
  networkRules: {
    // Only allow Base and Ethereum mainnet
    allowedNetworks: ['eip155:8453', 'eip155:1'],
    // Block specific networks
    blockedNetworks: ['eip155:56'] // No BSC
  }
}

Category Rules

Classify and restrict payments by category:

{
  categoryRules: {
    allowedCategories: ['api_usage', 'subscription', 'data_storage'],
    blockedCategories: ['gambling', 'adult_content']
  }
}

Approval Workflow

For high-value payments, require human approval before execution.

Configuration

{
  approvalConfig: {
    thresholds: [
      {
        // Payments >= 100 USDT require 1 approver
        amount: { value: '100000000', decimals: 6, symbol: 'USDT' },
        requiredApprovers: 1,
        approvers: ['admin@example.com', 'manager@example.com']
      },
      {
        // Payments >= 1000 USDT require 2 approvers
        amount: { value: '1000000000', decimals: 6, symbol: 'USDT' },
        requiredApprovers: 2,
        approvers: ['admin@example.com', 'manager@example.com', 'cfo@example.com']
      }
    ],
    timeout: 3600000 // 1 hour timeout for approvals
  }
}

Approval Flow

Agent Requests Payment

The agent calls agent-policy/authorize with the payment details.

Policy Engine Evaluates

The engine checks time rules, merchant rules, network rules, spending limits, and approval thresholds.

Approval Created (if needed)

If the amount exceeds a threshold, a pending approval is created and the budget is reserved.

Approvers Notified

Authorized approvers receive notifications (via webhook if configured).

Decision Submitted

Approvers submit decisions via agent-policy/approvals/decide.

Payment Proceeds or Rejected

Once enough approvals are collected, payment proceeds. If denied, budget is released.

Example

// 1. Set up policy with approval thresholds
await server.handleToolCall('agent-policy/set', {
  agentId: 'agent-123',
  policy: {
    enabled: true,
    limits: { daily: { value: '10000000000', decimals: 6 } },
    approvalConfig: {
      thresholds: [{
        amount: { value: '100000000', decimals: 6 },
        requiredApprovers: 1,
        approvers: ['admin@company.com'],
      }],
      timeout: 3600000,
    },
  },
});
 
// 2. Agent requests payment (500 USDT - needs approval)
const result = await server.handleToolCall('agent-policy/authorize', {
  agentId: 'agent-123',
  amount: '500000000',
  recipient: '0xvendor...',
  network: 'eip155:8453',
});
// Returns: { requiresApproval: true, approvalId: 'uuid' }
 
// 3. Approver submits decision
await server.handleToolCall('agent-policy/approvals/decide', {
  approvalId: result.data.approvalId,
  decision: 'approve',
  approver: 'admin@company.com',
});

MCP Tools Reference

ToolDescription
agent-policy/authorizeCheck if a payment is authorized
agent-policy/budgetGet remaining budget for an agent
agent-policy/getGet current policy configuration
agent-policy/setSet or update policy configuration
agent-policy/listList all policies
agent-policy/confirmConfirm a payment reservation
agent-policy/releaseRelease a payment reservation
agent-policy/approvals/listList pending approvals
agent-policy/approvals/getGet approval details
agent-policy/approvals/decideSubmit approval decision

Webhook Notifications

Get notified of approval events via HTTP webhooks:

const server = await createServerWithRedis('redis://localhost:6379', {
  webhookEndpoints: [
    {
      url: 'https://api.example.com/webhooks/approvals',
      secret: 'your-hmac-secret',
      events: ['approval.created', 'approval.approved', 'approval.denied'],
    },
  ],
});

Events

EventDescription
approval.createdNew approval request created
approval.decision_submittedApprover submitted decision
approval.approvedPayment approved
approval.deniedPayment denied
approval.expiredApproval timed out

Webhook Payload

{
  "event": "approval.created",
  "timestamp": "2026-01-19T10:30:00.000Z",
  "approval": {
    "id": "approval-uuid",
    "agentId": "agent-123",
    "status": "pending",
    "amount": "500 USDT",
    "recipient": "0x1234...",
    "network": "eip155:8453"
  }
}

Signature Verification

Webhooks include HMAC-SHA256 signature in X-Webhook-Signature header:

import { createHmac } from 'crypto';
 
function verifyWebhookSignature(payload: string, signature: string, secret: string): boolean {
  const expected = 'sha256=' + createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return signature === expected;
}

Environment Variables

VariableDescriptionDefault
AGENT_POLICY_DEMO_MODEEnable demo modefalse
AGENT_POLICY_REDIS_URLRedis URLIn-memory
AGENT_POLICY_WEBHOOK_URLWebhook endpointNone
AGENT_POLICY_WEBHOOK_SECRETHMAC secretNone
AGENT_POLICY_WEBHOOK_EVENTSEvent filterAll

Architecture

┌─────────────────────────────────────────────────────────────┐
│                   MCP Client (Claude)                        │
└─────────────────────────────────────────────────────────────┘
                            │ stdio

┌─────────────────────────────────────────────────────────────┐
│                 AgentPolicyMcpServer                         │
│  ┌─────────────┐  ┌───────────────┐  ┌─────────────────┐    │
│  │Tool Handler │──│ PolicyEngine  │──│ SpendingLimiter │    │
│  └─────────────┘  └───────────────┘  └─────────────────┘    │
│         │                │                    │              │
│         │         ┌──────▼─────────┐         │              │
│         │         │ApprovalManager │─────────┤              │
│         │         └────────────────┘         │              │
│         ▼                ▼                   ▼              │
│  ┌─────────────┐  ┌───────────────┐  ┌─────────────────┐    │
│  │ PolicyStore │  │ RuleEvaluator │  │   LimitStore    │    │
│  │ (In-Memory  │  │               │  │ (In-Memory or   │    │
│  │  or Redis)  │  │               │  │     Redis)      │    │
│  └─────────────┘  └───────────────┘  └─────────────────┘    │
└─────────────────────────────────────────────────────────────┘

TypeScript Types

interface AgentPolicy {
  enabled: boolean;
  limits?: SpendingLimits;
  timeRules?: TimeRules;
  merchantRules?: MerchantRules;
  networkRules?: NetworkRules;
  categoryRules?: CategoryRules;
  approvalConfig?: ApprovalConfig;
}
 
interface SpendingLimits {
  perTransaction?: Amount;
  hourly?: Amount;
  daily?: Amount;
  weekly?: Amount;
  monthly?: Amount;
}
 
interface Amount {
  value: string;      // Raw value as string (bigint-safe)
  decimals: number;   // Token decimals (e.g., 6 for USDT)
  symbol?: string;    // Token symbol
}
 
interface PolicyDecision {
  allowed: boolean;
  reason?: string;
  reservationId?: string;
  requiresApproval?: boolean;
  approvalId?: string;
}