---
title: "Use Claude Code Features in the SDK"
aliases: [setting-sources, sdk-claude-md, sdk-skills-hooks]
tags: [agent-sdk, settings, skills, hooks, claude-md, configuration]
sources: [raw/Use Claude Code features in the SDK.md]
created: 2026-04-17
updated: 2026-04-17
---

# Use Claude Code Features in the SDK

SDK agents share the same filesystem-based feature layer as the Claude Code CLI: `CLAUDE.md` instructions, skills, hooks, and settings. The `settingSources` option controls which of these load.

## settingSources

Controls which filesystem locations the SDK reads at startup.

| Source | Loads from | Contents |
|--------|-----------|----------|
| `"project"` | `<cwd>/.claude/` and parent dirs | CLAUDE.md, `.claude/rules/*.md`, project skills, project hooks, `settings.json` |
| `"user"` | `~/.claude/` | User CLAUDE.md, `~/.claude/rules/*.md`, user skills, user settings |
| `"local"` | `<cwd>/` | `CLAUDE.local.md` (gitignored), `settings.local.json` |

- Omitting `settingSources` → equivalent to `["user", "project", "local"]`
- Pass `settingSources: []` to disable all three (programmatic-only mode)

```python
options=ClaudeAgentOptions(
    setting_sources=["user", "project"],
    allowed_tools=["Read", "Edit", "Bash"],
)
```

### What settingSources does NOT control

These load regardless:

| Input | To disable |
|-------|-----------|
| Managed policy settings | Remove the managed settings file |
| `~/.claude.json` global config | Relocate with `CLAUDE_CONFIG_DIR` in `env` |
| Auto memory (`~/.claude/projects/<project>/memory/`) | `autoMemoryEnabled: false` or `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1` |

**Multi-tenant isolation:** use separate filesystems per tenant + `settingSources: []` + `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1`. See [[wiki/agent-sdk/secure-deployment|secure-deployment]].

## Project Instructions (CLAUDE.md and rules)

- Loaded when `settingSources` includes `"project"`
- All levels are **additive** — project + user CLAUDE.md both load, no hard precedence
- Child-dir `CLAUDE.md` files load on demand when agent reads a file in that subtree

| Level | Location |
|-------|---------|
| Project root | `<cwd>/CLAUDE.md` or `<cwd>/.claude/CLAUDE.md` |
| Project rules | `<cwd>/.claude/rules/*.md` |
| Parent dirs | CLAUDE.md in any ancestor of `cwd` |
| Child dirs | CLAUDE.md in subdirs (loaded on demand) |
| Local (gitignored) | `<cwd>/CLAUDE.local.md` |
| User | `~/.claude/CLAUDE.md`, `~/.claude/rules/*.md` |

If instructions conflict, state precedence explicitly in the more specific file. Alternatively inject context via `systemPrompt` — see [[wiki/agent-sdk/modifying-system-prompts|modifying-system-prompts]].

## Skills

- Discovered from `.claude/skills/` via `settingSources`
- Descriptions loaded at startup; full content loads on demand
- `"Skill"` tool is enabled by default unless you use an `allowedTools` allowlist (then add it explicitly)

```python
options=ClaudeAgentOptions(
    setting_sources=["user", "project"],
    allowed_tools=["Skill", "Read", "Grep", "Glob"],
)
```

Skills are filesystem artifacts (`SKILL.md`) — no programmatic registration API. See [[wiki/agent-sdk/skills-in-sdk|skills-in-sdk]].

## Hooks

Two types run side by side:

| Type | Best for | Scope |
|------|---------|-------|
| **Filesystem** (`settings.json`) | Shared CLI + SDK hooks; supports `command`, `http`, `prompt`, `agent` types | Main agent + all subagents |
| **Programmatic** (callbacks in `query()`) | App-specific logic, structured decisions, in-process integration | Main session only |

```python
async def audit_bash(input_data, tool_use_id, context):
    if "rm -rf" in input_data.get("tool_input", {}).get("command", ""):
        return {"decision": "block", "reason": "Destructive command blocked"}
    return {}  # empty dict = allow

options=ClaudeAgentOptions(
    setting_sources=["project"],   # loads hooks from .claude/settings.json
    hooks={
        "PreToolUse": [HookMatcher(matcher="Bash", hooks=[audit_bash])]
    },
)
```

TypeScript SDK adds extra events: `SessionStart`, `SessionEnd`, `TeammateIdle`, `TaskCompleted`. See [[wiki/agent-sdk/sdk-hooks|sdk-hooks]].

## Feature Selection Guide

| Goal | Feature | SDK surface |
|------|---------|-------------|
| Project conventions always present | CLAUDE.md | `settingSources: ["project"]` |
| Reference material loaded when relevant | Skills | `settingSources` + `allowedTools: ["Skill"]` |
| Reusable workflow (deploy, review) | User-invocable skills | same as above |
| Isolated subtask, fresh context | Subagents | `agents` param + `allowedTools: ["Agent"]` |
| Coordinate multiple Claude Code instances | Agent teams (CLI feature) | not SDK-configurable |
| Deterministic logic on tool calls | Hooks | `hooks` callbacks or `settings.json` |
| External service with structured tools | MCP | `mcpServers` parameter |

**Context cost reminder:** every enabled feature adds to the context window. See the features-overview cost analysis.

## Key Takeaways

- `settingSources` selects which filesystem locations load — omit it for full parity with the CLI, pass `[]` for programmatic-only
- Three inputs always load regardless of `settingSources`: managed policy, `~/.claude.json`, auto memory
- CLAUDE.md levels are additive; write non-conflicting rules or state precedence explicitly
- Skills load descriptions at startup, full content on demand — include `"Skill"` in `allowedTools` when using an allowlist
- Filesystem hooks and programmatic hooks coexist; filesystem hooks propagate to subagents, programmatic do not
- For multi-tenant deployments: isolated filesystem + `settingSources: []` + disable auto memory

## Sources

- `raw/Use Claude Code features in the SDK.md`
