The Claude Agent SDK in TypeScript is type-safe when developers combine exported SDK types, Zod validation, and streaming event narrowing because each layer catches different failure modes before runtime.
The Claude Agent SDK in TypeScript provides compile-time type safety for agent definitions, tool schemas, and streaming responses through two official packages: @anthropic-ai/sdk (REST API client) and @anthropic-ai/claude-agent-sdk (autonomous agent runtime). Both ship with built-in type declarations, require Node 18+, and support Zod-based validation for runtime guarantees that match static types.
TL;DR
TypeScript agents built on the Claude SDK face a gap between API capabilities and type definitions that leads to silent any resolution and runtime failures. This guide covers typed agent configs, Zod tool schemas with strict enforcement, four streaming patterns with typed events, and discriminated union error handling. It also shows where Intent coordinates multiple Claude agents working in parallel across large TypeScript codebases.
Where TypeScript Type Safety Breaks Down in the Claude SDK
TypeScript developers building Claude-powered agents hit a specific frustration: the SDK's type surface evolves faster than its documentation. New tool types arrive without matching type definitions, the agent SDK can resolve types to any when the @anthropic-ai/sdk dependency is missing, and streaming events carry partial JSON that crashes JSON.parse on malformed escape sequences.
These failures show up in production. GitHub issue #864 documents the silent type resolution bug, issue #996 confirms the streaming JSON parse crash, and issue #939 tracks missing tool type definitions.
This guide walks through every layer of type safety available in the Claude Agent SDK for TypeScript: installation, agent definitions, Zod-validated tool schemas, four streaming patterns with typed events, and discriminated union error handling. The final section shows how Intent, the workspace for spec-driven development, coordinates multiple agents working in parallel across TypeScript codebases.
See how Intent's living specs keep parallel Claude agents aligned across cross-service TypeScript refactors.
Free tier available · VS Code extension · Takes 2 minutes
Installation and Setup: Node 18+, TypeScript Config
The Claude Agent SDK for TypeScript can be installed on its own via the @anthropic-ai/claude-agent-sdk package; Anthropic's official instructions do not require installing @anthropic-ai/sdk together with it. The two packages serve different purposes and aren't interchangeable, so figure out which one you actually need before adding either to your project.
| Package | Purpose | License | Entry Point |
|---|---|---|---|
| @anthropic-ai/sdk | REST API wrapper for Claude models | MIT | client.messages.create() |
| @anthropic-ai/claude-agent-sdk | Claude Agent SDK for building agents with built-in tool execution | Anthropic Commercial Terms | query() |
Install the packages explicitly:
The agent SDK re-exports aliased types from @anthropic-ai/sdk but does not declare it as a dependency. Without both packages in package.json, types can silently resolve to any, as described in issue #121. Verify both appear in your dependency list:
The @anthropic-ai/claude-agent-sdk accepts either Zod 3 (^3.24.1) or Zod 4 (^4.0.0) as a peer dependency, with Zod 4 support added in v0.1.71+ alongside continued Zod 3 compatibility. The SDK repository for @anthropic-ai/sdk includes tsconfig.build.json; consult the repo directly for canonical compiler settings. Both packages ship with built-in type declarations, so no separate @types/ package is needed.
Type-Safe Agent Definitions with the SDK
Type-safe agent definitions in the Claude SDK start with constraining model identifiers to verified string literals, then narrowing parameter types through Anthropic.MessageCreateParams and specialized config interfaces.
Model String Safety
The SDK accepts model strings as string for forward compatibility, but warns at runtime for deprecated models. A const object with literal types provides compile-time enforcement:
Typed Agent Configurations
Anthropic.MessageCreateParams, Anthropic.Message, and Anthropic.Tool are real exported types from src/resources/messages/messages.ts. Specialized agent configs use TypeScript narrowing to restrict model and token combinations:
Generic Typed Agent with Structured Output
The client.messages.parse() method combined with zodOutputFormat() from @anthropic-ai/sdk/helpers/zod infers the return type directly from a Zod schema, per the official example. The example below targets Zod 3; on Zod 4, replace zodOutputFormat(schema) with z.toJSONSchema(schema) directly, since zod-to-json-schema (which zodOutputFormat wraps) has documented incompatibilities with Zod 4 schemas:
TypeScript infers the full return shape from the Zod schema at compile time, so no separate interface definition is needed.
Known Type Safety Gaps
The adaptive thinking mode is a valid API value but does not appear in TypeScript type definitions yet, so a type assertion is required:
The same applies to newer tool types like tool_search_tool_regex_20251119, per issue #939.
Tool Schemas and Zod Validation Patterns
Tool schemas in the Claude API require JSON Schema format in the input_schema field, not Zod objects directly. Zod provides compile-time type inference through z.infer<> and runtime validation through parse() and safeParse(). The SDK also ships a betaZodTool helper that builds a runnable tool definition from a Zod schema and is designed to be passed into anthropic.beta.messages.toolRunner() for automatic execution.
Defining Schemas with Inferred Types
Converting Schemas to Claude Tool Definitions
Use zod-to-json-schema for the conversion. The default jsonSchema7 (draft-07) target produces output that the standard Messages API accepts directly, and adding strict: true guarantees Claude's tool calls always match the schema, per Anthropic's strict tool use docs:
This pattern targets the standard Messages API (client.messages.create()), which accepts draft-07 output. Tool schemas for Claude Code or MCP servers require JSON Schema draft-2020-12, so use Zod 4's native z.toJSONSchema(schema, { target: 'draft-2020-12' }) in those contexts instead of zod-to-json-schema.
The betaZodTool Helper
The SDK ships a built-in helper, documented in the official helpers reference, that combines schema conversion, type inference, and runtime validation in one call (added in v0.63.0+, per SDK discussion #817). betaZodTool is imported as a standalone function from @anthropic-ai/sdk/helpers, takes the Zod schema in an inputSchema field, and is then passed into anthropic.beta.messages.toolRunner():
The toolRunner handles the tool-use loop end to end: it calls messages.create, executes the matching run function with validated input, sends the result back to Claude, and repeats until the model returns a final message.
Type Safety by Layer
The mechanisms above each enforce safety at a different stage of the request lifecycle. The table below summarizes where each one catches errors:
| Mechanism | Enforcement Point |
|---|---|
| z.infer<typeof Schema> | Compile time: TypeScript errors on invalid field access |
| schema.parse(input) | Runtime: throws ZodError with field-level issues array |
| schema.safeParse(input) | Runtime: returns { success, error } without throwing |
| strict: true on a tool definition | Model output: schema conformance guaranteed by Claude, except in refusal cases |
| betaZodTool + toolRunner | Compile time + runtime: type inference from inputSchema, automatic invocation, validated input passed to run |
Once multiple typed tools start running across a large TypeScript project, coordinating them becomes the harder problem. Intent's coordinator agent decomposes work into tasks and delegates to specialist agents in parallel waves so work proceeds in sequence without conflicts, with a living spec acting as the shared coordination layer for every Claude Code instance involved.
See how Intent coordinates parallel Claude agents around a shared, evolving spec.
Free tier available · VS Code extension · Takes 2 minutes
in src/utils/helpers.ts:42
Streaming Responses: Handling Partial Outputs
Streaming responses from Claude-related streaming APIs are commonly represented with typed events such as message_start, content_block_start, content_block_delta, content_block_stop, message_delta, and message_stop, though the official TypeScript SDK example exposes higher-level .on('contentBlock', ...) and .on('message', ...) handlers rather than documenting that exact event sequence. The SDK provides four distinct patterns for consuming these events.
Pattern 1: Event Emitter with .on()
The client.messages.stream() method returns a MessageStream that accumulates the full message and exposes typed event callbacks:
Pattern 2: Raw Async Iterator (Low-Memory)
Setting stream: true on client.messages.create() returns a Stream<RawMessageStreamEvent> that does not accumulate a message object, using less memory per the SDK helpers docs:
Partial Tool Call Accumulation
Tool arguments arrive as input_json_delta events that contain incomplete JSON fragments. Example code in Anthropic's fine-grained tool streaming docs shows how to accumulate input_json_delta fragments and parse them on content_block_stop, demonstrated as an implementation pattern rather than an explicit recommendation:
Wrap every JSON.parse in try/catch within streaming pipelines. Issue #996 documents crashes on invalid escape sequences in the streaming path.
Type Guards for Stream Events
The SDK exposes streaming events that TypeScript can handle in a type-safe way:
Error Handling with Discriminated Unions
Error handling in Claude SDK TypeScript agents combines SDK instanceof checks for API-level errors with discriminated union types for application-level error routing. Some error classes extend Anthropic.APIError, while others, such as AbortError, extend the built-in Error class. The SDK automatically retries 429 and 5xx responses with exponential backoff (default max_retries=2), and max_retries is a configuration option that controls this behavior.
SDK Error Class Hierarchy
The official SDK exposes API error classes mapped to HTTP status codes. The exact mappings and retryability behavior described below could not be fully verified from official Anthropic documentation or source code, so confirm against the version you're running:
| HTTP Status | TypeScript Class | Retryable |
|---|---|---|
| 400 | Anthropic.BadRequestError | No |
| 401 | Anthropic.AuthenticationError | No |
| 403 | Anthropic.PermissionDeniedError | No |
| 404 | Anthropic.NotFoundError | No |
| 429 | Anthropic.RateLimitError | Yes |
| 500 | Anthropic.InternalServerError | Yes |
| 529 | Anthropic.OverloadedError | Yes |
instanceof checks must run most-specific to least-specific. RateLimitError must precede APIError, or the base class absorbs all subclasses.
Application-Level Discriminated Unions
A Result<T, E> type with a literal kind discriminant enables exhaustive switch statements that produce compile-time errors when new variants are added:
Adding a new variant to ToolError without a matching case produces a TypeScript error at the assertNever call, per TypeScript's narrowing documentation. The compiler then flags every error path that lacks a handler.
Surfacing Errors to Claude
When a tool call fails, return is_error: true on the ToolResultBlockParam. Claude uses this flag to reason about the failure and adjust its next action:
Scaling TypeScript Agents with Intent
Individual Claude agents built with the patterns above work well for single-task execution. Production TypeScript codebases with hundreds of files and cross-service dependencies require coordination across multiple agents working simultaneously, where each agent holds a subset of context.
Intent is the workspace where that coordination happens. It accepts Claude Code (built on @anthropic-ai/claude-agent-sdk) as a delegated agent runtime through a BYOA (Bring Your Own Agent) model, so existing Anthropic subscriptions cover model usage while Intent handles orchestration on an Augment Code account.
How Intent Coordinates TypeScript Agents
Intent uses a three-role architecture, with each role mapped to a separate agent and a shared living spec:
- Coordinator: Analyzes the codebase, drafts a living spec, decomposes tasks into a dependency-ordered DAG, then delegates to specialist agents in parallel batches
- Implementor agents: Execute subtasks simultaneously in isolated git worktrees so parallel execution avoids filesystem conflicts
- Verifier: Reads the spec and validates that implementations match before handoff
Intent ships with six built-in specialist personas (Investigate, Implement, Verify, Critique, Debug, Code Review) and supports custom agents defined as Markdown files with YAML front matter in .augment/agents/. Every agent is backed by the Context Engine, which is also exposed as an MCP server for third-party agent access.
Living Specs and CI/CD Integration
Living specs auto-update as agents complete work, so every agent reads the current state of the implementation rather than a stale PRD. When requirements change mid-flight, updates propagate to all active agents.
The Auggie CLI (npm install -g @augmentcode/auggie) enables headless execution in CI/CD pipelines. A GitHub Actions workflow can call Auggie to run spec-driven workflows alongside existing test stages.
Coordinate Multi-Agent TypeScript Work with a Shared Spec
The Claude Agent SDK gives TypeScript developers type safety through Zod-validated tool schemas, typed agent configs, and discriminated union error handling. The friction shows up when a single agent's context runs out before the task does. Cross-service TypeScript refactors, parallel implementation across isolated worktrees, and spec-driven coordination call for an orchestration layer that keeps multiple Claude agents aligned on shared, evolving requirements.
Intent's living specs and coordinator/implementor/verifier architecture keep independent Claude agents aligned as the plan changes, with each agent starting from the architectural context the codebase already contains.
See how Intent's living specs keep parallel agents aligned as TypeScript requirements evolve.
Free tier available · VS Code extension · Takes 2 minutes
FAQ
Related
Written by

Paula Hingel
Paula writes about the patterns that make AI coding agents actually work — spec-driven development, multi-agent orchestration, and the context engineering layer most teams skip. Her guides draw on real build examples and focus on what changes when you move from a single AI assistant to a full agentic codebase.