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:
- It has a per-tool-call hook that can return three outcomes (proceed, refuse, ask a human) or can be made to.
- It has a resume path on which the adapter can recompute
Decision.tokenbefore the tool runs. - 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
| Framework | Hook | Three outcomes | Resume path | Already covered by | Verdict |
|---|---|---|---|---|---|
| LangGraph.js | interrupt() inside a node; tool nodes wrap tools | Yes: return, throw, interrupt | Command({ resume }) with a checkpointer; state is durable | Nothing when tools are native; permdock/mcp when tools come from MCP | The only Phase 4 adapter candidate: a guardTools that wraps each tool with decide and raises interrupt on approval-required, recomputing token on resume |
| Mastra | Tool execute; workflow steps with suspend() and resume() | Yes through suspend | Workflow snapshot storage | Uses the AI SDK model layer; permdock/ai-sdk capabilityMiddleware applies to its tool list | Recipe: wrap execute with assert, map approval-required to suspend |
| Inngest AgentKit | Tool handler; step.waitForEvent for human input; lifecycle hooks onStart, beforeTool style middleware | Yes through a waiting step | Inngest durable step replay | Nothing | Recipe: beforeTool middleware calls decide; approval as a waitForEvent step keyed by token |
| Cloudflare Agents SDK | Tool definitions on the AI SDK; Durable Object state | Via AI SDK | Durable Object storage survives hibernation | permdock/ai-sdk; Durable Objects are the natural ApprovalStore | Recipe on the approvals page; no adapter |
| Google ADK for TypeScript | beforeToolCallback and afterToolCallback on an agent | Refuse yes; ask requires the app's own pause | Session service | Nothing | Recipe: 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 servers | Yes, via MCP elicitation | MCP | permdock/mcp | Nothing to add |
Vercel Workflow with AI SDK WorkflowAgent | needsApproval | Yes | Durable workflow suspend | permdock/ai-sdk | Nothing to add |
| Claude Code hooks | PreToolUse hook returning allow, deny or ask | Yes | The CLI re-prompts | permdock/claude-agent permissionRequestHook | Nothing to add |
| Cursor hooks | beforeShellExecution, beforeMCPExecution, beforeReadFile returning allow, deny or ask | Yes | The IDE re-prompts | Nothing | Recipe: 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 hooks | BeforeTool returning a decision of allow, deny or ask with a reason; AfterTool for audit | Yes | The CLI re-prompts | Nothing | Same 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, OpenCode | Pre-tool hooks with allow or deny (Codex); OpenCode plugin tool.execute.before throwing to block | Refuse yes; ask depends on the CLI's prompt | The CLI re-prompts where supported | Nothing | Same 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 node | n8n execution resumes on the response | permdock/mcp when the agent's tools are an MCP server | Recipe: 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 Policy | Gateway 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 session | permdock/mcp when the target is your own MCP server; the applied OpenAPI description for OpenAPI targets | Recipe: same as the MCP adapter bridge recipe; Cedar is a possible compile target, considered and not scheduled (commercial landscape) |
| OpenAI Agents SDK tool guardrails | toolInputGuardrails, toolOutputGuardrails with tripwires | Refuse yes; ask no | needsApproval covers it | permdock/openai | A second hook noted on the OpenAI adapter; needsApproval stays primary because guardrails cannot pause |
| Custom loops on raw provider SDKs | Whatever the loop author writes | Author's choice | Author's choice | permdock core | decide 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:
| Protocol | What it is | Relevance |
|---|---|---|
| AG-UI | An event stream between an agent backend and a UI: text, tool-call start and end, state, and human-in-the-loop events | Where 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 use | Same shape as Claude Code and Cursor hooks; a guard in the agent process answers permission requests from decide. Tracking only |
| Vercel Chat SDK | A 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 SDK | Where 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/mcpwithout 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;
capabilityMiddlewareandtoolApprovalapply. - Durable execution frameworks want approvals as steps. LangGraph checkpoints, Inngest steps, Mastra suspend, Cloudflare Durable Objects: each is a place to park an
approval-requireddecision and resume with the token. TheApprovalStoreinterface (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,
interrupton 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/terminalalready 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/mcpandpermdock/ai-sdkcomplete rather than adding parallel adapters. - The
ApprovalStoreinterface 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
interruptas a Phase 4 adapter candidate, gated on evidence from the recipe. - ADK
beforeToolCallback, Inngest middleware and Mastrasuspendas documented recipes on the approvals surfaces table, not adapters. - Cursor, Claude Code, Gemini CLI, Codex CLI and OpenCode hook scripts as one
permdock/terminalrecipe once the hook protocols settle. - Vercel Chat SDK
requestApprovalas the reference delivery recipe forapproval-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-requiredtodeniedsilently 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
- ADR 0023: compose with the OpenAPI toolchain, point 7 (the general rule).
- ADR 0022: approvals are pluggable (the store interface these recipes implement).
- ADR 0013: three-outcome decision (the test a hook must pass).
- Pages shaped: approvals surfaces table, approvals adapter, terminal adapter, roadmap Phase 4 candidates, agent standards survey.
OpenAPI ecosystem, September 2026
How PermDock's Overlay and standard security output fit the TypeScript OpenAPI toolchain (next-openapi-gen, hono-openapi, TypeSpec, Hey API, Orval, Kubb, Redocly, Bump.sh, Scalar, Mintlify, Fern, Speakeasy, Schemathesis, Arazzo runners, OpenAPI-to-MCP bridges), which tools are producers, appliers or consumers, and what PermDock adopts, adapts and avoids.
Local-first sync engines and MongoDB as where targets
How Zero, ElectricSQL, PowerSync, InstantDB and TinyBase express read and write permissions, how MongoDB queries relate to PermDock's portable condition AST, and which of them are candidates for a where compiler at Phase 3 planning.