codeforge-dev 1.5.7 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.devcontainer/.env +2 -1
- package/.devcontainer/CHANGELOG.md +55 -9
- package/.devcontainer/CLAUDE.md +65 -15
- package/.devcontainer/README.md +67 -6
- package/.devcontainer/config/keybindings.json +5 -0
- package/.devcontainer/config/main-system-prompt.md +63 -2
- package/.devcontainer/config/settings.json +25 -6
- package/.devcontainer/devcontainer.json +23 -7
- package/.devcontainer/features/README.md +21 -7
- package/.devcontainer/features/ccburn/README.md +60 -0
- package/.devcontainer/features/ccburn/devcontainer-feature.json +38 -0
- package/.devcontainer/features/ccburn/install.sh +174 -0
- package/.devcontainer/features/ccstatusline/README.md +22 -21
- package/.devcontainer/features/ccstatusline/devcontainer-feature.json +1 -1
- package/.devcontainer/features/ccstatusline/install.sh +48 -16
- package/.devcontainer/features/claude-code/config/settings.json +60 -24
- package/.devcontainer/features/mcp-qdrant/devcontainer-feature.json +1 -1
- package/.devcontainer/features/mcp-reasoner/devcontainer-feature.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/__pycache__/format-on-stop.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/format-on-stop.py +21 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/__pycache__/lint-file.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/lint-file.py +7 -10
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/REVIEW-RUBRIC.md +440 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/architect.md +190 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/bash-exec.md +173 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/claude-guide.md +155 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/dependency-analyst.md +248 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/doc-writer.md +233 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/explorer.md +235 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/generalist.md +125 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/git-archaeologist.md +242 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/migrator.md +195 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/perf-profiler.md +265 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/refactorer.md +209 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/researcher.md +195 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/security-auditor.md +289 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/spec-writer.md +284 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/statusline-config.md +188 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/test-writer.md +245 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/hooks/hooks.json +12 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/guard-readonly-bash.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/redirect-builtin-agents.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/skill-suggester.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/syntax-validator.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/verify-no-regression.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/verify-tests-pass.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/guard-readonly-bash.py +611 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/redirect-builtin-agents.py +83 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/skill-suggester.py +85 -2
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/syntax-validator.py +9 -4
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/verify-no-regression.py +221 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/verify-tests-pass.py +176 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/claude-agent-sdk/SKILL.md +599 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/claude-agent-sdk/references/sdk-typescript-reference.md +954 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/git-forensics/SKILL.md +276 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/git-forensics/references/advanced-commands.md +332 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/git-forensics/references/investigation-playbooks.md +319 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/performance-profiling/SKILL.md +341 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/performance-profiling/references/interpreting-results.md +235 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/performance-profiling/references/tool-commands.md +395 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/refactoring-patterns/SKILL.md +344 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/refactoring-patterns/references/safe-transformations.md +247 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/refactoring-patterns/references/smell-catalog.md +332 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/security-checklist/SKILL.md +277 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/security-checklist/references/owasp-patterns.md +269 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/security-checklist/references/secrets-patterns.md +253 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/SKILL.md +288 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/references/criteria-patterns.md +245 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/references/ears-templates.md +239 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/__pycache__/guard-protected.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected.py +40 -39
- package/.devcontainer/scripts/setup-aliases.sh +10 -20
- package/.devcontainer/scripts/setup-config.sh +2 -0
- package/.devcontainer/scripts/setup-plugins.sh +38 -46
- package/.devcontainer/scripts/setup-projects.sh +175 -0
- package/.devcontainer/scripts/setup-symlink-claude.sh +36 -0
- package/.devcontainer/scripts/setup-update-claude.sh +11 -8
- package/.devcontainer/scripts/setup.sh +4 -2
- package/package.json +1 -1
- package/.devcontainer/scripts/setup-irie-claude.sh +0 -32
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: claude-agent-sdk
|
|
3
|
+
description: >-
|
|
4
|
+
This skill should be used when the user asks to "build an agent with the Claude Agent SDK",
|
|
5
|
+
"use the Claude Agent SDK", "create an agent with TypeScript SDK", "configure SDK permissions",
|
|
6
|
+
"use canUseTool callback", "create custom MCP tools with createSdkMcpServer",
|
|
7
|
+
"manage SDK sessions", "define subagents", "configure SDK hooks",
|
|
8
|
+
"set up SDK sandbox", "stream SDK messages", "use sdk query function",
|
|
9
|
+
or discusses Claude Agent SDK TypeScript integration, SDK permission modes,
|
|
10
|
+
SDK message types, agent definitions, or programmatic Claude agent orchestration.
|
|
11
|
+
version: 0.1.0
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Claude Agent SDK (TypeScript)
|
|
15
|
+
|
|
16
|
+
## Mental Model
|
|
17
|
+
|
|
18
|
+
The Claude Agent SDK is the Claude Code agent loop as a library. The same tools (Read, Write, Edit, Bash, Glob, Grep, WebSearch, WebFetch), the same context management, the same permission system — but accessed programmatically from TypeScript instead of through a CLI.
|
|
19
|
+
|
|
20
|
+
The SDK gives you a single function: `query()`. You pass a prompt and options, and get back an async generator of structured messages. The agent loop runs internally — reading files, executing commands, editing code — and you observe or control it through the message stream and callbacks.
|
|
21
|
+
|
|
22
|
+
Key distinction: The SDK is locked to Anthropic's Claude models. It supports cloud-hosted Claude through Bedrock, Vertex AI, and Azure AI Foundry, but cannot use non-Anthropic models. For multi-model support (GPT, Gemini, Groq, Mistral, Ollama), use PydanticAI (Path B).
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Getting Started
|
|
27
|
+
|
|
28
|
+
### Install
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install @anthropic-ai/claude-agent-sdk
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Authentication
|
|
35
|
+
|
|
36
|
+
Set your API key:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
export ANTHROPIC_API_KEY=your-api-key
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
For cloud-hosted Claude:
|
|
43
|
+
|
|
44
|
+
| Provider | Environment Variable |
|
|
45
|
+
|----------|---------------------|
|
|
46
|
+
| Amazon Bedrock | `CLAUDE_CODE_USE_BEDROCK=1` + AWS credentials |
|
|
47
|
+
| Google Vertex AI | `CLAUDE_CODE_USE_VERTEX=1` + Google Cloud credentials |
|
|
48
|
+
| Azure AI Foundry | `CLAUDE_CODE_USE_FOUNDRY=1` + Azure credentials |
|
|
49
|
+
|
|
50
|
+
### First Query
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
54
|
+
|
|
55
|
+
for await (const message of query({
|
|
56
|
+
prompt: "Find and fix the bug in auth.py",
|
|
57
|
+
options: {
|
|
58
|
+
allowedTools: ["Read", "Edit", "Bash"],
|
|
59
|
+
permissionMode: "acceptEdits",
|
|
60
|
+
model: "sonnet",
|
|
61
|
+
},
|
|
62
|
+
})) {
|
|
63
|
+
if (message.type === "assistant") {
|
|
64
|
+
for (const block of message.message.content) {
|
|
65
|
+
if ("text" in block) process.stdout.write(block.text);
|
|
66
|
+
}
|
|
67
|
+
} else if (message.type === "result") {
|
|
68
|
+
console.log(`\nDone: ${message.subtype} | Cost: $${message.total_cost_usd}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Core API
|
|
76
|
+
|
|
77
|
+
### `query()` Signature
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
function query({
|
|
81
|
+
prompt,
|
|
82
|
+
options
|
|
83
|
+
}: {
|
|
84
|
+
prompt: string | AsyncIterable<SDKUserMessage>;
|
|
85
|
+
options?: Options;
|
|
86
|
+
}): Query
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`prompt` is either a string or an async iterable for streaming input mode. The return value is a `Query` object — an `AsyncGenerator<SDKMessage, void>` with additional control methods.
|
|
90
|
+
|
|
91
|
+
### Key Options Fields
|
|
92
|
+
|
|
93
|
+
| Field | Type | Default | Purpose |
|
|
94
|
+
|-------|------|---------|---------|
|
|
95
|
+
| `model` | `string` | CLI default | Claude model to use (e.g., `"sonnet"`, `"opus"`, `"haiku"`) |
|
|
96
|
+
| `allowedTools` | `string[]` | All tools | Tools the agent can use |
|
|
97
|
+
| `disallowedTools` | `string[]` | `[]` | Tools removed from model context entirely |
|
|
98
|
+
| `permissionMode` | `PermissionMode` | `'default'` | Permission behavior preset |
|
|
99
|
+
| `maxTurns` | `number` | unlimited | Maximum agentic turns before stopping |
|
|
100
|
+
| `maxBudgetUsd` | `number` | unlimited | Maximum dollar spend |
|
|
101
|
+
| `systemPrompt` | `string \| PresetPrompt` | minimal | System prompt — string for custom, or preset object |
|
|
102
|
+
| `mcpServers` | `Record<string, McpServerConfig>` | `{}` | MCP server configurations |
|
|
103
|
+
| `agents` | `Record<string, AgentDefinition>` | `undefined` | Subagent definitions |
|
|
104
|
+
| `hooks` | `Partial<Record<HookEvent, HookCallbackMatcher[]>>` | `{}` | Callback hooks for lifecycle events |
|
|
105
|
+
| `cwd` | `string` | `process.cwd()` | Working directory |
|
|
106
|
+
| `resume` | `string` | `undefined` | Session ID to resume |
|
|
107
|
+
| `settingSources` | `SettingSource[]` | `[]` | Which filesystem settings to load |
|
|
108
|
+
| `canUseTool` | `CanUseTool` | `undefined` | Custom permission callback |
|
|
109
|
+
| `sandbox` | `SandboxSettings` | `undefined` | Sandbox configuration |
|
|
110
|
+
|
|
111
|
+
### System Prompt Options
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// Custom system prompt (replaces default)
|
|
115
|
+
systemPrompt: "You are a security auditor. Review code for vulnerabilities."
|
|
116
|
+
|
|
117
|
+
// Preset with append (preserves Claude Code defaults + adds instructions)
|
|
118
|
+
systemPrompt: {
|
|
119
|
+
type: "preset",
|
|
120
|
+
preset: "claude_code",
|
|
121
|
+
append: "Focus on security best practices.",
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The preset approach is recommended — it preserves Claude Code's built-in tool usage patterns while adding custom instructions.
|
|
126
|
+
|
|
127
|
+
### Query Control Methods
|
|
128
|
+
|
|
129
|
+
The `Query` object exposes methods for runtime control (primarily useful in streaming input mode):
|
|
130
|
+
|
|
131
|
+
| Method | Description |
|
|
132
|
+
|--------|-------------|
|
|
133
|
+
| `interrupt()` | Interrupts the current query |
|
|
134
|
+
| `rewindFiles(uuid)` | Restores files to state at a message. Requires `enableFileCheckpointing: true` |
|
|
135
|
+
| `setPermissionMode(mode)` | Changes the permission mode at runtime |
|
|
136
|
+
| `setModel(model)` | Changes the model at runtime |
|
|
137
|
+
| `setMaxThinkingTokens(n)` | Changes max thinking tokens |
|
|
138
|
+
| `supportedCommands()` | Returns available slash commands |
|
|
139
|
+
| `supportedModels()` | Returns available models with display info |
|
|
140
|
+
| `mcpServerStatus()` | Returns status of connected MCP servers |
|
|
141
|
+
| `accountInfo()` | Returns account information |
|
|
142
|
+
|
|
143
|
+
> **Deep dive:** See `references/sdk-typescript-reference.md` for the complete `Options` interface (~35 fields), full `Query` type definition, and all control methods.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Message Types
|
|
148
|
+
|
|
149
|
+
The `query()` generator yields `SDKMessage` — a union of message types that form the event stream:
|
|
150
|
+
|
|
151
|
+
```text
|
|
152
|
+
system (init) -> assistant/user messages (interleaved) -> result (final)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### SDKMessage Union
|
|
156
|
+
|
|
157
|
+
| Type | `message.type` | `message.subtype` | When |
|
|
158
|
+
|------|----------------|-------------------|------|
|
|
159
|
+
| `SDKSystemMessage` | `"system"` | `"init"` | First message — session metadata |
|
|
160
|
+
| `SDKAssistantMessage` | `"assistant"` | — | Agent text, tool calls, thinking |
|
|
161
|
+
| `SDKUserMessage` | `"user"` | — | Tool results fed back to the model |
|
|
162
|
+
| `SDKResultMessage` | `"result"` | `"success"` or error variant | Final message — cost, usage, outcome |
|
|
163
|
+
| `SDKPartialAssistantMessage` | `"stream_event"` | — | Streaming tokens (requires `includePartialMessages: true`) |
|
|
164
|
+
| `SDKCompactBoundaryMessage` | `"system"` | `"compact_boundary"` | Context compaction occurred |
|
|
165
|
+
|
|
166
|
+
### System Init Message
|
|
167
|
+
|
|
168
|
+
The first message provides session metadata:
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
if (message.type === "system" && message.subtype === "init") {
|
|
172
|
+
console.log(`Session: ${message.session_id}`);
|
|
173
|
+
console.log(`Model: ${message.model}`);
|
|
174
|
+
console.log(`Tools: ${message.tools.join(", ")}`);
|
|
175
|
+
console.log(`Permission mode: ${message.permissionMode}`);
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Result Message
|
|
180
|
+
|
|
181
|
+
The final message contains cost tracking and outcome:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
if (message.type === "result") {
|
|
185
|
+
if (message.subtype === "success") {
|
|
186
|
+
console.log(`Result: ${message.result}`);
|
|
187
|
+
console.log(`Cost: $${message.total_cost_usd}`);
|
|
188
|
+
console.log(`Turns: ${message.num_turns}`);
|
|
189
|
+
console.log(`Duration: ${message.duration_ms}ms`);
|
|
190
|
+
} else {
|
|
191
|
+
// Error variants: error_max_turns, error_during_execution,
|
|
192
|
+
// error_max_budget_usd, error_max_structured_output_retries
|
|
193
|
+
console.error(`Error: ${message.subtype}`, message.errors);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
> **Deep dive:** See `references/sdk-typescript-reference.md` for complete TypeScript type definitions of all message types, including `SDKPermissionDenial`, `ModelUsage`, and `NonNullableUsage`.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Permissions
|
|
203
|
+
|
|
204
|
+
### Permission Modes
|
|
205
|
+
|
|
206
|
+
| Mode | Behavior |
|
|
207
|
+
|------|----------|
|
|
208
|
+
| `'default'` | Standard prompting for sensitive operations |
|
|
209
|
+
| `'acceptEdits'` | Auto-accept file edits; prompt for bash commands |
|
|
210
|
+
| `'plan'` | Planning mode — read-only, no execution |
|
|
211
|
+
| `'bypassPermissions'` | Skip all permission checks (requires `allowDangerouslySkipPermissions: true`) |
|
|
212
|
+
|
|
213
|
+
### `canUseTool` Callback
|
|
214
|
+
|
|
215
|
+
For fine-grained permission control, provide a `canUseTool` callback:
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
import { query, PermissionResult } from "@anthropic-ai/claude-agent-sdk";
|
|
219
|
+
|
|
220
|
+
for await (const message of query({
|
|
221
|
+
prompt: "Refactor the auth module",
|
|
222
|
+
options: {
|
|
223
|
+
canUseTool: async (
|
|
224
|
+
toolName: string,
|
|
225
|
+
input: ToolInput,
|
|
226
|
+
{ signal, suggestions }
|
|
227
|
+
): Promise<PermissionResult> => {
|
|
228
|
+
// Allow all reads
|
|
229
|
+
if (toolName === "Read" || toolName === "Glob" || toolName === "Grep") {
|
|
230
|
+
return { behavior: "allow", updatedInput: input };
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Block destructive bash commands
|
|
234
|
+
if (toolName === "Bash" && /rm\s+-rf/.test((input as any).command)) {
|
|
235
|
+
return { behavior: "deny", message: "Destructive commands blocked" };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Allow everything else
|
|
239
|
+
return { behavior: "allow", updatedInput: input };
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
})) {
|
|
243
|
+
// process messages
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### PermissionResult Type
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
type PermissionResult =
|
|
251
|
+
| { behavior: "allow"; updatedInput: ToolInput; updatedPermissions?: PermissionUpdate[] }
|
|
252
|
+
| { behavior: "deny"; message: string; interrupt?: boolean }
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
- **Allow** — must include `updatedInput` (can be the original input unchanged). Optionally update permission rules.
|
|
256
|
+
- **Deny** — must include a `message` explaining why. Set `interrupt: true` to stop the entire query.
|
|
257
|
+
|
|
258
|
+
### Read-Only Agent Pattern
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
for await (const message of query({
|
|
262
|
+
prompt: "Review this code for best practices",
|
|
263
|
+
options: {
|
|
264
|
+
allowedTools: ["Read", "Glob", "Grep"],
|
|
265
|
+
permissionMode: "bypassPermissions",
|
|
266
|
+
allowDangerouslySkipPermissions: true,
|
|
267
|
+
},
|
|
268
|
+
})) {
|
|
269
|
+
if ("result" in message) console.log(message.result);
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Custom MCP Tools
|
|
276
|
+
|
|
277
|
+
Create in-process MCP tools using `createSdkMcpServer()` and `tool()` with Zod schemas:
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
import { query, createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
|
|
281
|
+
import { z } from "zod";
|
|
282
|
+
|
|
283
|
+
const ticketServer = createSdkMcpServer({
|
|
284
|
+
name: "ticket-tools",
|
|
285
|
+
tools: [
|
|
286
|
+
tool(
|
|
287
|
+
"create_ticket",
|
|
288
|
+
"Create a support ticket in the issue tracker",
|
|
289
|
+
{ title: z.string(), priority: z.enum(["low", "medium", "high"]) },
|
|
290
|
+
async ({ title, priority }) => ({
|
|
291
|
+
content: [{ type: "text", text: `Ticket created: ${title} (${priority})` }],
|
|
292
|
+
})
|
|
293
|
+
),
|
|
294
|
+
tool(
|
|
295
|
+
"list_tickets",
|
|
296
|
+
"List open tickets",
|
|
297
|
+
{ status: z.enum(["open", "closed", "all"]).default("open") },
|
|
298
|
+
async ({ status }) => ({
|
|
299
|
+
content: [{ type: "text", text: `Listing ${status} tickets...` }],
|
|
300
|
+
})
|
|
301
|
+
),
|
|
302
|
+
],
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
for await (const message of query({
|
|
306
|
+
prompt: "Create a high-priority ticket for the auth bug",
|
|
307
|
+
options: {
|
|
308
|
+
mcpServers: { tickets: ticketServer },
|
|
309
|
+
},
|
|
310
|
+
})) {
|
|
311
|
+
// The agent can now use create_ticket and list_tickets
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### External MCP Servers
|
|
316
|
+
|
|
317
|
+
Connect external MCP servers via stdio, SSE, or HTTP:
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
mcpServers: {
|
|
321
|
+
// stdio — spawns a subprocess
|
|
322
|
+
playwright: { command: "npx", args: ["@playwright/mcp@latest"] },
|
|
323
|
+
|
|
324
|
+
// SSE — connects to a running server
|
|
325
|
+
myServer: { type: "sse", url: "http://localhost:3001/sse" },
|
|
326
|
+
|
|
327
|
+
// HTTP — streamable HTTP transport
|
|
328
|
+
remote: { type: "http", url: "https://api.example.com/mcp" },
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Sessions
|
|
335
|
+
|
|
336
|
+
### Capture and Resume
|
|
337
|
+
|
|
338
|
+
Capture the `session_id` from the init message, then pass it as `resume` to continue:
|
|
339
|
+
|
|
340
|
+
```typescript
|
|
341
|
+
let sessionId: string | undefined;
|
|
342
|
+
|
|
343
|
+
// First query — capture session ID
|
|
344
|
+
for await (const message of query({
|
|
345
|
+
prompt: "Read the authentication module",
|
|
346
|
+
options: { allowedTools: ["Read", "Glob"] },
|
|
347
|
+
})) {
|
|
348
|
+
if (message.type === "system" && message.subtype === "init") {
|
|
349
|
+
sessionId = message.session_id;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Second query — resume the session
|
|
354
|
+
for await (const message of query({
|
|
355
|
+
prompt: "Now find all places that call it",
|
|
356
|
+
options: { resume: sessionId },
|
|
357
|
+
})) {
|
|
358
|
+
if ("result" in message) console.log(message.result);
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Fork Session
|
|
363
|
+
|
|
364
|
+
Create a new session ID that preserves context but diverges history:
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
for await (const message of query({
|
|
368
|
+
prompt: "Try an alternative approach",
|
|
369
|
+
options: {
|
|
370
|
+
resume: sessionId,
|
|
371
|
+
forkSession: true, // new session ID, same conversation context
|
|
372
|
+
},
|
|
373
|
+
})) {
|
|
374
|
+
// ...
|
|
375
|
+
}
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## Subagents
|
|
381
|
+
|
|
382
|
+
Define specialized agents that the main agent can delegate to via the Task tool:
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
for await (const message of query({
|
|
386
|
+
prompt: "Review this codebase for security issues, then fix any critical findings",
|
|
387
|
+
options: {
|
|
388
|
+
allowedTools: ["Read", "Write", "Edit", "Glob", "Grep", "Task"],
|
|
389
|
+
agents: {
|
|
390
|
+
"security-reviewer": {
|
|
391
|
+
description: "Expert security auditor. Finds vulnerabilities in code.",
|
|
392
|
+
prompt: "Analyze code for security vulnerabilities. Report findings with severity levels.",
|
|
393
|
+
tools: ["Read", "Glob", "Grep"],
|
|
394
|
+
model: "opus",
|
|
395
|
+
},
|
|
396
|
+
"code-fixer": {
|
|
397
|
+
description: "Applies targeted code fixes based on review findings.",
|
|
398
|
+
prompt: "Fix the identified issues with minimal changes. Preserve existing behavior.",
|
|
399
|
+
tools: ["Read", "Edit", "Write"],
|
|
400
|
+
model: "sonnet",
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
},
|
|
404
|
+
})) {
|
|
405
|
+
// The main agent orchestrates: delegates review to security-reviewer,
|
|
406
|
+
// then passes findings to code-fixer
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### AgentDefinition
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
type AgentDefinition = {
|
|
414
|
+
description: string; // When to use this agent
|
|
415
|
+
prompt: string; // The agent's system prompt
|
|
416
|
+
tools?: string[]; // Allowed tools (inherits all if omitted)
|
|
417
|
+
model?: "sonnet" | "opus" | "haiku" | "inherit"; // Model override
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
Messages from subagents include a `parent_tool_use_id` field for tracking which delegation produced them.
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## Hooks
|
|
426
|
+
|
|
427
|
+
SDK callback hooks intercept lifecycle events for logging, validation, or control:
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
import { query, HookCallback } from "@anthropic-ai/claude-agent-sdk";
|
|
431
|
+
import { appendFileSync } from "fs";
|
|
432
|
+
|
|
433
|
+
const auditLog: HookCallback = async (input) => {
|
|
434
|
+
const filePath = (input as any).tool_input?.file_path ?? "unknown";
|
|
435
|
+
appendFileSync("./audit.log", `${new Date().toISOString()}: modified ${filePath}\n`);
|
|
436
|
+
return {};
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
const blockDestructive: HookCallback = async (input) => {
|
|
440
|
+
const cmd = (input as any).tool_input?.command ?? "";
|
|
441
|
+
if (/rm\s+-rf\s+\//.test(cmd)) {
|
|
442
|
+
return {
|
|
443
|
+
hookSpecificOutput: {
|
|
444
|
+
hookEventName: "PreToolUse",
|
|
445
|
+
permissionDecision: "deny",
|
|
446
|
+
permissionDecisionReason: "Destructive command blocked by hook",
|
|
447
|
+
},
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
return {};
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
for await (const message of query({
|
|
454
|
+
prompt: "Clean up the project",
|
|
455
|
+
options: {
|
|
456
|
+
permissionMode: "acceptEdits",
|
|
457
|
+
hooks: {
|
|
458
|
+
PostToolUse: [{ matcher: "Edit|Write", hooks: [auditLog] }],
|
|
459
|
+
PreToolUse: [{ matcher: "Bash", hooks: [blockDestructive] }],
|
|
460
|
+
},
|
|
461
|
+
},
|
|
462
|
+
})) {
|
|
463
|
+
// ...
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Available Hook Events
|
|
468
|
+
|
|
469
|
+
| Event | When | Use Case |
|
|
470
|
+
|-------|------|----------|
|
|
471
|
+
| `PreToolUse` | Before a tool executes | Validation, permission override, input modification |
|
|
472
|
+
| `PostToolUse` | After a tool succeeds | Audit logging, output inspection |
|
|
473
|
+
| `PostToolUseFailure` | After a tool fails | Error tracking, retry logic |
|
|
474
|
+
| `Stop` | Agent is about to stop | Final validation, cleanup |
|
|
475
|
+
| `UserPromptSubmit` | User prompt received | Prompt filtering, context injection |
|
|
476
|
+
| `SessionStart` | Session begins | Setup, context loading |
|
|
477
|
+
| `SessionEnd` | Session ends | Cleanup, reporting |
|
|
478
|
+
| `SubagentStart` | Subagent spawned | Tracking, resource allocation |
|
|
479
|
+
| `SubagentStop` | Subagent finished | Result aggregation |
|
|
480
|
+
| `PreCompact` | Before context compaction | Custom compaction instructions |
|
|
481
|
+
| `Notification` | Agent sends a notification | Routing notifications |
|
|
482
|
+
| `PermissionRequest` | Permission prompt triggered | Custom permission UI |
|
|
483
|
+
|
|
484
|
+
### HookCallbackMatcher
|
|
485
|
+
|
|
486
|
+
```typescript
|
|
487
|
+
interface HookCallbackMatcher {
|
|
488
|
+
matcher?: string; // Regex pattern to match tool names (for tool hooks)
|
|
489
|
+
hooks: HookCallback[];
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
The `matcher` field is a regex string tested against the tool name. Omit it to match all tools.
|
|
494
|
+
|
|
495
|
+
> **Deep dive:** See `references/sdk-typescript-reference.md` for all `HookInput` variants, `HookJSONOutput` fields, and `AsyncHookJSONOutput` for long-running hooks.
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
## Sandbox
|
|
500
|
+
|
|
501
|
+
Configure sandboxed execution for untrusted environments:
|
|
502
|
+
|
|
503
|
+
```typescript
|
|
504
|
+
for await (const message of query({
|
|
505
|
+
prompt: "Build and test my project",
|
|
506
|
+
options: {
|
|
507
|
+
sandbox: {
|
|
508
|
+
enabled: true,
|
|
509
|
+
autoAllowBashIfSandboxed: true,
|
|
510
|
+
network: { allowLocalBinding: true },
|
|
511
|
+
},
|
|
512
|
+
},
|
|
513
|
+
})) {
|
|
514
|
+
// Agent runs in sandbox — filesystem and network restricted
|
|
515
|
+
}
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### SandboxSettings
|
|
519
|
+
|
|
520
|
+
| Property | Type | Default | Description |
|
|
521
|
+
|----------|------|---------|-------------|
|
|
522
|
+
| `enabled` | `boolean` | `false` | Enable sandbox mode |
|
|
523
|
+
| `autoAllowBashIfSandboxed` | `boolean` | `false` | Auto-approve bash when sandboxed |
|
|
524
|
+
| `excludedCommands` | `string[]` | `[]` | Commands that always bypass sandbox |
|
|
525
|
+
| `allowUnsandboxedCommands` | `boolean` | `false` | Allow model to request unsandboxed execution |
|
|
526
|
+
| `network` | `NetworkSandboxSettings` | `undefined` | Network restrictions |
|
|
527
|
+
|
|
528
|
+
### Permissions Fallback
|
|
529
|
+
|
|
530
|
+
When `allowUnsandboxedCommands` is `true`, the model can set `dangerouslyDisableSandbox: true` in tool input. These requests fall back to the `canUseTool` handler:
|
|
531
|
+
|
|
532
|
+
```typescript
|
|
533
|
+
canUseTool: async (tool, input) => {
|
|
534
|
+
if (tool === "Bash" && (input as any).dangerouslyDisableSandbox) {
|
|
535
|
+
console.log(`Unsandboxed command requested: ${(input as any).command}`);
|
|
536
|
+
// Apply your own authorization logic
|
|
537
|
+
return { behavior: "deny", message: "Unsandboxed execution not allowed" };
|
|
538
|
+
}
|
|
539
|
+
return { behavior: "allow", updatedInput: input };
|
|
540
|
+
}
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
**Warning:** If `permissionMode` is `"bypassPermissions"` AND `allowUnsandboxedCommands` is enabled, the model can execute commands outside the sandbox without approval.
|
|
544
|
+
|
|
545
|
+
---
|
|
546
|
+
|
|
547
|
+
## Authentication Model
|
|
548
|
+
|
|
549
|
+
### Self-Hosted (Local)
|
|
550
|
+
|
|
551
|
+
OAuth subscription — CodeDirective manages API access. The user authenticates through the platform, and the SDK uses the subscription credentials automatically.
|
|
552
|
+
|
|
553
|
+
### Customer Infrastructure (BYOK)
|
|
554
|
+
|
|
555
|
+
User provides their own API credentials:
|
|
556
|
+
|
|
557
|
+
```bash
|
|
558
|
+
# Direct Anthropic API
|
|
559
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
560
|
+
|
|
561
|
+
# Amazon Bedrock
|
|
562
|
+
export CLAUDE_CODE_USE_BEDROCK=1
|
|
563
|
+
# + AWS credentials (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION)
|
|
564
|
+
|
|
565
|
+
# Google Vertex AI
|
|
566
|
+
export CLAUDE_CODE_USE_VERTEX=1
|
|
567
|
+
# + Google Cloud credentials (GOOGLE_APPLICATION_CREDENTIALS)
|
|
568
|
+
|
|
569
|
+
# Azure AI Foundry
|
|
570
|
+
export CLAUDE_CODE_USE_FOUNDRY=1
|
|
571
|
+
# + Azure credentials
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
### Model Constraint
|
|
575
|
+
|
|
576
|
+
The Claude Agent SDK supports Claude models only. This includes all Claude model variants (Haiku, Sonnet, Opus) across all supported providers (Anthropic API, Bedrock, Vertex AI, Foundry).
|
|
577
|
+
|
|
578
|
+
For multi-model support (GPT, Gemini, Groq, Mistral, Ollama), use PydanticAI (Path B).
|
|
579
|
+
|
|
580
|
+
---
|
|
581
|
+
|
|
582
|
+
## Ambiguity Policy
|
|
583
|
+
|
|
584
|
+
These defaults apply when the user does not specify a preference. State the assumption when applying a default:
|
|
585
|
+
|
|
586
|
+
- **System prompt:** `{ type: "preset", preset: "claude_code", append: "..." }` to preserve default behaviors
|
|
587
|
+
- **Permission mode:** `"acceptEdits"` for trusted automation; `"plan"` for read-only analysis
|
|
588
|
+
- **Model:** `"sonnet"` for automation tasks (balanced cost and capability)
|
|
589
|
+
- **Session persistence:** New session by default; resume only when continuation is explicitly needed
|
|
590
|
+
- **Settings sources:** `[]` (no filesystem settings) unless the user needs CLAUDE.md or project settings
|
|
591
|
+
- **Sandbox:** Disabled by default; enable for untrusted environments or multi-tenant scenarios
|
|
592
|
+
|
|
593
|
+
---
|
|
594
|
+
|
|
595
|
+
## Reference Files
|
|
596
|
+
|
|
597
|
+
| File | Contents |
|
|
598
|
+
|------|----------|
|
|
599
|
+
| `references/sdk-typescript-reference.md` | Full Options interface, Query object methods, all SDKMessage type definitions, CanUseTool callback, createSdkMcpServer + tool(), hook types and inputs, sandbox configuration, tool input/output types, cost tracking, permission types |
|