Date: 2026-01-26 Reviewer: Claude Opus 4.5 + Codex (via pairctl) Sources: Official Python Agent SDK reference (platform.claude.com), knowctl claude-code topic, web research, cross-skill analysis
The agents-sdk-creator skill is a comprehensive guide for building Python applications with the Claude Agent SDK. It includes a 7-phase workflow, 4 graded examples, 7 reference documents, and 2 validation scripts. The documentation depth and structure are strong.
However, the skill contains a critical factual error about query() vs ClaudeSDKClient capabilities that propagates through multiple files and would cause agents to produce non-functional code. The official Python SDK reference states that hooks, custom tools, and interrupts are only supported by ClaudeSDKClient, but the skill claims all three work with query(). This error affects the decision guide, the flagship "complete agent" example, the tools reference, and the hooks reference.
Beyond this central issue, the skill is missing coverage of several newer SDK features (sandbox settings, plugin loading, file checkpointing), uses asyncio.run instead of the officially recommended anyio.run, and follows a different workflow structure than sibling skills in the same plugin.
Strengths:
- Three-tier progressive disclosure (SKILL.md -> references/ -> examples/) follows the pattern established by sibling skills
- Validation script (
validate-agent-script.sh) catches common errors like deprecated imports, missing async patterns, and incorrect API usage - Context detection script (
detect-sdk-context.sh) smartly identifies existing SDK projects - Examples are graded by complexity (minimal -> standard -> complete -> multi-turn)
- Quick reference tables in SKILL.md provide useful at-a-glance information
Structural differences from sibling skills:
- Uses 7 phases instead of the standard 6 used by command-creator, hook-creator, skill-creator, subagent-creator, plugin-creator, and marketplace-creator
- Sibling pattern: Requirements -> Context Detection -> Research -> Structure -> Content -> Validation
- This skill: Requirements -> Project Setup -> Research -> Build -> Hooks/Permissions -> Subagents -> Validation
- The 7-phase approach is reasonable given the different nature of this skill (building Python apps vs creating Claude Code config files), but the naming deviation may cause friction for agents familiar with the shared pattern
- Clear imperative style consistent with sibling skills
- Description follows the standard trigger-phrase pattern:
"This skill should be used when the user asks to..." - Good use of decision tables for API selection and permission modes
- Code examples are well-commented and practical
Description: The comparison table in SKILL.md (and repeated in references/api-reference.md) incorrectly states that query() supports hooks ("Yes (via options)") and custom tools ("Yes (via options)"). The official Python SDK reference at platform.claude.com/docs/en/agent-sdk/python explicitly states these are NOT supported by query():
| Feature | query() | ClaudeSDKClient |
|---|---|---|
| Hooks | Not supported | Supported |
| Custom Tools | Not supported | Supported |
| Interrupts | Not supported | Supported |
| Continue Chat | New session each time | Maintains conversation |
This error propagates to:
- SKILL.md Phase 1 decision guide (directs users to choose
query()even when they need hooks/tools) - SKILL.md Phase 4 custom tools code snippet (shows options with MCP tools in
query()context) - SKILL.md Phase 5 hook example (builds hooks config but pairs it with
query()) examples/complete-agent.md— the flagship example usesquery()with hooks, custom MCP tools, AND subagents simultaneously. This code would fail at runtime.references/tools-reference.md— explicitly states "Bothquery()andClaudeSDKClientsupport custom MCP tools viaoptions" and shows aquery()example with custom toolsreferences/hooks-and-permissions.md— hook examples define options but don't showClaudeSDKClientusagereferences/patterns-guide.md— no pattern demonstrates hooks +ClaudeSDKClient
Why it matters: This is the single most impactful error. An agent following this skill would produce code that silently fails or throws errors. The "complete agent" example — which agents would naturally copy as a best-practice template — is non-functional according to the official SDK.
Suggested approach:
- Update the comparison table in SKILL.md and api-reference.md to match official docs
- Revise the Phase 1 decision guide: "If you need hooks, custom tools, or interrupts, you MUST use
ClaudeSDKClientregardless of whether the task is one-shot" - Rewrite
examples/complete-agent.mdto useClaudeSDKClient(can still be a one-shot pattern usingasync with ClaudeSDKClient() as client:with a single query/response cycle) - Update tools-reference.md "Running Custom Tools" section to use
ClaudeSDKClient - Update hooks-and-permissions.md examples to use
ClaudeSDKClient - Add a new pattern to patterns-guide.md: "One-shot with hooks and custom tools" using
ClaudeSDKClient - Update validate-agent-script.sh to warn when hooks or custom tools are detected alongside
query()usage
Notes and status: ready
Description: The official Agent SDK quickstart (platform.claude.com/docs/en/agent-sdk/quickstart) uses anyio.run(main) instead of asyncio.run(main()). The skill exclusively uses asyncio.run() in all examples and the validation checklist.
anyio is an async compatibility library that avoids event-loop conflicts in environments where an event loop is already running (e.g., Jupyter notebooks, some web frameworks). The SDK quickstart chose it deliberately.
Why it matters: Users running agent scripts in environments with existing event loops will get RuntimeError: This event loop is already running. Using anyio.run is the safer default and matches official guidance.
Suggested approach:
- Update SKILL.md Phase 2 (Project Setup) to recommend
anyioas the default runner, notingasyncio.run()works in standalone scripts - Update the uv script template to include
anyioas a dependency:# /// script # requires-python = ">=3.10" # dependencies = ["claude-agent-sdk", "anyio"] # ///
- Update examples to use
anyio.run(main)(note: no parentheses onmain) - Add a note in SKILL.md explaining when
asyncio.run()is acceptable (standalone scripts with no existing event loop) - Update validate-agent-script.sh to suggest
anyio.runas the preferred pattern
Notes and status: ready
Description: The official SDK reference documents SandboxSettings, SandboxNetworkConfig, and SandboxIgnoreViolations as full configuration types for controlling command execution sandboxing, network isolation, and violation handling. The skill mentions sandbox in the ClaudeAgentOptions listing with a one-line example but provides no reference documentation, no patterns, and no explanation of the security implications.
Key features missing from the skill:
SandboxSettings:enabled,autoAllowBashIfSandboxed,excludedCommands,allowUnsandboxedCommands,network,ignoreViolations,enableWeakerNestedSandboxSandboxNetworkConfig:allowLocalBinding,allowUnixSockets,allowAllUnixSockets,httpProxyPort,socksProxyPortSandboxIgnoreViolations:file,networkpatternscan_use_toolintegration for unsandboxed command approval- Security warning about
bypassPermissions+allowUnsandboxedCommandscombination
Why it matters: Sandboxing is the primary safety mechanism for agents running shell commands autonomously. Users building CI/CD agents or deployment tools need this guidance to avoid security issues.
Suggested approach:
- Add a new reference document:
references/sandbox-reference.md - Cover all three types with examples
- Add a sandbox pattern to patterns-guide.md (e.g., "Sandboxed CI Agent")
- Add sandbox considerations to the SKILL.md Phase 5 (Hooks and Permissions) section
- Include security warnings about dangerous combinations
Notes and status: ready
Description: The official docs explain that when setting_sources is omitted or None, the SDK does NOT load any filesystem settings — no ~/.claude/settings.json, no .claude/settings.json, no .claude/settings.local.json, and critically no CLAUDE.md files. This is a deliberate isolation default. To load CLAUDE.md project instructions, users must set setting_sources=["project"].
The skill's api-reference.md mentions setting_sources and shows examples, but SKILL.md's workflow doesn't guide users through this decision. A user creating a "project-aware" agent would miss this and wonder why CLAUDE.md isn't being loaded.
Why it matters: Many agents need project context from CLAUDE.md. Without explicit guidance, users will create agents that silently ignore project instructions.
Suggested approach:
- Add a note in SKILL.md Phase 4 (Build the Agent) explaining the
setting_sourcesdefault behavior - In the project-aware pattern (patterns-guide.md Pattern 7), ensure
setting_sources=["project"]is prominently shown - Add to the validation checklist: "If the agent should follow CLAUDE.md, verify
setting_sourcesincludes'project'"
Notes and status: ready
Description: The ClaudeSDKClient has a rewind_files(user_message_uuid) method that restores files to their state at a given point, and ClaudeAgentOptions has enable_file_checkpointing: bool. The api-reference.md mentions both but provides no usage example anywhere in the skill.
Why it matters: File checkpointing enables powerful "try and rollback" workflows — attempt a refactor, check if tests pass, rewind if they don't. This is a differentiating feature of the SDK vs plain CLI usage.
Suggested approach:
- Add a new example:
examples/checkpoint-agent.mdshowing a try/rewind/retry pattern - Or add a new pattern to patterns-guide.md: "Iterative Agent with File Checkpointing"
- Ensure the example shows:
enable_file_checkpointing=Truein options, capturinguser_message_uuidfrom messages, callingclient.rewind_files(uuid)on failure
Notes and status: ready
Description: The SDK supports loading local plugins programmatically via plugins=[{"type": "local", "path": "./my-plugin"}] in ClaudeAgentOptions. This allows SDK applications to leverage the same plugin ecosystem as the interactive CLI. The skill mentions this in a one-liner but doesn't explain what it does, when to use it, or what "local" means.
Why it matters: Plugin loading enables SDK apps to reuse skills, hooks, agents, and commands from plugins — a key integration point between the interactive and programmatic worlds.
Suggested approach:
- Add a brief section to api-reference.md explaining
SdkPluginConfig - Add a note in patterns-guide.md about when plugin loading is useful (e.g., reusing existing hooks/skills in an SDK app)
- Consider adding to the SKILL.md quick reference if space permits
Notes and status: ready
Description: The official SDK docs explicitly warn: "When iterating over messages, avoid using break to exit early as this can cause asyncio cleanup issues. Instead, let the iteration complete naturally or use flags to track when you've found what you need."
The skill's anti-patterns section in patterns-guide.md lists "Using break to exit message loops" but doesn't explain the asyncio cleanup consequence. Several examples implicitly encourage full iteration but don't call out this footgun.
Why it matters: An agent writing message-processing code might naturally insert break to exit early when it finds what it needs. This would cause subtle asyncio errors.
Suggested approach:
- Expand the anti-pattern entry in patterns-guide.md with the asyncio cleanup explanation
- Add a brief note in SKILL.md Phase 4 message handling section
- Show the flag-based alternative pattern explicitly
Notes and status: ready
Description: All other skills in the claude plugin follow a consistent 6-phase workflow: Requirements -> Context Detection -> Research -> Structure -> Content -> Validation. The agents-sdk-creator uses 7 phases with different names: Requirements -> Project Setup -> Research -> Build -> Hooks/Permissions -> Subagents -> Validation.
The divergence is partially justified — this skill creates Python applications rather than Claude Code config files, so "Context Detection" and "Structure Creation" don't map cleanly. However, the inconsistency may confuse agents that have learned the shared workflow pattern from other skills.
Why it matters: Consistency across skills reduces cognitive load for agents and users. When all skills follow the same structure, an agent familiar with one skill can navigate others predictably.
Suggested approach: This is a judgment call. Two options:
- Option A (Adapt): Rename phases to align closer to siblings: Phase 1 (Requirements), Phase 2 (Context Detection — existing project? dependencies?), Phase 3 (Research), Phase 4 (Structure — create project files/dirs), Phase 5 (Content — write the agent code with hooks, permissions, subagents, tools), Phase 6 (Validation). This collapses Phases 4-6 into a single "Content" phase with subsections.
- Option B (Keep): Keep the 7-phase structure but add a note explaining why this skill diverges. The current breakdown is logical for the task at hand.
Recommend Option A for consistency, but either approach is valid.
Notes and status: ready
Description: The validate-agent-script.sh script currently validates imports, async patterns, API usage, and message handling. It should be updated to catch the issues identified in this review:
- Warn when hooks or custom tools are used with
query()(they requireClaudeSDKClient) - Suggest
anyio.runoverasyncio.run - Check for
breakstatements inside message iteration loops - Verify
setting_sourcesis set whensystem_promptuses the claude_code preset
Why it matters: The validation script is the last line of defense before an agent delivers code to the user. Catching these issues automatically prevents silent failures.
Suggested approach:
- Add a check: if file contains
query(AND containshooks=orcreate_sdk_mcp_server, emit a warning - Add a check: if file uses
asyncio.run, suggestanyio.runas the preferred alternative - Add a check: if file contains
breakinside anasync for messageblock, warn about asyncio cleanup - Add a check: if file contains
system_prompt.*preset.*claude_codebut nosetting_sources, suggest adding it
Notes and status: ready
Description: ClaudeAgentOptions has a stderr: Callable[[str], None] | None field that provides a callback for capturing stderr output from the CLI process. The deprecated debug_stderr field is also present. Neither is explained or demonstrated in the skill.
Why it matters: Debugging SDK applications often requires inspecting stderr output. The callback pattern is the modern replacement for debug_stderr.
Suggested approach:
- Add a brief entry in api-reference.md explaining
stderrcallback - Show a simple example:
stderr=lambda line: print(f"[DEBUG] {line}") - Note that
debug_stderris deprecated
Notes and status: ready
- Graded examples (minimal -> standard -> complete -> multi-turn) are excellent for progressive learning
- Context detection script prevents creation in read-only cache directories
- Validation script catches the most common errors (wrong package, missing async, deprecated API)
- Quick reference tables in SKILL.md provide fast lookup during coding
- Anti-patterns section in patterns-guide.md proactively prevents common mistakes
- uv shebang pattern follows project conventions from CLAUDE.md
The skill already incorporates several patterns from sibling skills:
- Progressive disclosure with SKILL.md -> references/ -> examples/
- Frontmatter with
name,description,argument-hint - Validation scripts in
scripts/directory - Context detection for existing projects
- Imperative writing style
| Topic | Official Docs | Skill Coverage | Gap |
|---|---|---|---|
query() basic usage |
Yes | Yes | None |
ClaudeSDKClient |
Yes | Yes | Capability table wrong |
Custom tools (@tool) |
Yes | Yes | Uses wrong API (query()) |
| Hooks | Yes | Yes | Uses wrong API (query()) |
| Permissions | Yes | Yes | Good coverage |
| Subagents | Yes | Yes | Good coverage |
| Structured output | Yes | Yes | Good coverage |
| Sessions | Yes | Yes | Good coverage |
| Sandbox | Yes | Minimal | Needs full reference |
| Plugin loading | Yes | One-liner | Needs explanation |
| File checkpointing | Yes | API listing only | Needs example |
setting_sources |
Yes | Reference only | Needs workflow guidance |
| Tool I/O schemas | Yes | Not covered | Low priority |
| StreamEvent type | Yes | Minimal | Low priority |
| # | Item | Severity | Effort |
|---|---|---|---|
| 1 | Fix query() vs ClaudeSDKClient capabilities | CRITICAL | High (7+ files) |
| 2 | Add anyio guidance | HIGH | Medium (examples + SKILL.md) |
| 3 | Document sandbox settings | MEDIUM | Medium (new reference) |
| 4 | Document setting_sources defaults | MEDIUM | Low (notes in 3 files) |
| 5 | Add file checkpointing example | MEDIUM | Low (1 new file) |
| 6 | Document SdkPluginConfig | LOW-MEDIUM | Low (brief additions) |
| 7 | Add break-in-loops warning | LOW-MEDIUM | Low (expand existing) |
| 8 | Align workflow phases | LOW | Medium (restructure) |
| 9 | Update validation script | LOW | Medium (4 new checks) |
| 10 | Add stderr callback docs | LOW | Low (brief addition) |