Summary

Anthropic์˜ Claude Code SDK๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ Claude์˜ ์ฝ”๋”ฉ ๋Šฅ๋ ฅ์„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด SDK๋Š” ๋ช…๋ น์ค„, TypeScript, Python์„ ํ†ตํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, Claude Code๋ฅผ ์„œ๋ธŒ ํ”„๋กœ์„ธ์Šค๋กœ ์‹คํ–‰ํ•˜์—ฌ AI ๊ธฐ๋ฐ˜ ์ฝ”๋”ฉ ๋„์šฐ๋ฏธ๋ฅผ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. API ํ‚ค ์ธ์ฆ, ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•, ๋‹ค์ค‘ ํ„ด ๋Œ€ํ™”, ์‚ฌ์šฉ์ž ์ •์˜ ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ, MCP ๊ตฌ์„ฑ, CLI ์˜ต์…˜, ์ถœ๋ ฅ ํ˜•์‹ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฉฐ, ์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ†ตํ•ฉ ๋ฐ ๊ด€๋ จ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์ •๋ณด๋„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

Claude Code SDK๋ฅผ ํ†ตํ•ด Claude Code๋ฅผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ํ”„๋กœ๊ทธ๋žจ ๋ฐฉ์‹์œผ๋กœ ํ†ตํ•ฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

Claude Code SDK๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ Claude Code๋ฅผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ํ”„๋กœ๊ทธ๋žจ ๋ฐฉ์‹์œผ๋กœ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด SDK๋Š” Claude Code๋ฅผ ์„œ๋ธŒ ํ”„๋กœ์„ธ์Šค๋กœ ์‹คํ–‰ํ•˜์—ฌ Claude์˜ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜๋Š” AI ๊ธฐ๋ฐ˜ ์ฝ”๋”ฉ ๋„์šฐ๋ฏธ ๋ฐ ๋„๊ตฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ด SDK๋Š” ๋ช…๋ น์ค„, TypeScript, Python์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ธ์ฆ

Claude Code SDK๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ „์šฉ API ํ‚ค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

  • Anthropic Console์—์„œ Anthropic API ํ‚ค๋ฅผ ์ƒ์„ฑํ•˜์‹ญ์‹œ์˜ค.
  • ๊ทธ๋Ÿฐ ๋‹ค์Œ, ANTHROPIC_API_KEY ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜์‹ญ์‹œ์˜ค. ์ด ํ‚ค๋Š” ์•ˆ์ „ํ•˜๊ฒŒ ์ €์žฅํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: GitHub ์‹œํฌ๋ฆฟ ์‚ฌ์šฉ).

SDK ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

Claude Code SDK๋ฅผ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ Claude Code๋ฅผ ๋น„๋Œ€ํ™”ํ˜• ๋ชจ๋“œ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ช…๋ น์ค„

๋‹ค์Œ์€ ๋ช…๋ น์ค„ SDK์˜ ๋ช‡ ๊ฐ€์ง€ ๊ธฐ๋ณธ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

# ๋‹จ์ผ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค (์ธ์‡„ ๋ชจ๋“œ).
$ claude -p "ํ”ผ๋ณด๋‚˜์น˜ ์ˆซ์ž๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜์‹ญ์‹œ์˜ค."
# ํŒŒ์ดํ”„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ‘œ์ค€ ์ž…๋ ฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
$ echo "์ด ์ฝ”๋“œ๋ฅผ ์„ค๋ช…ํ•˜์‹ญ์‹œ์˜ค." | claude -p
# ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ JSON ํ˜•์‹์œผ๋กœ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
$ claude -p "Hello World ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜์‹ญ์‹œ์˜ค." --output-format json
# JSON ์ถœ๋ ฅ์ด ๋„์ฐฉํ•˜๋Š” ๋Œ€๋กœ ์ŠคํŠธ๋ฆฌ๋ฐํ•ฉ๋‹ˆ๋‹ค.
$ claude -p "React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋นŒ๋“œํ•˜์‹ญ์‹œ์˜ค." --output-format stream-json

TypeScript

TypeScript SDK๋Š” NPM์˜ ์ฃผ์š” @anthropic-ai/claude-code ํŒจํ‚ค์ง€์— ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

import { query, type SDKMessage } from "@anthropic-ai/claude-code";
 
const messages: SDKMessage[] = [];
 
for await (const message of query({
  prompt: "foo.py์— ๋Œ€ํ•œ ํ•˜์ด์ฟ ๋ฅผ ์ž‘์„ฑํ•˜์‹ญ์‹œ์˜ค.",
  abortController: new AbortController(),
  options: {
    maxTurns: 3,
  },
})) {
  messages.push(message);
}
 
