Claude Code SDK를 사용하면 개발자가 프로그래밍 방식으로 Claude Code를 애플리케이션에 통합할 수 있습니다. 이를 통해 Claude Code를 하위 프로세스로 실행하여 Claude의 기능을 활용하는 AI 기반 코딩 어시스턴트 및 도구를 구축할 수 있습니다.

SDK는 명령줄, TypeScript 및 Python 사용을 위해 제공됩니다.

인증

Claude Code SDK를 사용하려면 전용 API 키를 생성하는 것이 좋습니다:

  1. Anthropic 콘솔에서 Anthropic API 키를 생성합니다
  2. 그런 다음 ANTHROPIC_API_KEY 환경 변수를 설정합니다. 이 키를 안전하게 저장하는 것이 좋습니다(예: Github 시크릿 사용)

기본 SDK 사용법

Claude Code SDK를 사용하면 애플리케이션에서 비대화형 모드로 Claude Code를 사용할 수 있습니다.

명령줄

다음은 명령줄 SDK의 몇 가지 기본 예시입니다:

# 단일 프롬프트를 실행하고 종료 (프린트 모드)
$ claude -p "Write a function to calculate Fibonacci numbers"

# 파이프를 사용하여 stdin 제공
$ echo "Explain this code" | claude -p

# 메타데이터가 포함된 JSON 형식으로 출력
$ claude -p "Generate a hello world function" --output-format json

# JSON 출력을 도착하는 대로 스트리밍
$ claude -p "Build a React component" --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: "Write a haiku about foo.py",
  abortController: new AbortController(),
  options: {
    maxTurns: 3,
  },
})) {
  messages.push(message);
}

console.log(messages);

TypeScript SDK는 명령줄 SDK에서 지원하는 모든 인수와 함께 다음을 허용합니다:

인수설명기본값
abortController중단 컨트롤러new AbortController()
cwd현재 작업 디렉토리process.cwd()
executable사용할 JavaScript 런타임Node.js로 실행 시 node, Bun으로 실행 시 bun
executableArgs실행 파일에 전달할 인수[]
pathToClaudeCodeExecutableClaude 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="Write a haiku about 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="You are a helpful assistant",
    cwd=Path("/path/to/project"),  # 문자열 또는 Path 가능
    allowed_tools=["Read", "Write", "Bash"],
    permission_mode="acceptEdits"
)

async for message in query(prompt="Hello", options=options):
    print(message)

고급 사용법

아래 문서는 명령줄 SDK를 예시로 사용하지만, TypeScript 및 Python SDK에서도 사용할 수 있습니다.

다중 턴 대화

다중 턴 대화의 경우, 대화를 재개하거나 가장 최근 세션에서 계속할 수 있습니다:

# 가장 최근 대화 계속하기
$ claude --continue

# 계속하고 새 프롬프트 제공하기
$ claude --continue "Now refactor this for better performance"

# 세션 ID로 특정 대화 재개하기
$ claude --resume 550e8400-e29b-41d4-a716-446655440000

# 프린트 모드에서 재개하기 (비대화형)
$ claude -p --resume 550e8400-e29b-41d4-a716-446655440000 "Update the tests"

# 프린트 모드에서 계속하기 (비대화형)
$ claude -p --continue "Add error handling"

커스텀 시스템 프롬프트

Claude의 동작을 안내하기 위해 커스텀 시스템 프롬프트를 제공할 수 있습니다:

# 시스템 프롬프트 재정의 (--print와 함께만 작동)
$ claude -p "Build a REST API" --system-prompt "You are a senior backend engineer. Focus on security, performance, and maintainability."

# 특정 요구 사항이 있는 시스템 프롬프트
$ claude -p "Create a database schema" --system-prompt "You are a database architect. Use PostgreSQL best practices and include proper indexing."

기본 시스템 프롬프트에 지시사항을 추가할 수도 있습니다:

# 시스템 프롬프트 추가 (--print와 함께만 작동)
$ claude -p "Build a REST API" --append-system-prompt "After writing code, be sure to code review yourself."

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 "List all files in the project" --mcp-config mcp-servers.json

# 중요: MCP 도구는 --allowedTools를 사용하여 명시적으로 허용되어야 합니다
# MCP 도구는 mcp__$serverName__$toolName 형식을 따릅니다
$ claude -p "Search for TODO comments" \
  --mcp-config mcp-servers.json \
  --allowedTools "mcp__filesystem__read_file,mcp__filesystem__list_directory"

