The Claude Code SDK
You already met the Claude Code SDK — the query deduplication hook in the previous lesson used it to spawn a reviewer instance. This lesson shows you how to use it directly. The SDK lets you run Claude Code programmatically from a TypeScript script, a Python script, or a CLI invocation, with the exact same tools, the exact same settings, and the exact same model behaviour as the interactive CLI you have been using.
The Claude Code SDK is Claude Code, minus the interactive shell. Same capabilities, same configuration, called from your own code.
Where the SDK fits
Three flavours, same core:
- TypeScript SDK —
@anthropic-ai/claude-code, the one you will use most if you live in Node. - Python SDK — same capabilities, Pythonic API.
- CLI SDK — non-interactive CLI invocations, useful in shell scripts and CI steps.
All three inherit settings from the same directory they are run in. That is worth emphasising: if you have a project-level CLAUDE.md, an .claude/settings.local.json, and a set of custom commands, all of that applies automatically to SDK calls made from inside that directory. The SDK is not a parallel world — it is the same Claude Code, headless.
Step 1 — Basic TypeScript usage
Install the SDK:
npm install @anthropic-ai/claude-code
Then call query and iterate over the messages it yields:
import { query } from "@anthropic-ai/claude-code";
const messages = query({
prompt: "Summarise the README in three bullet points.",
});
for await (const message of messages) {
console.log(message);
}
query returns an async iterable of raw conversation messages — the same messages Claude Code would render in its UI. The final message in the stream contains Claude's complete response, which is usually what you want to capture and use downstream.
Step 2 — Know about the read-only default
Here is the gotcha that trips people up on their first SDK call. By default, SDK-driven Claude sessions are read-only. Read, Grep, and directory listing are enabled. Edit, Write, and anything else that mutates the filesystem is not.
This is deliberate — scripts that accidentally modify files are much worse than scripts that fail to — but it means your first "please fix the typo in the README" script will look like it succeeded while having changed nothing.
Step 3 — Enable write permissions with allowedTools
To let Claude write files, add the tools you want to the allowedTools option:
import { query } from "@anthropic-ai/claude-code";
const messages = query({
prompt: "Fix the typo in the README and commit the change.",
options: {
allowedTools: ["Edit"],
},
});
for await (const message of messages) {
console.log(message);
}
allowedTools takes an array of tool names — "Edit", "Write", "MultiEdit", and so on. Only the tools you list are available beyond the read-only defaults. Be specific about what a script is allowed to touch; the principle of least privilege applies here the same way it does to any other automation.
Where you will actually use this
The SDK is for integrating Claude Code into larger pipelines. A few concrete patterns:
Helper commands. Wrap a frequently-needed task — "generate a changelog entry from the latest commits" — as a small script that calls query and prints the result.
CI steps. Run Claude Code as a step in your build pipeline. Review dependency updates, generate release notes, or flag anything unusual in a PR without needing a full GitHub Actions integration.
Advanced hooks. The query deduplication hook from the previous lesson is the canonical example: a PostToolUse hook that uses the SDK to spawn a scoped reviewer instance. That pattern — hook calls out to another Claude instance via the SDK — lets you build arbitrarily smart checks on top of the hook system.
Data pipelines. Use Claude Code programmatically to analyse, classify, or transform batches of files.
Each of these is just "Claude Code, but the trigger is my code instead of a human typing in a terminal." That is the mental model. Once it clicks, you will stop thinking of Claude Code as purely an interactive tool and start thinking of it as a building block.
Key Takeaways
- 1The Claude Code SDK exposes Claude Code's full capabilities as a TypeScript, Python, or CLI API for running it programmatically.
- 2The SDK inherits its configuration — CLAUDE.md, settings, custom commands — from the directory it runs in, so it behaves exactly like the interactive CLI would there.
- 3Basic TypeScript usage is `query({ prompt })` returning an async iterable of messages, with the final message holding Claude's complete response.
- 4By default, SDK sessions are read-only; add tools like `Edit` or `Write` to the `allowedTools` option to enable file mutation.
- 5The SDK is the right tool for pipelines, helper scripts, CI steps, and advanced hooks that need to spawn additional Claude instances.