console.log(messages);

TypeScript SDK๋Š” ๋ช…๋ น์ค„ SDK์—์„œ ์ง€์›ํ•˜๋Š” ๋ชจ๋“  ์ธ์ˆ˜๋ฅผ ํ—ˆ์šฉํ•˜๋ฉฐ, ๋‹ค์Œ๋„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

  • abortController: Abort ์ปจํŠธ๋กค๋Ÿฌ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ new AbortController()์ž…๋‹ˆ๋‹ค.
  • cwd: ํ˜„์žฌ ์ž‘์—… ๋””๋ ‰ํ„ฐ๋ฆฌ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ process.cwd()์ž…๋‹ˆ๋‹ค.
  • executable: ์‚ฌ์šฉํ•  JavaScript ๋Ÿฐํƒ€์ž„์ž…๋‹ˆ๋‹ค. Node.js์—์„œ ์‹คํ–‰ ์‹œ node, Bun์—์„œ ์‹คํ–‰ ์‹œ bun์ž…๋‹ˆ๋‹ค.
  • executableArgs: ์‹คํ–‰ ํŒŒ์ผ์— ์ „๋‹ฌํ•  ์ธ์ˆ˜์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ []์ž…๋‹ˆ๋‹ค.
  • pathToClaudeCodeExecutable: Claude Code ์‹คํ–‰ ํŒŒ์ผ์˜ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ @anthropic-ai/claude-code์™€ ํ•จ๊ป˜ ์ œ๊ณต๋˜๋Š” ์‹คํ–‰ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.

Python

Python SDK๋Š” PyPI์—์„œ claude-code-sdk๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

pip install claude-code-sdk

์‚ฌ์ „ ์š”๊ตฌ ์‚ฌํ•ญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • Python 3.10 ์ด์ƒ
  • Node.js
  • Claude Code CLI: npm install -g @anthropic-ai/claude-code

๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

import anyio
from claude_code_sdk import query, ClaudeCodeOptions, Message
 
async def main():
    messages: list[Message] = []
 
    async for message in query(
        prompt="foo.py์— ๋Œ€ํ•œ ํ•˜์ด์ฟ ๋ฅผ ์ž‘์„ฑํ•˜์‹ญ์‹œ์˜ค.",
        options=ClaudeCodeOptions(max_turns=3)
    ):
        messages.append(message)
 
    print(messages)
 
anyio.run(main)

Python SDK๋Š” ClaudeCodeOptions ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ๋ช…๋ น์ค„ SDK์—์„œ ์ง€์›ํ•˜๋Š” ๋ชจ๋“  ์ธ์ˆ˜๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

from claude_code_sdk import query, ClaudeCodeOptions
from pathlib import Path
 
options = ClaudeCodeOptions(
    max_turns=3,
    system_prompt="๋‹น์‹ ์€ ์œ ์šฉํ•œ ๋น„์„œ์ž…๋‹ˆ๋‹ค.",
    cwd=Path("/path/to/project"),  # ๋ฌธ์ž์—ด ๋˜๋Š” Path์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    allowed_tools=["Read", "Write", "Bash"],
    permission_mode="acceptEdits"
)
 
async for message in query(prompt="์•ˆ๋…•ํ•˜์„ธ์š”", options=options):
    print(message)

๊ณ ๊ธ‰ ์‚ฌ์šฉ๋ฒ•

์•„๋ž˜ ๋ฌธ์„œ๋Š” ๋ช…๋ น์ค„ SDK๋ฅผ ์˜ˆ์‹œ๋กœ ์‚ฌ์šฉํ•˜์ง€๋งŒ, TypeScript ๋ฐ Python SDK์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์ค‘ ํ„ด ๋Œ€ํ™”

๋‹ค์ค‘ ํ„ด ๋Œ€ํ™”์˜ ๊ฒฝ์šฐ, ๋Œ€ํ™”๋ฅผ ์žฌ๊ฐœํ•˜๊ฑฐ๋‚˜ ๊ฐ€์žฅ ์ตœ๊ทผ ์„ธ์…˜์—์„œ ๊ณ„์†ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# ๊ฐ€์žฅ ์ตœ๊ทผ ๋Œ€ํ™”๋ฅผ ๊ณ„์†ํ•ฉ๋‹ˆ๋‹ค.
$ claude --continue
 