# 비대화형 모드에서 권한 프롬프트를 처리하기 위한 MCP 도구 사용
$ claude -p "Deploy the application" \
  --mcp-config mcp-servers.json \
  --allowedTools "mcp__permissions__approve" \
  --permission-prompt-tool mcp__permissions__approve

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",
  'Simulate a permission check - approve if the input contains "allow", otherwise deny',
  {
    tool_name: z.string().describe("The tool requesting permission"),
    input: z.object({}).passthrough().describe("The input for the tool"),
  },
  async ({ tool_name, input }) => {
    return {
      content: [
        {
          type: "text",
          text: JSON.stringify(
            JSON.stringify(input).includes("allow")
              ? {
                  behavior: "allow",
                  updatedInput: input,
                }
              : {
                  behavior: "deny",
                  message: "Permission denied by test approval_prompt tool",
                }
          ),
        },
      ],
    };
  }
);

이 도구를 사용하려면 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 "Custom instruction"
--append-system-prompt시스템 프롬프트에 추가(--print와 함께만 사용)claude --append-system-prompt "Custom instruction"
--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-configJSON 파일에서 MCP 서버 로드claude --mcp-config servers.json
--permission-prompt-tool권한 프롬프트 처리를 위한 MCP 도구(--print와 함께만 사용)claude --permission-prompt-tool mcp__auth__prompt

CLI 옵션 및 기능의 전체 목록은 CLI 사용법 및 제어 문서를 참조하세요.

출력 형식

SDK는 여러 출력 형식을 지원합니다:

텍스트 출력(기본값)

응답 텍스트만 반환합니다:

$ claude -p "Explain file src/components/Header.tsx"
# 출력: This is a React component showing...

JSON 출력

메타데이터를 포함한 구조화된 데이터를 반환합니다:

$ claude -p "How does the data layer work?" --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": "The response text here...",
  "session_id": "abc123"
}

스트리밍 JSON 출력

각 메시지를 수신할 때마다 스트리밍합니다:

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

각 대화는 초기 init 시스템 메시지로 시작하고, 사용자 및 어시스턴트 메시지 목록이 이어지며, 통계가 포함된 최종 result 시스템 메시지로 끝납니다. 각 메시지는 별도의 JSON 객체로 출력됩니다.

메시지 스키마

JSON API에서 반환된 메시지는 다음 스키마에 따라 엄격하게 타입이 지정됩니다:

type SDKMessage =
  // 어시스턴트 메시지
  | {
      type: "assistant";
      message: Message; // Anthropic SDK에서
      session_id: string;
    }

  // 사용자 메시지
  | {
      type: "user";
      message: MessageParam; // Anthropic SDK에서
      session_id: string;
    }

  // 마지막 메시지로 출력됨
  | {
      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;
    }

  // 최대 턴 수에 도달했을 때 마지막 메시지로 출력됨
  | {
      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;
    }

  // 대화 시작 시 첫 번째 메시지로 출력됨
  | {
      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 패키지에 시맨틱 버전 관리를 사용합니다.

MessageMessageParam 타입은 Anthropic SDK에서 사용할 수 있습니다. 예를 들어, Anthropic TypeScriptPython SDK를 참조하세요.

예시

간단한 스크립트 통합

#!/bin/bash

# Claude를 실행하고 종료 코드를 확인하는 간단한 함수
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
}

# 사용 예시
run_claude "Write a Python function to read CSV files"
run_claude "Optimize this database query" "json"

Claude로 파일 처리하기

# Claude를 통해 파일 처리
$ cat mycode.py | claude -p "Review this code for bugs"

# 여러 파일 처리
$ for file in *.js; do
    echo "Processing $file..."
    claude -p "Add JSDoc comments to this file:" < "$file" > "${file}.documented"
done

# 파이프라인에서 Claude 사용
$ grep -l "TODO" *.py | while read file; do
    claude -p "Fix all TODO items in this file" < "$file"
done

세션 관리

# 세션을 시작하고 세션 ID 캡처
$ claude -p "Initialize a new project" --output-format json | jq -r '.session_id' > session.txt

# 동일한 세션 계속하기
$ claude -p --resume "$(cat session.txt)" "Add unit tests"

모범 사례

  1. 프로그래밍 방식 응답 파싱을 위해 JSON 출력 형식 사용:

    # jq로 JSON 응답 파싱
    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를 사용하면 개발 워크플로우와 강력한 통합이 가능합니다. 주목할 만한 예시로는 Claude Code GitHub Actions가 있으며, 이는 SDK를 사용하여 GitHub 워크플로우에서 직접 자동화된 코드 리뷰, PR 생성 및 이슈 분류 기능을 제공합니다.

관련 리소스