npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@the-bot-club/agentguard

v0.9.0

Published

AgentGuard SDK — policy engine, audit trail, kill switch, and LangChain/OpenAI integrations

Downloads

488

Readme

@the-bot-club/agentguard

Runtime security for AI agents — policy engine, audit trail, kill switch, and cloud API client.

npm version License: MIT

Overview

AgentGuard gives you production-grade guardrails for AI agents:

  • 🛡️ Policy Engine — evaluate tool calls against a YAML policy DSL (local, zero-latency)
  • 📋 Audit Trail — append-only, tamper-evident hash chain of every action
  • 🔴 Kill Switch — instantly halt one agent or all agents
  • 🌐 Cloud API Client — connect to the hosted AgentGuard API
  • 🔗 Framework Integrations — one-liner guards for LangChain, OpenAI, CrewAI, Express, and Fastify

Installation

npm install @the-bot-club/agentguard

Requires Node.js 18+ (uses native fetch).


Quick Start — Cloud API Client

import { AgentGuard } from '@the-bot-club/agentguard';

const guard = new AgentGuard({ apiKey: 'ag_your_api_key' });

// Evaluate an agent action before executing it
const decision = await guard.evaluate({
  tool: 'send_email',
  params: { to: '[email protected]', subject: 'Hello' },
});

if (decision.result === 'allow') {
  // Safe to proceed
  console.log('Action allowed, risk score:', decision.riskScore);
} else if (decision.result === 'block') {
  console.error('Action blocked:', decision.reason);
} else if (decision.result === 'require_approval') {
  console.log('Waiting for human approval...');
}

Get Usage Statistics

const usage = await guard.getUsage();
console.log(usage);

Get Audit Trail

const audit = await guard.getAudit({ limit: 50, offset: 0 });
console.log(audit.events);

Activate Kill Switch

// Halt all agents immediately
await guard.killSwitch(true);

// Resume operations
await guard.killSwitch(false);

Webhooks

// Register a webhook endpoint
const webhook = await guard.createWebhook({
  url: 'https://example.com/hooks/agentguard',
  events: ['action.blocked', 'killswitch.activated'],
  secret: 'my-signing-secret', // optional
});
console.log('Webhook ID:', webhook.id);

// List all webhooks
const { webhooks } = await guard.listWebhooks();

// Remove a webhook
await guard.deleteWebhook('wh_abc123');

Agents

// Register an agent
const agent = await guard.createAgent({
  name: 'email-agent',
  policyScope: { allowedTools: ['send_email', 'read_inbox'] }, // optional
});
console.log('Agent ID:', agent.id);

// List all agents
const { agents } = await guard.listAgents();

// Remove an agent
await guard.deleteAgent('ag_abc123');

Templates

// Browse available policy templates
const { templates } = await guard.listTemplates();

// Inspect a template
const template = await guard.getTemplate('strict');
console.log(template.rules);

// Apply a template to your tenant
await guard.applyTemplate('strict');

Rate Limits

// Set a tenant-wide rate limit: max 100 requests per 60 seconds
const limit = await guard.setRateLimit({ windowSeconds: 60, maxRequests: 100 });

// Scope to a specific agent
await guard.setRateLimit({ agentId: 'ag_abc123', windowSeconds: 60, maxRequests: 20 });

// List all rate limits
const { rateLimits } = await guard.listRateLimits();

// Delete a rate limit
await guard.deleteRateLimit(limit.id);

Cost

// Get overall cost summary
const summary = await guard.getCostSummary();

// Filter by agent and date range
const filtered = await guard.getCostSummary({
  agentId: 'ag_abc123',
  from: '2024-01-01',
  to: '2024-01-31',
  groupBy: 'day',
});

// Per-agent cost breakdown
const agentCosts = await guard.getAgentCosts();

Dashboard

// High-level stats (requests, blocks, risk scores)
const stats = await guard.getDashboardStats();

// Live activity feed
const feed = await guard.getDashboardFeed();

// Feed from a specific timestamp onward
const recent = await guard.getDashboardFeed({ since: '2024-06-01T00:00:00Z' });

// Per-agent activity summary
const activity = await guard.getAgentActivity();

PolicyEngine — Local Evaluation

For zero-latency, in-process policy evaluation without a network call:

import { PolicyEngine, PolicyBundle } from '@the-bot-club/agentguard';