# ๊ณ„์†ํ•˜๊ณ  ์ƒˆ๋กœ์šด ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
$ claude --continue "์ด์ œ ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ์œ„ํ•ด ์ด๊ฒƒ์„ ๋ฆฌํŒฉํ„ฐ๋งํ•˜์‹ญ์‹œ์˜ค."
# ์„ธ์…˜ ID๋กœ ํŠน์ • ๋Œ€ํ™”๋ฅผ ์žฌ๊ฐœํ•ฉ๋‹ˆ๋‹ค.
$ claude --resume 550e8400-e29b-41d4-a716-446655440000
 
# ์ธ์‡„ ๋ชจ๋“œ(๋น„๋Œ€ํ™”ํ˜•)๋กœ ์žฌ๊ฐœํ•ฉ๋‹ˆ๋‹ค.
$ claude -p --resume 550e8400-e29b-41d4-a716-446655440000 "ํ…Œ์ŠคํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์‹ญ์‹œ์˜ค."
# ์ธ์‡„ ๋ชจ๋“œ(๋น„๋Œ€ํ™”ํ˜•)๋กœ ๊ณ„์†ํ•ฉ๋‹ˆ๋‹ค.
$ claude -p --continue "์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค."

์‚ฌ์šฉ์ž ์ •์˜ ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ

Claude์˜ ๋™์ž‘์„ ์•ˆ๋‚ดํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ์ž ์ •์˜ ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์žฌ์ •์˜ํ•ฉ๋‹ˆ๋‹ค (--print์—์„œ๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค).
$ claude -p "REST API๋ฅผ ๋นŒ๋“œํ•˜์‹ญ์‹œ์˜ค." --system-prompt "๋‹น์‹ ์€ ์„ ์ž„ ๋ฐฑ์—”๋“œ ์—”์ง€๋‹ˆ์–ด์ž…๋‹ˆ๋‹ค. ๋ณด์•ˆ, ์„ฑ๋Šฅ ๋ฐ ์œ ์ง€๋ณด์ˆ˜์„ฑ์— ์ค‘์ ์„ ๋‘์‹ญ์‹œ์˜ค."
# ํŠน์ • ์š”๊ตฌ์‚ฌํ•ญ์ด ์žˆ๋Š” ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ์ž…๋‹ˆ๋‹ค.
$ claude -p "๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ๋ฅผ ์ƒ์„ฑํ•˜์‹ญ์‹œ์˜ค." --system-prompt "๋‹น์‹ ์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์•„ํ‚คํ…ํŠธ์ž…๋‹ˆ๋‹ค. PostgreSQL ๋ชจ๋ฒ” ์‚ฌ๋ก€๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ ์ ˆํ•œ ์ธ๋ฑ์‹ฑ์„ ํฌํ•จํ•˜์‹ญ์‹œ์˜ค."

๊ธฐ๋ณธ ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ์— ์ง€์นจ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

# ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค (--print์—์„œ๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค).
$ claude -p "REST API๋ฅผ ๋นŒ๋“œํ•˜์‹ญ์‹œ์˜ค." --append-system-prompt "์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ ํ›„์—๋Š” ๋ฐ˜๋“œ์‹œ ์ง์ ‘ ์ฝ”๋“œ ๊ฒ€ํ† ๋ฅผ ํ•˜์‹ญ์‹œ์˜ค."

MCP ๊ตฌ์„ฑ

๋ชจ๋ธ ์ปจํ…์ŠคํŠธ ํ”„๋กœํ† ์ฝœ(MCP)์„ ์‚ฌ์šฉํ•˜๋ฉด ์™ธ๋ถ€ ์„œ๋ฒ„์˜ ์ถ”๊ฐ€ ๋„๊ตฌ ๋ฐ ๋ฆฌ์†Œ์Šค๋กœ Claude Code๋ฅผ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. --mcp-config ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์•ก์„ธ์Šค, API ํ†ตํ•ฉ ๋˜๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ๋„๊ตฌ์™€ ๊ฐ™์€ ํŠน์ˆ˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” MCP ์„œ๋ฒ„๋ฅผ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

MCP ์„œ๋ฒ„๊ฐ€ ํฌํ•จ๋œ JSON ๊ตฌ์„ฑ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์‹ญ์‹œ์˜ค.

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/path/to/allowed/files"
      ]
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "your-github-token"
      }
    }
  }
}

๊ทธ๋Ÿฐ ๋‹ค์Œ Claude Code์—์„œ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

