Comparison

OpenAI Agents SDK vs Claude Agent SDK

Claude Agent SDK can deny inbound text on UserPromptSubmit and deny built-ins or MCP on PreToolUse. OpenAI Agents SDK screens text with a direct guard() before run(), and denies authored tool() via guardTool. OpenAI Agents has no MCP or hosted deny.

4 min read
In short: Claude Agent SDK can deny inbound text on UserPromptSubmit and deny built-ins or MCP on PreToolUse. OpenAI Agents SDK screens text with a direct guard() before run(), and denies authored tool() via guardTool. OpenAI Agents has no MCP or hosted deny.

How do OpenAI Agents SDK and Claude Agent SDK differ on security?

OpenAI Agents SDK and Claude Agent SDK are two first-party agent runtimes. Claude can deny inbound text on UserPromptSubmit and deny built-ins or MCP on PreToolUse. OpenAI Agents can screen text with a direct guard() before run(), and deny authored tool() via guardTool. OpenAI Agents has no MCP or hosted deny.

The useful compare is which hook can still refuse the side effect. Helper names aren't that hook. Claude exposes UserPromptSubmit and PreToolUse. OpenAI Agents exposes run() and authored invoke. Copying guardHooks onto an OpenAI Agents project won't compile.

A Claude agent that can call Bash still has a labeled deny on PreToolUse. An OpenAI Agents agent that can call webSearchTool doesn't have an Arcjet deny on that path. That is the gap this page exists to name. For more information about the series hub, see Agent framework security.

What can Claude Agent SDK deny?

Claude Agent SDK screens inbound prompts on UserPromptSubmit through guardHooks({ inbound }). On DENY, the hook returns { decision: "block" } and Claude Code erases the prompt.

Authored tool() wraps with guardTool. Unwrapped built-ins (Bash, Write) and MCP that you didn't wrap deny on PreToolUse via guardHooks. canUseTool is the ask path. A bare allowedTools name can skip it. For more information about that trap, see canUseTool is not a policy gate.

Import from @arcjet/guard/claude-agent-sdk/v0. Helpers default to onGuardError: "deny". "allow" is legitimate on inbound UserPromptSubmit because failing closed there stops the agent answering. How to screen inbound prompts in Claude Agent SDK and Claude Agent SDK security are the how-tos.

What can OpenAI Agents SDK deny?

OpenAI Agents has no inbound hook. Screen user text with a direct guard() call before run(). On DENY, skip run(). Direct guard() fails open. Gate hasFailedOpen() when that site must fail closed.

guardTool wraps FunctionTool.invoke after tool({ execute }). That is the only local side effect this adapter can stop. Hosted tools, MCP, handoffs, agent.asTool(), and computer/shell aren't deny points. Runner agent_tool_start is observe-only. There is no guardHooks and no guardToolNode.

needsApproval and hosted requireApproval are human holds. They aren't policy. Import from @arcjet/guard/openai-agents/v0. The adapter covers a text Agent, so Realtime and Sandbox are outside it as well. For more information about the how-to, see How do I secure an OpenAI Agents SDK agent?.

How the two SDKs compare

JobClaude Agent SDKOpenAI Agents SDK
Inbound screen

UserPromptSubmit via guardHooks({ inbound })

Direct guard() before run(). No inbound hook

Authored-tool deny

guardTool on authored tool()

guardTool on authored FunctionTool.invoke

Unwrapped / MCP deny

PreToolUse via guardHooks

None. Hosted tools, MCP, handoffs, and agent.asTool() are not deny points

HITL trap

canUseTool / bare allowedTools

needsApproval / hosted requireApproval

SDK-owned filtersClaude permission rules and hooks

inputGuardrails, outputGuardrails, tool guardrails. See

OpenAI guardrails vs Arcjet

protect() is HTTP on both stacks. Don't mint a fake Request inside a tool. Guard doesn't detect bots.

When to choose which

Claude Agent SDK is the better security surface when you need a deny on Bash, Write, or MCP that you didn't author. PreToolUse still sees those calls.

OpenAI Agents SDK is the better fit when the work is an authored tool({ execute }) that you own, plus an inbound screen that you write before run(). Plan for hosted tools and MCP to stay outside the Arcjet deny.

Teams that run both must not copy helper names across SDKs. guardHooks exists on Claude. It doesn't exist on OpenAI Agents. UserPromptSubmit isn't run(). Human approval is not a security policy covers the Claude click. needsApproval and LangGraph interrupt() are not a security policy covers the OpenAI click.

Frequently asked questions

How do OpenAI Agents SDK and Claude Agent SDK differ on security?

Claude can deny inbound text on UserPromptSubmit and deny built-ins or MCP on PreToolUse. OpenAI Agents screens text with a direct guard() before run(), and denies authored tool() via guardTool. OpenAI Agents has no MCP or hosted deny.

Can OpenAI Agents deny MCP the way Claude can?

No. Claude PreToolUse via guardHooks can deny MCP that you didn't wrap. OpenAI Agents guardTool wraps authored invoke only. Hosted tools, MCP, handoffs, and agent.asTool() aren't deny points.

Where does each stack screen inbound text?

Claude uses UserPromptSubmit via guardHooks({ inbound }). OpenAI Agents has no inbound hook; screen with a direct guard() call before run(). Direct guard() fails open; Claude helpers default to deny.

Is canUseTool the same as needsApproval?

Same class of control: a human hold, not a policy. canUseTool can also be skipped by a bare allowedTools name. needsApproval and hosted requireApproval park the run for a person.

Where do the helpers for each SDK import from?

OpenAI Agents helpers import from @arcjet/guard/openai-agents/v0 and Claude helpers from @arcjet/guard/claude-agent-sdk/v0. Neither has an unversioned alias. The OpenAI adapter covers a text Agent, so Realtime and Sandbox are outside it.

AI runtime security in your code

Protect your AI agent workflows with Arcjet

Arcjet runs inside your application, where it can use runtime context to enforce agent actions and budgets, detect prompt injection, and protect sensitive information before a workflow acts.