AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP unreviewed MIT Self-run

Agentgate

mcp-drandrewlaw-agentgate · by drandrewlaw

Production-grade permissions, hooks, and tool safety for AI agents. Works with any LLM provider.

No reviews yet
0 installs
27 views
0.0% view→install

Install

$ agentstack add mcp-drandrewlaw-agentgate

Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Destructive filesystem operation.

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Reliability & compatibility

Not yet reviewed
0 installs to date
no reviews yet
5mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Agentgate? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

agentgate

The missing safety layer for AI agents.

[](https://www.npmjs.com/package/agentgate) [](https://opensource.org/licenses/MIT) [](https://www.typescriptlang.org/)

Your agent can call tools. But should it?

agentgate gives you declarative permission rules, lifecycle hooks, and tool execution control for any AI agent — extracted from battle-tested patterns in production AI systems serving millions of users.

Your Agent (LangChain / CrewAI / OpenAI / Custom)
         │
    ┌────▼─────────────────┐
    │      agentgate        │
    │  permissions + hooks  │
    └────┬─────────────────┘
         │
    Actual Tools (filesystem, bash, APIs, databases)

Why agentgate?

Every AI agent framework gives you tools. None gives you governance.

| Feature | agentgate | LangChain | CrewAI | OpenAI Agents | ShipAny | |---------|:---------:|:---------:|:------:|:-------------:|:-------:| | Permission DSL (allow/deny/ask) | Yes | No | No | No | No | | Lifecycle hooks (pre/post/error) | Yes | No | No | No | No | | Provider-agnostic | Yes | Yes | Yes | No | No | | MCP support | Yes | No | No | No | Yes | | Type-safe tools (Zod) | Yes | Partial | No | Partial | Yes | | Zero runtime deps | Yes | No | No | No | No |

Install

npm install agentgate zod

Quick Start — 5 lines to safety

import { agentgate, buildTool, matchPattern } from 'agentgate'
import { z } from 'zod'

const Bash = buildTool({
  name: 'Bash',
  inputSchema: z.object({ command: z.string() }),
  call: async (input) => ({ data: `ran: ${input.command}` }),
  preparePermissionMatcher: (input) => (pattern) => matchPattern(pattern, input.command),
})

const gate = agentgate({
  permissions: {
    mode: 'default',
    rules: [
      { allow: 'Bash(git *)' },   // ✅ Allow git commands
      { deny:  'Bash(rm *)' },    // ❌ Block rm commands
    ],
  },
  tools: [Bash],
})

await gate.execute('Bash', { command: 'git status' })  // ✅ allowed
await gate.execute('Bash', { command: 'rm -rf /' })    // ❌ denied

Core Concepts

1. Permission Engine

Declarative rules control what your agent can do. Rules use a compact DSL:

import { createPermissionEngine } from 'agentgate'

const permissions = createPermissionEngine({
  mode: 'default',  // 'strict' | 'default' | 'permissive' | 'bypass'
  rules: [
    { allow: 'Read' },                    // Allow entire tool
    { allow: 'Bash(git *)' },             // Allow by input pattern
    { deny:  'Bash(rm *)' },              // Deny by input pattern
    { ask:   'Write' },                   // Require approval
    { allow: 'mcp__github__*' },          // Allow all MCP server tools
    { deny:  'mcp__filesystem__write_*' }, // Deny MCP write tools
  ],
})

Permission modes:

  • strict — Deny by default. Only explicitly allowed tools run.
  • default — Allow reads, ask for writes/destructive actions.
  • permissive — Allow unless explicitly denied.
  • bypass — Allow everything (testing only).

2. Lifecycle Hooks

Hooks fire before/after tool execution for logging, validation, and control:

import { agentgate } from 'agentgate'

const gate = agentgate({
  hooks: {
    preToolUse: [{
      matcher: 'Write',  // Only for Write tool
      hooks: [{
        type: 'callback',
        fn: async (input) => {
          const { path } = input.toolInput as { path: string }
          if (path.startsWith('/etc/')) {
            return { continue: false, decision: 'block', reason: 'Cannot write to /etc/' }
          }
          return { continue: true, decision: 'approve' }
        },
      }],
    }],
    postToolUse: [{
      hooks: [{
        type: 'http',
        url: 'https://audit.company.com/log',  // Webhook for audit trail
      }],
    }],
  },
})

Hook types:

  • callback — In-process async function (fastest)
  • command — Shell command (stdin: JSON input, exit code 0=approve, 2=block)
  • http — HTTP POST webhook (JSON request/response)

Hook events: preToolUse, postToolUse, toolError, permissionDenied, sessionStart, sessionEnd, beforeCompact, afterCompact, configChange, custom

3. Type-Safe Tools

Build tools with Zod schemas and built-in safety classification:

import { buildTool } from 'agentgate'
import { z } from 'zod'

const DatabaseQuery = buildTool({
  name: 'DatabaseQuery',
  inputSchema: z.object({
    query: z.string(),
    database: z.enum(['production', 'staging', 'dev']),
  }),

  // Safety classification
  isReadOnly: (input) => /^\s*SELECT\b/i.test(input.query),
  isDestructive: (input) => /\b(DROP|TRUNCATE)\b/i.test(input.query),

  // Tool-specific permission check
  checkPermissions: async (input) => {
    if (input.database === 'production' && !/^\s*SELECT\b/i.test(input.query)) {
      return { behavior: 'deny', message: 'Only SELECT on production' }
    }
    return { behavior: 'allow', updatedInput: input }
  },

  call: async (input) => {
    const result = await db.query(input.query)
    return { data: result }
  },
})

4. Tool Executor

The executor wires permissions + hooks + tools into a single lifecycle:

import { createToolExecutor, createPermissionEngine, createHookEngine } from 'agentgate'

const executor = createToolExecutor({
  permissions: createPermissionEngine({ mode: 'default', rules: [...] }),
  hooks: createHookEngine({ preToolUse: [...] }),
  tools: [ReadTool, WriteTool, BashTool],
  maxConcurrency: 10,

  // Handle 'ask' permission decisions interactively
  onPermissionRequest: async (toolName, message, input) => {
    const approved = await promptUser(`Allow ${toolName}? ${message}`)
    return approved
      ? { behavior: 'allow', updatedInput: input }
      : { behavior: 'deny', message: 'User rejected' }
  },
})

const result = await executor.execute('Bash', { command: 'git push' })
// result.status: 'allowed' | 'denied' | 'error' | 'blocked_by_hook'

5. MCP Integration (Optional)

Connect to MCP servers and govern their tools with the same permission system:

import { createPermissionEngine } from 'agentgate'
import { createMCPClient } from 'agentgate/mcp'

const mcp = createMCPClient({
  servers: {
    filesystem: {
      type: 'stdio',
      command: 'npx',
      args: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'],
    },
  },
})

await mcp.connect()
const tools = mcp.discoverTools()
// tools: [{ name: 'mcp__filesystem__read_file', ... }, ...]

// Same permission rules work for MCP tools
const perms = createPermissionEngine({
  rules: [
    { allow: 'mcp__filesystem__read_file' },
    { deny: 'mcp__filesystem__write_file' },
  ],
})

API Reference

Main Exports

| Export | Description | |--------|------------| | agentgate(config) | One-liner: creates a configured ToolExecutor | | buildTool(def) | Create a type-safe tool with defaults | | createPermissionEngine(config) | Create a permission engine | | createHookEngine(config) | Create a hook engine | | createToolExecutor(config) | Create an executor (permissions + hooks + tools) | | defineConfig(config) | Type-safe config helper | | createMCPClient(config) | Create an MCP client (from agentgate/mcp) |

Permission Rule DSL

"ToolName"              → matches entire tool
"ToolName(pattern)"     → matches tool + input pattern
"mcp__server__tool"     → matches specific MCP tool
"mcp__server__*"        → matches all tools from MCP server
"mcp__server"           → matches all tools from MCP server

Patterns support wildcards:
"git *"                 → prefix match
"*.ts"                  → suffix match
"src/*.ts"              → prefix + suffix
"*"                     → matches everything

Architecture

agentgate is designed as middleware, not a framework. It sits between your agent and its tools:

  1. Agent requests tool call → agentgate receives (toolName, input)
  2. Permission engine evaluates rules → allow, deny, or ask
  3. PreToolUse hooks fire → can approve, block, or modify input
  4. Tool executes with validated input
  5. PostToolUse hooks fire → logging, audit, side effects
  6. Result returns to agent

This works with any LLM provider and any agent framework because agentgate only cares about the tool layer, not the model layer.

Dependencies

  • Runtime: Zero. No dependencies.
  • Peer: zod >= 3.23 (you likely already have it)
  • Optional peer: @modelcontextprotocol/sdk >= 1.0 (only for MCP module)

Examples

See the [examples/](./examples) directory — all runnable with npx tsx examples/:

| # | Example | Use Case | |---|---------|----------| | 01 | [Basic Permissions](./examples/01-basic-permissions.ts) | Quick start with allow/deny/ask rules | | 02 | [Hooks and Lifecycle](./examples/02-hooks-and-lifecycle.ts) | Pre/post hooks for logging and validation | | 03 | [Custom Tools](./examples/03-custom-tools.ts) | Type-safe tools with Zod schemas | | 04 | [MCP Integration](./examples/04-mcp-integration.ts) | Govern MCP server tools | | 05 | [Infrastructure Safety](./examples/05-infrastructure-safety.ts) | Prevent agents from destroying your infra | | 06 | [Database Safety](./examples/06-database-safety.ts) | Tiered DB access (prod read-only, staging read-write) | | 07 | [Audit Trail](./examples/07-audit-trail.ts) | SOC2/HIPAA/GDPR compliance logging with PII detection | | 08 | [Human-in-the-Loop](./examples/08-human-in-the-loop.ts) | Interactive approval for risky actions | | 09 | [Input Validation](./examples/09-input-validation.ts) | SQL injection blocking, PII redaction, email safety | | 10 | [Rate Limiting](./examples/10-rate-limiting.ts) | Per-tool limits, budget caps, cost tracking |

Contributing

Contributions welcome! Please open an issue first to discuss what you'd like to change.

git clone https://github.com/agentgate/agentgate
cd agentgate
npm install
npm test

License

[MIT](./LICENSE)

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.