# ๊ตฌ์„ฑ์—์„œ MCP ์„œ๋ฒ„๋ฅผ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.
$ claude -p "ํ”„๋กœ์ ํŠธ์˜ ๋ชจ๋“  ํŒŒ์ผ์„ ๋‚˜์—ดํ•˜์‹ญ์‹œ์˜ค." --mcp-config mcp-servers.json
# ์ค‘์š”: MCP ๋„๊ตฌ๋Š” --allowedTools๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ช…์‹œ์ ์œผ๋กœ ํ—ˆ์šฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
# MCP ๋„๊ตฌ๋Š” mcp__$serverName__$toolName ํ˜•์‹์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.
$ claude -p "TODO ์ฃผ์„์„ ๊ฒ€์ƒ‰ํ•˜์‹ญ์‹œ์˜ค." \
  --mcp-config mcp-servers.json \
  --allowedTools "mcp__filesystem__read_file,mcp__filesystem__list_directory"
 
# ๋น„๋Œ€ํ™”ํ˜• ๋ชจ๋“œ์—์„œ ๊ถŒํ•œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด MCP ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
$ claude -p "์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•˜์‹ญ์‹œ์˜ค." \
  --mcp-config mcp-servers.json \
  --allowedTools "mcp__permissions__approve" \
  --permission-prompt-tool mcp__permissions__approve

Info

MCP ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” --allowedTools ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ช…์‹œ์ ์œผ๋กœ ํ—ˆ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. MCP ๋„๊ตฌ ์ด๋ฆ„์€ mcp__<serverName>__<toolName> ํŒจํ„ด์„ ๋”ฐ๋ฅด๋ฉฐ, ์—ฌ๊ธฐ์„œ serverName์€ MCP ๊ตฌ์„ฑ ํŒŒ์ผ์˜ ํ‚ค์ด๊ณ  toolName์€ ํ•ด๋‹น ์„œ๋ฒ„์—์„œ ์ œ๊ณตํ•˜๋Š” ํŠน์ • ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

์ด ๋ณด์•ˆ ์กฐ์น˜๋Š” MCP ๋„๊ตฌ๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ํ—ˆ์šฉ๋  ๋•Œ๋งŒ ์‚ฌ์šฉ๋˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

์„œ๋ฒ„ ์ด๋ฆ„๋งŒ ์ง€์ •ํ•˜๋Š” ๊ฒฝ์šฐ(์˜ˆ: mcp__<serverName>), ํ•ด๋‹น ์„œ๋ฒ„์˜ ๋ชจ๋“  ๋„๊ตฌ๊ฐ€ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ „์—ญ ํŒจํ„ด(์˜ˆ: mcp__go*)์€ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ์ •์˜ ๊ถŒํ•œ ํ”„๋กฌํ”„ํŠธ ๋„๊ตฌ

์„ ํƒ์ ์œผ๋กœ --permission-prompt-tool์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ๋„๊ตฌ๋ฅผ ํ˜ธ์ถœํ•  ๊ถŒํ•œ์„ ๋ชจ๋ธ์— ๋ถ€์—ฌํ•˜๋Š”์ง€ ํ™•์ธํ•  ๋•Œ ์‚ฌ์šฉํ•  MCP ๋„๊ตฌ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋ธ์ด ๋„๊ตฌ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋‹ค์Œ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  1. ๋จผ์ € ๊ถŒํ•œ ์„ค์ •์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  settings.json ํŒŒ์ผ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ SDK์— ์ „๋‹ฌ๋œ --allowedTools ๋ฐ --disallowedTools๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ด ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋„๊ตฌ ํ˜ธ์ถœ์„ ํ—ˆ์šฉํ•˜๊ฑฐ๋‚˜ ๊ฑฐ๋ถ€ํ•˜๋ฉด ๋„๊ตฌ ํ˜ธ์ถœ์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด --permission-prompt-tool์— ์ œ๊ณตํ•œ MCP ๋„๊ตฌ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

--permission-prompt-tool MCP ๋„๊ตฌ๋Š” ๋„๊ตฌ ์ด๋ฆ„๊ณผ ์ž…๋ ฅ์„ ์ „๋‹ฌ๋ฐ›์œผ๋ฉฐ, ๊ฒฐ๊ณผ์™€ ํ•จ๊ป˜ JSON ๋ฌธ์ž์—ดํ™”๋œ ํŽ˜์ด๋กœ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํŽ˜์ด๋กœ๋“œ๋Š” ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

// ๋„๊ตฌ ํ˜ธ์ถœ์ด ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค.
{
  "behavior": "allow",
  "updatedInput": {...}, // ์—…๋ฐ์ดํŠธ๋œ ์ž…๋ ฅ ๋˜๋Š” ์›๋ณธ ์ž…๋ ฅ ๋ฐ˜ํ™˜
}
 