// Load your compiled policy bundle (from AgentGuard Control Plane or local YAML)
const bundle: PolicyBundle = {
  policyId: 'my-policy',
  version: '1.0.0',
  compiledAt: new Date().toISOString(),
  defaultAction: 'block',
  rules: [
    {
      id: 'allow-read-tools',
      priority: 100,
      action: 'allow',
      toolCondition: { in: ['read_file', 'list_directory', 'search'] },
      paramConditions: [],
      contextConditions: [],
      dataClassConditions: [],
      timeConditions: [],
      severity: 'low',
      riskBoost: 0,
      tags: ['read-only'],
    },
    {
      id: 'block-delete',
      priority: 200,
      action: 'block',
      toolCondition: { matches: ['*delete*', '*remove*', '*drop*'] },
      paramConditions: [],
      contextConditions: [],
      dataClassConditions: [],
      timeConditions: [],
      severity: 'critical',
      riskBoost: 500,
      tags: ['destructive'],
    },
  ],
  toolIndex: {
    '*': [0, 1],
  },
  checksum: 'abc123',
  ruleCount: 2,
};

const engine = new PolicyEngine(bundle);

const decision = engine.evaluate({
  id: crypto.randomUUID(),
  agentId: 'agent-1',
  tool: 'read_file',
  params: { path: '/data/config.json' },
  inputDataLabels: [],
  timestamp: new Date().toISOString(),
});

console.log(decision.result);    // 'allow'
console.log(decision.riskScore); // 0

AuditLogger

import { AuditLogger } from '@the-bot-club/agentguard';

const logger = new AuditLogger();

// Log an action decision
const event = logger.log({
  agentId: 'agent-1',
  sessionId: 'session-abc',
  policyVersion: '1.0.0',
  tool: 'send_email',
  params: { to: '[email protected]' },
  decision: 'allow',
  matchedRuleId: 'allow-email',
  monitorRuleIds: [],
  riskScore: 10,
  reason: 'Matched allow-email rule',
  durationMs: 1.2,
});

// Verify the entire audit chain
const { valid, invalidAt } = logger.verify();
console.log('Chain valid:', valid); // true

KillSwitch

import { KillSwitch } from '@the-bot-club/agentguard';

const ks = new KillSwitch();

// Register agent check in your tool execution loop
ks.on('halt', ({ tier, reason }) => {
  console.error(`HALT [${tier}]:`, reason);
});

// Before every tool call:
if (ks.isHalted('agent-1')) {
  throw new Error('Agent is halted');
}

// Halt globally
ks.haltGlobal('Security incident detected');

// Halt a specific agent
ks.haltAgent('agent-1', 'Exceeded rate limit');

Framework Integrations

One-liner guards for popular AI agent frameworks. No peer dependencies required.

LangChain

import { langchainGuard } from '@the-bot-club/agentguard';

// Pass as a callback to AgentExecutor — every tool call is evaluated automatically:
const executor = AgentExecutor.fromAgentAndTools({
  agent,
  tools,
  callbacks: [langchainGuard({ apiKey: 'ag_...' })],
});

Blocked tool calls throw AgentGuardBlockError — LangChain surfaces this as a tool execution error:

import { AgentGuardCallbackHandler, AgentGuardBlockError } from '@the-bot-club/agentguard';

const handler = new AgentGuardCallbackHandler({ apiKey: 'ag_...', agentId: 'my-agent' });
try {
  await handler.handleToolStart({ name: 'exec' }, '{"cmd":"rm -rf /"}');
} catch (err) {
  if (err instanceof AgentGuardBlockError) {
    console.log('Blocked:', err.reason);
    console.log('Try instead:', err.alternatives);
  }
}

OpenAI

import OpenAI from 'openai';
import { openaiGuard } from '@the-bot-club/agentguard';

const client = new OpenAI({ apiKey: 'sk-...' });
const guarded = openaiGuard(client, { apiKey: 'ag_...' });

// Use `guarded` exactly like the regular OpenAI client:
const response = await guarded.chat.completions.create({
  model: 'gpt-4o',
  messages: [...],
  tools: [...],
});

// Check which tool calls were blocked before executing them:
if (response._agentguard?.hasBlocks) {
  for (const d of response._agentguard.decisions) {
    if (d.decision === 'block') {
      console.log(`Blocked ${d.tool}: ${d.reason}`);
      console.log(`Suggestion: ${d.suggestion}`);
    }
  }
}

CrewAI

import { crewaiGuard } from '@the-bot-club/agentguard';

const guard = crewaiGuard({ apiKey: 'ag_...' });

