PermDock
Research

Agent frameworks beyond the five adapters

Which TypeScript agent frameworks and agent-UI protocols expose a hook PermDock could occupy (LangGraph.js, Mastra, Inngest AgentKit, Cloudflare Agents, Google ADK, OpenAI Apps SDK, AG-UI, Cursor and Claude Code hooks), which are already covered by an existing adapter, and why none becomes an adapter before Phase 4.

Source: a review run in September 2026 of agent frameworks a TypeScript team might already run, after the five agent adapters (ai-sdk, claude-agent, eve, openai, mcp) were specified. The question was the same one ADR 0023 asks of every ecosystem: does the framework expose a hook only in-process code can occupy, or is an existing wire format or adapter enough? Sources are the frameworks' documentation linked below; hook names are as documented at review time and should be re-checked before any adapter is written.

The question an adapter answers

PermDock's agent adapters are thin translators from a Decision into a runtime's vocabulary (agent standards survey). Each exists because the runtime has a slot that only code inside the process can fill: AI SDK's toolApproval, Claude Agent SDK's canUseTool, Eve's defineTool approval pair, OpenAI's needsApproval and interruptions, MCP's registerTool and elicitation. A framework earns an adapter when three things hold:

  1. It has a per-tool-call hook that can return three outcomes (proceed, refuse, ask a human) or can be made to.
  2. It has a resume path on which the adapter can recompute Decision.token before the tool runs.
  3. It is not already reached through MCP, the AuthZEN endpoint or one of the five adapters.

Most frameworks fail the third test: they consume MCP servers, in which case permdock/mcp already guards every tool they can see, or they wrap the AI SDK, in which case permdock/ai-sdk applies unchanged.

Framework table

FrameworkHookThree outcomesResume pathAlready covered byVerdict
LangGraph.jsinterrupt() inside a node; tool nodes wrap toolsYes: return, throw, interruptCommand({ resume }) with a checkpointer; state is durableNothing when tools are native; permdock/mcp when tools come from MCPThe only Phase 4 adapter candidate: a guardTools that wraps each tool with decide and raises interrupt on approval-required, recomputing token on resume
MastraTool execute; workflow steps with suspend() and resume()Yes through suspendWorkflow snapshot storageUses the AI SDK model layer; permdock/ai-sdk capabilityMiddleware applies to its tool listRecipe: wrap execute with assert, map approval-required to suspend
Inngest AgentKitTool handler; step.waitForEvent for human input; lifecycle hooks onStart, beforeTool style middlewareYes through a waiting stepInngest durable step replayNothingRecipe: beforeTool middleware calls decide; approval as a waitForEvent step keyed by token
Cloudflare Agents SDKTool definitions on the AI SDK; Durable Object stateVia AI SDKDurable Object storage survives hibernationpermdock/ai-sdk; Durable Objects are the natural ApprovalStoreRecipe on the approvals page; no adapter
Google ADK for TypeScriptbeforeToolCallback and afterToolCallback on an agentRefuse yes; ask requires the app's own pauseSession serviceNothingRecipe: beforeToolCallback returns a refusal result from decide; approvals need the app's own loop until ADK exposes one
OpenAI Apps SDK (ChatGPT apps)Apps are MCP serversYes, via MCP elicitationMCPpermdock/mcpNothing to add
Vercel Workflow with AI SDK WorkflowAgentneedsApprovalYesDurable workflow suspendpermdock/ai-sdkNothing to add
Claude Code hooksPreToolUse hook returning allow, deny or askYesThe CLI re-promptspermdock/claude-agent permissionRequestHookNothing to add
Cursor hooksbeforeShellExecution, beforeMCPExecution, beforeReadFile returning allow, deny or askYesThe IDE re-promptsNothingRecipe: a hook script that calls a permdock/terminal-style guard; tool names map to permissions, the subject comes from the developer's verified login. Documented, not packaged
Gemini CLI hooksBeforeTool returning a decision of allow, deny or ask with a reason; AfterTool for auditYesThe CLI re-promptsNothingSame recipe as Cursor and Claude Code; the three coding agents share one hook script shape (tool name plus arguments in, a decision out), so one guard serves all of them
Codex CLI, OpenCodePre-tool hooks with allow or deny (Codex); OpenCode plugin tool.execute.before throwing to blockRefuse yes; ask depends on the CLI's promptThe CLI re-prompts where supportedNothingSame recipe; tracked because the hook protocols are younger than Claude Code's
n8n AI Agent"Require approval" option on agent tools, "Send and Wait for Response" node (Slack, Teams, Gmail, Telegram, Discord, WhatsApp)Yes through the wait noden8n execution resumes on the responsepermdock/mcp when the agent's tools are an MCP serverRecipe: expose tools through permdock/mcp; n8n's approval is the no-code delivery surface and the store record still lives behind the MCP server
AWS Bedrock AgentCore Gateway and PolicyGateway turns OpenAPI, Lambda and MCP targets into MCP tools; Policy evaluates Cedar with context.toolName and context.input.*Refuse yes at the gateway; ask requires the application (Runtime keeps agent state)AgentCore Runtime sessionpermdock/mcp when the target is your own MCP server; the applied OpenAPI description for OpenAPI targetsRecipe: same as the MCP adapter bridge recipe; Cedar is a possible compile target, considered and not scheduled (commercial landscape)
OpenAI Agents SDK tool guardrailstoolInputGuardrails, toolOutputGuardrails with tripwiresRefuse yes; ask noneedsApproval covers itpermdock/openaiA second hook noted on the OpenAI adapter; needsApproval stays primary because guardrails cannot pause
Custom loops on raw provider SDKsWhatever the loop author writesAuthor's choiceAuthor's choicepermdock coredecide and assert directly; the for AI agents page is the recipe