// ๋„๊ตฌ ํ˜ธ์ถœ์ด ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค.
{
  "behavior": "deny",
  "message": "..." // ๊ถŒํ•œ์ด ๊ฑฐ๋ถ€๋œ ์ด์œ ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ž์—ด
}

์˜ˆ๋ฅผ ๋“ค์–ด, TypeScript MCP ๊ถŒํ•œ ํ”„๋กฌํ”„ํŠธ ๋„๊ตฌ ๊ตฌํ˜„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const server = new McpServer({
  name: "Test permission prompt MCP Server",
  version: "0.0.1",
});
 
server.tool(
  "approval_prompt",
  '๊ถŒํ•œ ํ™•์ธ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค - ์ž…๋ ฅ์— "allow"๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉด ์Šน์ธํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค.',
  {
    tool_name: z.string().describe("๊ถŒํ•œ์„ ์š”์ฒญํ•˜๋Š” ๋„๊ตฌ"),
    input: z.object({}).passthrough().describe("๋„๊ตฌ์— ๋Œ€ํ•œ ์ž…๋ ฅ"),
  },
  async ({ tool_name, input }) => {
    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(
            JSON.stringify(input).includes("allow")
              ? {
                  behavior: "allow",
                  updatedInput: input,
                }
              : {
                  behavior: "deny",
                  message: "ํ…Œ์ŠคํŠธ ์Šน์ธ ํ”„๋กฌํ”„ํŠธ ๋„๊ตฌ์— ์˜ํ•ด ๊ถŒํ•œ์ด ๊ฑฐ๋ถ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.",
                }
          ),
        },
      ],
    };
  }
);

์ด ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด MCP ์„œ๋ฒ„๋ฅผ ์ถ”๊ฐ€ํ•œ ๋‹ค์Œ(์˜ˆ: --mcp-config ์‚ฌ์šฉ) ๋‹ค์Œ๊ณผ ๊ฐ™์ด SDK๋ฅผ ํ˜ธ์ถœํ•˜์‹ญ์‹œ์˜ค.

claude -p "..." \
  --permission-prompt-tool mcp__test-server__approval_prompt \
  --mcp-config my-config.json

์‚ฌ์šฉ๋ฒ• ์ฐธ๊ณ  ์‚ฌํ•ญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • updatedInput์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ถŒํ•œ ํ”„๋กฌํ”„ํŠธ๊ฐ€ ์ž…๋ ฅ์„ ๋ณ€๊ฒฝํ–ˆ์Œ์„ ๋ชจ๋ธ์— ์•Œ๋ฆฌ์‹ญ์‹œ์˜ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์œ„์˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ updatedInput์„ ์›๋ณธ ์ž…๋ ฅ์œผ๋กœ ์„ค์ •ํ•˜์‹ญ์‹œ์˜ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋„๊ตฌ๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ํŒŒ์ผ ํŽธ์ง‘ ์ฐจ์ด๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ์ˆ˜๋™์œผ๋กœ ์ฐจ์ด๋ฅผ ํŽธ์ง‘ํ•˜๋„๋ก ํ—ˆ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ๊ถŒํ•œ ํ”„๋กฌํ”„ํŠธ ๋„๊ตฌ๋Š” ํ•ด๋‹น ์—…๋ฐ์ดํŠธ๋œ ํŽธ์ง‘์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ํŽ˜์ด๋กœ๋“œ๋Š” JSON์œผ๋กœ ๋ฌธ์ž์—ดํ™”๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ CLI ์˜ต์…˜

