Skip to main content
The Agent SDK gives you the same tools, agent loop, and context management that power Claude Code. It’s available as a CLI for scripts and CI/CD, or as Python and TypeScript packages for full programmatic control. To run Claude Code in non-interactive mode, pass -p with your prompt and the CLI options you need:
This page covers using the Agent SDK via the CLI (claude -p). For the Python and TypeScript SDK packages with structured outputs, tool approval callbacks, and native message objects, see the full Agent SDK documentation.

Basic usage

Add the -p (or --print) flag to any claude command to run it non-interactively. Not every CLI option combines with -p. Claude Code rejects --bg, and rejects --cloud with a task description, with an error naming the conflict; --cloud with a session ID and -p instead queues a message into that cloud session and exits. Options you’ll combine with -p often include: This example asks Claude a question about your codebase and prints the response:
Claude Code exits with code 0 on success and a non-zero code when the run fails, so your scripts can branch on the exit status. If you pass an invalid flag, Claude Code reports the error to stderr before the run starts. When a failure happens inside the run, such as missing authentication, Claude Code prints the failure as the result on stdout.

Start faster with bare mode

Add --bare to reduce startup time by skipping auto-discovery of hooks, skills, plugins, MCP servers, auto memory, and CLAUDE.md. Without it, claude -p loads the same context an interactive session would, including anything configured in the working directory or ~/.claude. Bare mode is useful for CI and scripts where you need the same result on every machine. A hook in a teammate’s ~/.claude or an MCP server in the project’s .mcp.json won’t run, because bare mode never reads them. Without --bare, Claude Code runs the hooks in a project’s .claude/settings.json even in a folder you’ve never trusted, because a -p session shows no workspace trust dialog. It also connects the servers in the project’s .mcp.json, because a -p session can’t show the per-server approval prompt either. What runs before you trust a folder covers each kind of repository content under -p and how to keep it out. This example runs a one-off summarize task in bare mode and pre-approves the Read tool so the call completes without a permission prompt. Set ANTHROPIC_API_KEY before running it, because bare mode doesn’t use your subscription login:
In bare mode, Claude Code never reads OAuth credentials or the system keychain. For the Anthropic API, set ANTHROPIC_API_KEY in the environment, with a key created in the Claude Console, or supply an apiKeyHelper in the --settings JSON. Amazon Bedrock, Google Cloud’s Agent Platform, and Microsoft Foundry continue to read their own provider credentials as usual. In bare mode Claude has access to the Bash, file read, and file edit tools. Pass any context you need with a flag:
--bare is the recommended mode for scripted and SDK calls, and will become the default for -p in a future release.

Background tasks at exit

If Claude starts a background Bash task during a claude -p run, for example a dev server or a watch build, that shell is terminated about five seconds after Claude has returned its final result and stdin has closed. The grace period lets a task that finishes right after the result still deliver its output. Before v2.1.163, a never-exiting background process would hold the claude -p invocation open indefinitely. Background subagents and workflows are exempt from the five-second grace because their result is part of the final output, so claude -p waits for them to complete. From v2.1.182, that wait is capped at ten minutes by default so a stuck background agent cannot hold the process open indefinitely. Adjust the cap with CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS, or set it to 0 to wait without a limit. If you stop a claude -p run with SIGTERM, for example from kill, a process supervisor, or an SDK host closing the session, Claude Code aborts the in-progress turn, terminates the process tree of any running Bash command, runs SessionEnd hooks, and exits with code 143.

Examples

These examples highlight common CLI patterns. Where a command names a file such as auth.py or build-error.txt, substitute a file from your own project. In CI or other scripted environments, add --bare so Claude Code starts without loading the host’s hooks, plugins, auto memory, or CLAUDE.md.

Pipe data through Claude

Non-interactive mode reads stdin, so you can pipe data in and redirect the response out like any other command-line tool. This example pipes a build log into Claude and writes the explanation to a file:
With --output-format json, the response payload includes total_cost_usd and a per-model cost breakdown, so scripted callers can track spend per invocation without consulting the usage dashboard. Both figures are client-side estimates and can differ from your actual bill.
Piped stdin is capped at 10MB. If you exceed the cap, Claude Code exits with a clear error and a non-zero status. To work with larger inputs, write the content to a file and reference the file path in your prompt instead of piping it.
If Claude Code can’t read stdin, for example because the process that started it disconnected its end, Claude Code prints a warning to stderr and continues with the prompt from the command line. Before v2.1.211, an unreadable stdin on Windows crashed the session or made it exit silently with no output.

Add Claude to a build script

You can wrap a non-interactive call in a script to use Claude as a project-specific linter or reviewer. This package.json script pipes the diff against main into Claude and asks it to report typos. Piping the diff means Claude doesn’t need Bash permission to read it, and the escaped double quotes keep the script portable to Windows:
Run it with npm run lint:claude.

Get structured output

Use --output-format to control how responses are returned: