---
title: "Slash Commands in the SDK"
aliases: [sdk-slash-commands, custom-commands-sdk]
tags: [agent-sdk, slash-commands, custom-commands, typescript, claude-code]
sources: [raw/Slash Commands in the SDK.md]
created: 2026-04-17
updated: 2026-04-17
---

# Slash Commands in the SDK

Slash commands let you control Claude Code sessions programmatically via the Agent SDK. Built-in commands (`/compact`, `/context`, `/cost`) plus any custom commands you define are all sent as plain prompt strings.

Only non-interactive commands work through the SDK — the `system/init` message lists what's available in your session.

## Discovering Available Commands

Read `slash_commands` from the `system/init` message at session start:

```typescript
import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({ prompt: "Hello", options: { maxTurns: 1 } })) {
  if (message.type === "system" && message.subtype === "init") {
    console.log(message.slash_commands);
    // ["/compact", "/context", "/cost", "/your-custom-cmd"]
  }
}
```

## Sending Commands

Pass the command as the prompt string:

```typescript
for await (const message of query({ prompt: "/compact", options: { maxTurns: 1 } })) {
  if (message.type === "result") console.log("Done:", message.result);
}
```

## Built-in Commands

| Command | What it does |
|---------|-------------|
| `/compact` | Summarizes older messages to reduce context size; emits `compact_boundary` event with token counts |
| `/context` | Shows current context usage |
| `/cost` | Reports token cost for the session |
| `/clear` | **Not available** in SDK — start a new `query()` instead |

### /compact response shape

```typescript
if (message.type === "system" && message.subtype === "compact_boundary") {
  message.compact_metadata.pre_tokens  // tokens before compaction
  message.compact_metadata.trigger     // what triggered it
}
```

## Custom Slash Commands

### File Locations

| Scope | Legacy path | Preferred path |
|-------|------------|----------------|
| Project | `.claude/commands/<name>.md` | `.claude/skills/<name>/SKILL.md` |
| Personal (all projects) | `~/.claude/commands/<name>.md` | `~/.claude/skills/<name>/SKILL.md` |

The preferred format is Skills — same `/name` invocation but also supports autonomous invocation by Claude. See [[wiki/agent-sdk/skills-in-sdk|skills-in-sdk]] for the current format.

### Frontmatter Options

```markdown
---
allowed-tools: Read, Grep, Glob, Bash(git diff *)
description: One-line description shown in /help
argument-hint: [arg1] [arg2]
model: claude-opus-4-6
---
```

### Arguments / Placeholders

Use `$1`, `$2`, … or `$ARGUMENTS` in the command body:

```markdown
---
argument-hint: [issue-number] [priority]
---
Fix issue #$1 with priority $2.
```

```typescript
query({ prompt: "/fix-issue 123 high" })  // $1="123", $2="high"
```

### Dynamic Content in Commands

| Syntax | Effect |
|--------|--------|
| `` !`git status` `` | Runs bash command, inlines output |
| `@package.json` | Inlines file contents |

### Subdirectory Namespacing

Commands in subdirectories keep their short name but the subdirectory appears in the description:

```
.claude/commands/
├── frontend/component.md   →  /component  (project:frontend)
└── review.md               →  /review     (project)
```

## Practical Examples

**Code review command** — `.claude/commands/code-review.md`:
```markdown
---
allowed-tools: Read, Grep, Glob, Bash(git diff *)
description: Comprehensive code review
---
## Changed Files
!`git diff --name-only HEAD~1`
## Detailed Changes
!`git diff HEAD~1`
Review for: code quality, security, performance, test coverage, docs.
```

**Test runner with arguments** — `.claude/commands/test.md`:
```markdown
---
allowed-tools: Bash, Read, Edit
argument-hint: [test-pattern]
---
Run tests matching: $ARGUMENTS
Detect framework, run, fix failures, re-run to verify.
```

## Key Takeaways

- Send slash commands as plain prompt strings — no special API needed
- Check `system/init → slash_commands` to see what's available in a session
- `/clear` is unavailable; start a new `query()` to reset context
- Custom commands: `.claude/commands/<name>.md` (legacy) or `.claude/skills/<name>/SKILL.md` (preferred)
- Frontmatter controls `allowed-tools`, `description`, `argument-hint`, and `model`
- Dynamic content: `` !`bash command` `` and `@file` work inside command bodies
- Subdirectories organize commands visually but don't change the command name

## Related

- [[wiki/agent-sdk/skills-in-sdk|Skills in the SDK]] — preferred modern format replacing `.claude/commands/`
- [[wiki/agent-sdk/agent-skills-plugins|Agent Skills & Plugins]] — loading skills, agents, hooks into SDK sessions
- [[wiki/agent-sdk/agent-loop|Agent Loop]] — how turns, compaction, and sessions work
- [[wiki/agent-sdk/typescript-api-reference|TypeScript API Reference]] — full `query()` options and message types

## Sources

- `raw/Slash Commands in the SDK.md`