SDK๋Š” Claude Code์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  CLI ์˜ต์…˜์„ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ SDK ์‚ฌ์šฉ์„ ์œ„ํ•œ ์ฃผ์š” ์˜ต์…˜์ž…๋‹ˆ๋‹ค.

  • --print, -p: ๋น„๋Œ€ํ™”ํ˜• ๋ชจ๋“œ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ: claude -p "query"
  • --output-format: ์ถœ๋ ฅ ํ˜•์‹์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค (text, json, stream-json). ์˜ˆ์‹œ: claude -p --output-format json
  • --resume, -r: ์„ธ์…˜ ID๋กœ ๋Œ€ํ™”๋ฅผ ์žฌ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ: claude --resume abc123
  • --continue, -c: ๊ฐ€์žฅ ์ตœ๊ทผ ๋Œ€ํ™”๋ฅผ ๊ณ„์†ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ: claude --continue
  • --verbose: ์ƒ์„ธ ๋กœ๊น…์„ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ: claude --verbose
  • --max-turns: ๋น„๋Œ€ํ™”ํ˜• ๋ชจ๋“œ์—์„œ ์—์ด์ „ํŠธ ํ„ด์„ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ: claude --max-turns 3
  • --system-prompt: ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์žฌ์ •์˜ํ•ฉ๋‹ˆ๋‹ค (--print์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ). ์˜ˆ์‹œ: claude --system-prompt "์‚ฌ์šฉ์ž ์ •์˜ ์ง€์นจ"
  • --append-system-prompt: ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค (--print์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ). ์˜ˆ์‹œ: claude --append-system-prompt "์‚ฌ์šฉ์ž ์ •์˜ ์ง€์นจ"
  • --allowedTools: ํ—ˆ์šฉ๋œ ๋„๊ตฌ์˜ ๊ณต๋ฐฑ์œผ๋กœ ๊ตฌ๋ถ„๋œ ๋ชฉ๋ก ๋˜๋Š” ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„๋œ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค. ์˜ˆ์‹œ: claude --allowedTools mcp__slack mcp__filesystem, claude --allowedTools "Bash(npm install),mcp__filesystem"
  • --disallowedTools: ๊ฑฐ๋ถ€๋œ ๋„๊ตฌ์˜ ๊ณต๋ฐฑ์œผ๋กœ ๊ตฌ๋ถ„๋œ ๋ชฉ๋ก ๋˜๋Š” ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„๋œ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค. ์˜ˆ์‹œ: claude --disallowedTools mcp__splunk mcp__github, claude --disallowedTools "Bash(git commit),mcp__github"
  • --mcp-config: JSON ํŒŒ์ผ์—์„œ MCP ์„œ๋ฒ„๋ฅผ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ: claude --mcp-config servers.json
  • --permission-prompt-tool: ๊ถŒํ•œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ MCP ๋„๊ตฌ์ž…๋‹ˆ๋‹ค (--print์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ). ์˜ˆ์‹œ: claude --permission-prompt-tool mcp__auth__prompt

CLI ์˜ต์…˜ ๋ฐ ๊ธฐ๋Šฅ์˜ ์ „์ฒด ๋ชฉ๋ก์€ CLI ์‚ฌ์šฉ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ถœ๋ ฅ ํ˜•์‹

SDK๋Š” ์—ฌ๋Ÿฌ ์ถœ๋ ฅ ํ˜•์‹์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

ํ…์ŠคํŠธ ์ถœ๋ ฅ (๊ธฐ๋ณธ๊ฐ’)

์‘๋‹ต ํ…์ŠคํŠธ๋งŒ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ claude -p "src/components/Header.tsx ํŒŒ์ผ์„ ์„ค๋ช…ํ•˜์‹ญ์‹œ์˜ค."
# ์ถœ๋ ฅ: ์ด๊ฒƒ์€ React ์ปดํฌ๋„ŒํŠธ์ด๋ฉฐ...

JSON ์ถœ๋ ฅ

๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•œ ๊ตฌ์กฐํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

$ claude -p "๋ฐ์ดํ„ฐ ๊ณ„์ธต์€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?" --output-format json

์‘๋‹ต ํ˜•์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

{
  "type": "result",
  "subtype": "success",
  "total_cost_usd": 0.003,
  "is_error": false,
  "duration_ms": 1234,
  "duration_api_ms": 800,
  "num_turns": 6,
  "result": "์—ฌ๊ธฐ์— ์‘๋‹ต ํ…์ŠคํŠธ...",
  "session_id": "abc123"
}

์ŠคํŠธ๋ฆฌ๋ฐ JSON ์ถœ๋ ฅ

๊ฐ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•˜๋Š” ์ฆ‰์‹œ ์ŠคํŠธ๋ฆฌ๋ฐํ•ฉ๋‹ˆ๋‹ค.

CLI ๋ช…๋ น ์˜ˆ์‹œ

$ claude -p "Build an application" --output-format stream-json

๊ฐ ๋Œ€ํ™”๋Š” ์ดˆ๊ธฐ init ์‹œ์Šคํ…œ ๋ฉ”์‹œ์ง€๋กœ ์‹œ์ž‘ํ•˜๋ฉฐ, ์ด์–ด์„œ ์‚ฌ์šฉ์ž ๋ฐ ์–ด์‹œ์Šคํ„ดํŠธ ๋ฉ”์‹œ์ง€ ๋ชฉ๋ก์ด ์˜ค๊ณ , ๋งˆ์ง€๋ง‰์œผ๋กœ ํ†ต๊ณ„๊ฐ€ ํฌํ•จ๋œ ์ตœ์ข… result ์‹œ์Šคํ…œ ๋ฉ”์‹œ์ง€๋กœ ๋งˆ๋ฌด๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ๊ฐ ๋ฉ”์‹œ์ง€๋Š” ๋ณ„๋„์˜ JSON ๊ฐ์ฒด๋กœ ๋ฐฉ์ถœ๋ฉ๋‹ˆ๋‹ค.

