Claude Code SDK는 Claude Code를 서브프로세스로 실행할 수 있게 해주며, Claude의 기능을 활용하는 AI 기반 코딩 어시스턴트와 도구를 구축하는 방법을 제공합니다.

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

인증

Claude Code SDK를 사용하려면 전용 API 키를 생성하는 것을 권장합니다:

  1. Anthropic Console에서 Anthropic API 키를 생성합니다
  2. 그런 다음 ANTHROPIC_API_KEY 환경 변수를 설정합니다. 이 키를 안전하게 저장하는 것을 권장합니다 (예: Github secret 사용)

기본 SDK 사용법

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

명령줄

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

# 단일 프롬프트를 실행하고 종료 (출력 모드)
$ claude -p "피보나치 수를 계산하는 함수를 작성하세요"

# 파이프를 사용하여 stdin 제공
$ 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중단 컨트롤러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="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 구성

Model Context Protocol (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

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: "테스트 approval_prompt 도구에 의해 권한이 거부되었습니다",
                }
          ),
        },
      ],
    };
  }
);

이 도구를 사용하려면 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 "쿼리"
--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-configJSON 파일에서 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 출력

수신되는 각 메시지를 스트리밍합니다:

$ claude -p "애플리케이션을 구축하세요" --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를 참조하세요.

입력 형식

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

텍스트 입력 (기본값)

입력 텍스트는 인수로 제공할 수 있습니다:

$ claude -p "이 코드를 설명하세요"

또는 입력 텍스트는 stdin을 통해 파이프할 수 있습니다:

$ echo "이 코드를 설명하세요" | claude -p

스트리밍 JSON 입력

각 메시지가 사용자 턴을 나타내는 stdin을 통해 제공되는 메시지 스트림입니다. 이를 통해 claude 바이너리를 다시 시작하지 않고도 대화의 여러 턴을 허용하고 요청을 처리하는 동안 모델에 안내를 제공할 수 있습니다.

각 메시지는 출력 메시지 스키마와 동일한 형식을 따르는 JSON ‘사용자 메시지’ 객체입니다. 메시지는 각 입력 줄이 완전한 JSON 객체인 jsonl 형식을 사용하여 형식화됩니다. 스트리밍 JSON 입력에는 -p--output-format stream-json이 필요합니다.

현재 이는 텍스트 전용 사용자 메시지로 제한됩니다.

$ echo '{"type":"user","message":{"role":"user","content":[{"type":"text","text":"이 코드를 설명하세요"}]}}' | claude -p --output-format=stream-json --input-format=stream-json --verbose

예제

간단한 스크립트 통합

#!/bin/bash

# Claude를 실행하고 종료 코드를 확인하는 간단한 함수
run_claude() {
    local prompt="$1"
    local output_format="${2:-text}"

    if claude -p "$prompt" --output-format "$output_format"; then
        echo "성공!"
    else
        echo "오류: Claude가 종료 코드 $?로 실패했습니다" >&2
        return 1
    fi
}

# 사용 예제
run_claude "CSV 파일을 읽는 Python 함수를 작성하세요"
run_claude "이 데이터베이스 쿼리를 최적화하세요" "json"

Claude로 파일 처리

# Claude를 통해 파일 처리
$ cat mycode.py | claude -p "이 코드에서 버그를 검토하세요"

# 여러 파일 처리
$ for file in *.js; do
    echo "$file 처리 중..."
    claude -p "이 파일에 JSDoc 주석을 추가하세요:" < "$file" > "${file}.documented"
done

# 파이프라인에서 Claude 사용
$ grep -l "TODO" *.py | while read file; do
    claude -p "이 파일의 모든 TODO 항목을 수정하세요" < "$file"
done

세션 관리

# 세션을 시작하고 세션 ID 캡처
$ claude -p "새 프로젝트를 초기화하세요" --output-format json | jq -r '.session_id' > session.txt

# 같은 세션으로 계속
$ claude -p --resume "$(cat session.txt)" "단위 테스트를 추가하세요"

모범 사례

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

    # jq로 JSON 응답 파싱
    result=$(claude -p "코드 생성" --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 "오류가 발생했습니다:" >&2
        cat error.log >&2
        exit 1
    fi
    
  3. 다중 턴 대화에서 컨텍스트를 유지하기 위해 세션 관리 사용

  4. 장시간 실행되는 작업에 대해 타임아웃 고려:

    timeout 300 claude -p "$complex_prompt" || echo "5분 후 타임아웃"
    
  5. 여러 요청을 할 때 호출 간 지연을 추가하여 속도 제한 준수

실제 애플리케이션

Claude Code SDK는 개발 워크플로우와의 강력한 통합을 가능하게 합니다. 주목할 만한 예제 중 하나는 SDK를 사용하여 GitHub 워크플로우에서 직접 자동화된 코드 리뷰, PR 생성 및 이슈 분류 기능을 제공하는 Claude Code GitHub Actions입니다.

관련 리소스