Integrations
The gate is one function call between “the model produced something” and “the user’s phone buzzed”. Each framework already has a place reserved for that decision; the adapters put the gate there. This page shows the whole loop per framework and links the examples in the repository.
Two of the examples need neither the framework nor a network. They import the package by name, read a JSON policy and a day of candidates with the clock taken from each line, and print the same thing every run:
git clone https://github.com/Bubblegunn/proactive-gate && cd proactive-gatenpm ci && npm run buildnode examples/mastra/run.mjsnode examples/ai-sdk/run.mjsMastra
Section titled “Mastra”An output processor. Mastra calls it after the model has produced the message and before
anything reaches the user; on a rejection the processor calls abort() with the gate’s
reason, and the tripwire response tells the model why the message did not go out.
import { Agent } from "@mastra/core/agent";import { createGate, defaultChecks, MemoryStore } from "proactive-gate";import { gateProcessor } from "proactive-gate/mastra";
const gate = createGate({ store: new MemoryStore(), checks: defaultChecks({ dailyLimit: 3, quietHoursFloor: "high" }) });
export const assistant = new Agent({ id: "calendar-assistant", instructions: "Say the one thing the user should be told right now, or answer NONE.", model: "openai/gpt-4o-mini", outputProcessors: [gateProcessor({ gate, toInput: () => ({ user, candidate }) })],});Offline: examples/mastra/
runs ten candidates for two users through a policy with weekly and daily budgets; five go
out, and the output names the check that stopped each of the other five. With a model:
examples/mastra.ts.
Vercel AI SDK
Section titled “Vercel AI SDK”The send tool has needsApproval: true, and the gate answers every approval request. A
denied call carries the reason, so the model can plan around it; an approved call has already
consumed the budget.
import { gateToolApproval } from "proactive-gate/ai-sdk";
const approve = gateToolApproval({ gate, toInput: (call) => ({ user, candidate: fromCall(call) }) });const { approved, reason } = await approve(call);// addToolApprovalResponse({ id: call.approvalId, approved, reason })Offline: examples/ai-sdk/
answers nine approval requests under a policy that includes the TCPA preset; one of them is a
critical alert at 23:00 that the legal window still refuses, because presets carry no
priority bypass. With a model:
examples/vercel-ai-sdk.ts.
LangChain and LangGraph
Section titled “LangChain and LangGraph”Middleware around the send tool (proactive-gate/langchain): a watched tool call is refused
with the gate’s reason as the tool result; other tools pass through. In a graph, the notify
node asks the gate before it fires the tool:
examples/langgraph.ts.
OpenAI Agents
Section titled “OpenAI Agents”A tool-input guardrail (proactive-gate/openai-agents): the tripwire fires on a rejection
and outputInfo carries the decision, including the surfaces an allowed message may use.
Claude Code
Section titled “Claude Code”A PreToolUse hook. npx proactive-gate hook --policy policy.json --tool send_message
reads the event on stdin and prints a permissionDecision for the matching tool; other
tools print nothing.
examples/claude-code-hook.json.
As a skill and plugin
Section titled “As a skill and plugin”A skill teaches the coding agent that is writing your code when to put the gate in front of a message, which calls to make, and how to read the answer. In Claude Code:
claude plugin marketplace add Bubblegunn/proactive-gateclaude plugin install proactive-gate@proactive-gateThe skill is skills/proactive-gate/SKILL.md, in the repository and in the npm package, so an
agent that reads skill folders can use it from node_modules/proactive-gate/skills/proactive-gate.
A test checks every API name, option, preset, check id, subcommand and flag in it against what
the package exports, so the skill cannot describe a function that no longer exists.
As an MCP tool
Section titled “As an MCP tool”npx proactive-gate mcp --policy policy.json serves the gate to any MCP client over stdio. It
has two tools: decide takes { user, candidate, now?, commit? } and returns the decision,
including rejectedBy, reason and nextAllowedAt; explain takes the same input and returns
the decision as plain sentences. Neither spends a budget unless decide is called with
commit: true, which is the call to make when you are about to send. The gate keeps its counters
in memory for the life of the process.
claude mcp add proactive-gate -- npx proactive-gate mcp --policy policy.jsonThe server is about 150 lines of JSON-RPC over standard input and output, with no MCP SDK and no dependency, and it gives the same answers as the library on every fixture.
Python
Section titled “Python”The same policy file runs in the Python package (Gate.from_policy), sync or async, and
passes the same fixtures. See Python.
Listing the gate where these frameworks live
Section titled “Listing the gate where these frameworks live”The texts for a Mastra integrations page and a Vercel AI SDK docs pointer are in
docs/integrations/
in the repository. If you maintain a framework and want the gate in its docs, open an issue
and the page is yours to review.