๋ฉ”์‹œ์ง€ ์Šคํ‚ค๋งˆ

JSON API์—์„œ ๋ฐ˜ํ™˜๋˜๋Š” ๋ฉ”์‹œ์ง€๋Š” ๋‹ค์Œ ์Šคํ‚ค๋งˆ์— ๋”ฐ๋ผ ์—„๊ฒฉํ•˜๊ฒŒ ์œ ํ˜•ํ™”๋ฉ๋‹ˆ๋‹ค.

SDKMessage ํƒ€์ž… ์ •์˜

type SDKMessage =
  // An assistant message
  | {
      type: "assistant";
      message: Message; // from Anthropic SDK
      session_id: string;
    }
  // A user message
  | {
      type: "user";
      message: MessageParam; // from Anthropic SDK
      session_id: string;
    }
  // Emitted as the last message
  | {
      type: "result";
      subtype: "success";
      duration_ms: float;
      duration_api_ms: float;
      is_error: boolean;
      num_turns: int;
      result: string;
      session_id: string;
      total_cost_usd: float;
    }
  // Emitted as the last message, when we've reached the maximum number of turns
  | {
      type: "result";
      subtype: "error_max_turns" | "error_during_execution";
      duration_ms: float;
      duration_api_ms: float;
      is_error: boolean;
      num_turns: int;
      session_id: string;
      total_cost_usd: float;
    }
  // Emitted as the first message at the start of a conversation
  | {
      type: "system";
      subtype: "init";
      apiKeySource: string;
      cwd: string;
      session_id: string;
      tools: string[];
      mcp_servers: {
        name: string;
        status: string;
      }[];
      model: string;
      permissionMode: "default" | "acceptEdits" | "bypassPermissions" | "plan";
    };

์ด๋Ÿฌํ•œ ์œ ํ˜•์€ ๊ณง JSONSchema ํ˜ธํ™˜ ํ˜•์‹์œผ๋กœ ๊ฒŒ์‹œ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. Claude Code ๊ธฐ๋ณธ ํŒจํ‚ค์ง€์—๋Š” ์ด ํ˜•์‹์˜ ํŒŒ๊ดด์  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด Semantic Versioning์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Message ๋ฐ MessageParam ํƒ€์ž…

Message ๋ฐ MessageParam ํƒ€์ž…์€ Anthropic SDK์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Anthropic TypeScript ๋ฐ Python SDK๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ž…๋ ฅ ํ˜•์‹

SDK๋Š” ์—ฌ๋Ÿฌ ์ž…๋ ฅ ํ˜•์‹์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

ํ…์ŠคํŠธ ์ž…๋ ฅ (๊ธฐ๋ณธ๊ฐ’)

์ž…๋ ฅ ํ…์ŠคํŠธ๋Š” ์ธ์ˆ˜๋กœ ์ œ๊ณต๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ claude -p "Explain this code"

๋˜๋Š” ์ž…๋ ฅ ํ…์ŠคํŠธ๋Š” stdin์„ ํ†ตํ•ด ํŒŒ์ดํ”„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ echo "Explain this code" | claude -p

์ŠคํŠธ๋ฆฌ๋ฐ JSON ์ž…๋ ฅ

๊ฐ ๋ฉ”์‹œ์ง€๊ฐ€ ์‚ฌ์šฉ์ž ํ„ด์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฉ”์‹œ์ง€ ์ŠคํŠธ๋ฆผ์ด stdin์„ ํ†ตํ•ด ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด claude ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜์ง€ ์•Š๊ณ ๋„ ์—ฌ๋Ÿฌ ํ„ด์˜ ๋Œ€ํ™”๋ฅผ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ชจ๋ธ์ด ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋™์•ˆ ๋ชจ๋ธ์— ์ง€์นจ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ๋ฉ”์‹œ์ง€๋Š” ์ถœ๋ ฅ ๋ฉ”์‹œ์ง€ ์Šคํ‚ค๋งˆ์™€ ๋™์ผํ•œ ํ˜•์‹์˜ JSON โ€˜์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€โ€™ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ๋ฉ”์‹œ์ง€๋Š” ๊ฐ ์ž…๋ ฅ ๋ผ์ธ์ด ์™„์ „ํ•œ JSON ๊ฐ์ฒด์ธ jsonl ํ˜•์‹์œผ๋กœ ํฌ๋งท๋ฉ๋‹ˆ๋‹ค. ์ŠคํŠธ๋ฆฌ๋ฐ JSON ์ž…๋ ฅ์—๋Š” -p ๋ฐ --output-format stream-json์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ๋Š” ํ…์ŠคํŠธ ์ „์šฉ ์‚ฌ์šฉ์ž ๋ฉ”์‹œ์ง€๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค.