Two protocols sit beside the frameworks and matter for the approvals story rather than for tool gating:

ProtocolWhat it isRelevance
AG-UIAn event stream between an agent backend and a UI: text, tool-call start and end, state, and human-in-the-loop eventsWhere an approval-required decision should appear in a chat UI. A backend using any adapter above emits the pending approval (reason, token, what to ask) as an AG-UI tool-call or custom event; the UI renders the approval control; the answer flows back and the adapter recomputes token. PermDock defines the payload (the approval request wire format on wire formats), not the event type
Agent Client Protocol (ACP)Editor-to-coding-agent protocol (Zed and others) with permission requests for tool useSame shape as Claude Code and Cursor hooks; a guard in the agent process answers permission requests from decide. Tracking only
Vercel Chat SDKA delivery surface, not a framework: requestApproval from a chat/workflow step posts an approval card to Slack, Teams or Discord, verifies the platform signature and returns the responder's user.id; durable through the Workflow SDKWhere an approval-required decision reaches a human who is not in the chat UI. The reference delivery recipe on the approvals adapter: the responder id is mapped to a Subject and store.resolve runs PermDock's actor and token checks

What the table says

  • MCP is the great equaliser. Any framework that consumes MCP servers is guarded by permdock/mcp without knowing it, including ChatGPT apps, Cursor, Claude Code and most enterprise agent platforms. The tool list a framework sees is already filtered per caller.
  • The AI SDK is the second. Mastra, Cloudflare Agents and Vercel Workflow build on it; capabilityMiddleware and toolApproval apply.
  • Durable execution frameworks want approvals as steps. LangGraph checkpoints, Inngest steps, Mastra suspend, Cloudflare Durable Objects: each is a place to park an approval-required decision and resume with the token. The ApprovalStore interface (ADR 0022) is what these recipes implement; the durable store is theirs, the token check is PermDock's.
  • Only LangGraph.js is large enough and hook-complete enough to justify an adapter, and only if the recipe (wrap tools, interrupt on approval) proves too fiddly for users to write themselves. Phase 4 at earliest, after the five shipped adapters have shown which translation problems recur.
  • Developer-tool hooks are a new surface. Cursor, Claude Code, Gemini CLI, Codex CLI and OpenCode hooks turn a coding agent's shell and MCP calls into permission requests. permdock/terminal already answers "may this command run" for a consumer's CLI; the same guard behind a hook script answers it for the agent driving the IDE. This is documented as a recipe because the hook protocols are young and differ per editor, though they converge on the same shape: tool name and arguments in, allow, deny or ask out.
  • Gateways are arriving with their own policy engines. AgentCore Policy evaluates Cedar at the gateway with the tool name and parsed arguments. It cannot see the row or pause for a human, so it complements rather than replaces an in-process check; the two agree when they read the same applied OpenAPI description.
  • Delivery is the missing half of approvals. Every hook pauses; none of them tells a human. Chat SDK, n8n's wait node and the durable runtimes are where the pending request becomes a message, and each hands back an identity PermDock only has to compare against the actor.

Adopt / adapt / avoid

Adopt:

  • MCP and the AI SDK as the two integration points that cover most frameworks; keep permdock/mcp and permdock/ai-sdk complete rather than adding parallel adapters.
  • The ApprovalStore interface as the contract durable frameworks implement (LangGraph checkpointer, Inngest step, Durable Object).
  • AG-UI's human-in-the-loop events as the place a chat UI renders approval-required, carrying PermDock's approval request payload unchanged.

Adapt:

  • LangGraph.js interrupt as a Phase 4 adapter candidate, gated on evidence from the recipe.
  • ADK beforeToolCallback, Inngest middleware and Mastra suspend as documented recipes on the approvals surfaces table, not adapters.
  • Cursor, Claude Code, Gemini CLI, Codex CLI and OpenCode hook scripts as one permdock/terminal recipe once the hook protocols settle.
  • Vercel Chat SDK requestApproval as the reference delivery recipe for approval-required; n8n's wait node and the durable runtimes as the alternatives.
  • AgentCore Gateway as an OpenAPI-to-MCP bridge; Cedar as a compile target only on demand.

Avoid:

  • One adapter per framework; the five shipped adapters already cover the hook shapes that exist.
  • Any hook that cannot express "ask a human"; mapping approval-required to denied silently would hide the third outcome.
  • Trusting a framework's own notion of the current user; the subject comes from the host's verified material, never from agent state (authentication).

Decisions informed

On this page