// In your agent tool execution hook — throws on block:
await guard.beforeToolExecution('send_email', { to: '[email protected]' });

// Batch evaluate (no throw — caller handles blocks):
const results = await guard.evaluateBatch([
  { tool: 'file_read', args: { path: '/data/report.csv' } },
  { tool: 'send_email', args: { to: '[email protected]' } },
]);

Express / Fastify

import express from 'express';
import { expressMiddleware } from '@the-bot-club/agentguard';

const app = express();
app.use(expressMiddleware({ apiKey: 'ag_...' }));

// `req.agentguard` is now available in all route handlers:
app.post('/run-agent', async (req, res) => {
  const decision = await req.agentguard.evaluate({
    tool: req.body.tool,
    params: req.body.params,
  });
  if (decision.result !== 'allow') {
    return res.status(403).json({ error: 'blocked', reason: decision.reason });
  }
  // ... proceed
});

Fastify:

import { fastifyMiddleware } from '@the-bot-club/agentguard';
app.addHook('preHandler', fastifyMiddleware({ apiKey: 'ag_...' }));

Batch Evaluate

Evaluate multiple tool calls in a single round-trip (1–50 calls):

const batch = await guard.evaluateBatch({
  agentId: 'my-agent',
  calls: [
    { tool: 'file_read', params: { path: '/data/report.csv' } },
    { tool: 'send_email', params: { to: '[email protected]' } },
    { tool: 'exec', params: { cmd: 'rm -rf /' } },
  ],
});

console.log(`${batch.summary.blocked}/${batch.summary.total} calls blocked`);

for (const result of batch.results) {
  if (result.decision === 'block') {
    console.log(`[${result.tool}] BLOCKED: ${result.reason}`);
    console.log(`  Suggestion: ${result.suggestion}`);
    console.log(`  Docs: ${result.docs}`);
  }
}

LangChain Integration (Core Wrapper)

For local in-process policy enforcement with a full PolicyEngine, use the lower-level AgentGuardToolWrapper:

import { AgentGuardToolWrapper } from '@the-bot-club/agentguard';
import { DynamicTool } from 'langchain/tools';

// Your existing LangChain tool
const emailTool = new DynamicTool({
  name: 'send_email',
  description: 'Send an email',
  func: async (input) => {
    // ... send email logic
    return 'Email sent';
  },
});

// Wrap with AgentGuard policy enforcement
const wrapper = new AgentGuardToolWrapper(engine, auditLogger, killSwitch, agentContext);
const guardedTool = wrapper.wrap(emailTool);

// Use the guarded tool in your LangChain agent — policy is enforced automatically
const result = await guardedTool.invoke({ input: '{"to":"[email protected]"}' });

API Reference

AgentGuard (Cloud Client)

| Method | Description | |---|---| | evaluate(action) | Evaluate a tool call against your hosted policy | | getUsage() | Get usage stats for your tenant | | getAudit(options?) | Retrieve audit trail events | | killSwitch(active) | Activate (true) or deactivate (false) global kill switch | | createWebhook(config) | Register a new webhook endpoint | | listWebhooks() | List all webhook subscriptions | | deleteWebhook(id) | Delete a webhook subscription | | createAgent(config) | Register a new agent | | listAgents() | List all registered agents | | deleteAgent(id) | Delete a registered agent | | listTemplates() | List available policy templates | | getTemplate(name) | Get a specific policy template | | applyTemplate(name) | Apply a template to your tenant | | setRateLimit(config) | Create a rate limit rule | | listRateLimits() | List all rate limit rules | | deleteRateLimit(id) | Delete a rate limit rule | | getCostSummary(options?) | Get cost summary with optional filters | | getAgentCosts() | Get per-agent cost breakdown | | getDashboardStats() | Get high-level dashboard statistics | | getDashboardFeed(options?) | Get the live activity feed | | getAgentActivity() | Get per-agent activity summary |

PolicyEngine

| Method | Description | |---|---| | evaluate(request) | Evaluate an ActionRequest, returns PolicyDecision |

AuditLogger

| Method | Description | |---|---| | log(input) | Append an AuditEvent to the chain | | getEvents() | Return all events | | verify() | Verify the hash chain integrity |

KillSwitch

| Method | Description | |---|---| | isHalted(agentId) | Returns true if agent or global halt is active | | haltGlobal(reason) | Halt all agents | | haltAgent(id, reason) | Halt a specific agent | | resumeGlobal() | Resume global operations | | resumeAgent(id) | Resume a specific agent |


Links

License

Business Source License 1.1