$ echo '{"type":"user","message":{"role":"user","content":[{"type":"text","text":"Explain this code"}]}}' | claude -p --output-format=stream-json --input-format=stream-json --verbose

์˜ˆ์‹œ

๊ฐ„๋‹จํ•œ ์Šคํฌ๋ฆฝํŠธ ํ†ตํ•ฉ

#!/bin/bash
# Simple function to run Claude and check exit code
run_claude() {
    local prompt="$1"
    local output_format="${2:-text}"
    if claude -p "$prompt" --output-format "$output_format"; then
        echo "Success!"
    else
        echo "Error: Claude failed with exit code $?" >&2
        return 1
    fi
}
# Usage examples
run_claude "Write a Python function to read CSV files"
run_claude "Optimize this database query" "json"

Claude๋กœ ํŒŒ์ผ ์ฒ˜๋ฆฌ

# Process a file through Claude
$ cat mycode.py | claude -p "Review this code for bugs"
# Process multiple files
$ for file in *.js; do
    echo "Processing $file..."
    claude -p "Add JSDoc comments to this file:" < "$file" > "${file}.documented"
done
# Use Claude in a pipeline
$ grep -l "TODO" *.py | while read file; do
    claude -p "Fix all TODO items in this file" < "$file"
done

์„ธ์…˜ ๊ด€๋ฆฌ

# Start a session and capture the session ID
$ claude -p "Initialize a new project" --output-format json | jq -r '.session_id' > session.txt
# Continue with the same session
$ claude -p --resume "$(cat session.txt)" "Add unit tests"

๋ชจ๋ฒ” ์‚ฌ๋ก€

  1. JSON ์ถœ๋ ฅ ํ˜•์‹ ์‚ฌ์šฉ์€ ์‘๋‹ต์„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์œผ๋กœ ํŒŒ์‹ฑํ•˜๋Š” ๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.
    # Parse JSON response with jq
    result=$(claude -p "Generate code" --output-format json)
    code=$(echo "$result" | jq -r '.result')
    cost=$(echo "$result" | jq -r '.cost_usd')
  2. ์˜ค๋ฅ˜๋ฅผ ์œ ์—ฐํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜์‹ญ์‹œ์˜ค. ์ข…๋ฃŒ ์ฝ”๋“œ์™€ stderr๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.
    if ! claude -p "$prompt" 2>error.log; then
        echo "Error occurred:" >&2
        cat error.log >&2
        exit 1
    fi
  3. ๋‹ค์ค‘ ํ„ด ๋Œ€ํ™”์—์„œ ์ปจํ…์ŠคํŠธ ์œ ์ง€๋ฅผ ์œ„ํ•ด ์„ธ์…˜ ๊ด€๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.
  4. ์žฅ๊ธฐ ์‹คํ–‰ ์ž‘์—…์— ๋Œ€ํ•ด ํƒ€์ž„์•„์›ƒ์„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค.
    timeout 300 claude -p "$complex_prompt" || echo "Timed out after 5 minutes"
  5. ์—ฌ๋Ÿฌ ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ์ง€์—ฐ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์†๋„ ์ œํ•œ์„ ์ค€์ˆ˜ํ•˜์‹ญ์‹œ์˜ค.

์‹ค์ œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ

Claude Code SDK๋Š” ๊ฐœ๋ฐœ ์›Œํฌํ”Œ๋กœ์™€ ๊ฐ•๋ ฅํ•˜๊ฒŒ ํ†ตํ•ฉ๋  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ๋ชฉํ•  ๋งŒํ•œ ์˜ˆ์‹œ ์ค‘ ํ•˜๋‚˜๋Š” SDK๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GitHub ์›Œํฌํ”Œ๋กœ ๋‚ด์—์„œ ์ž๋™ํ™”๋œ ์ฝ”๋“œ ๊ฒ€ํ† , PR ์ƒ์„ฑ ๋ฐ ์ด์Šˆ ๋ถ„๋ฅ˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” Claude Code GitHub Actions์ž…๋‹ˆ๋‹ค.

๊ด€๋ จ ๋ฆฌ์†Œ์Šค