API Key 없이 Claude Agent 서버 만들기! #1 — Claude Agent SDK

조현상·2026년 4월 2일

ClaudeCode

목록 보기
9/17
post-thumbnail

들어가며

Claude를 프로그래밍적으로 사용하려면 보통 Anthropic API Key를 발급받아야 합니다. 사용량만큼 과금되는 종량제 구조죠.

그런데 저는 이미 Claude Pro(또는 Max) 구독을 하고 있습니다. 이미 돈을 내고 있는데, 자동화를 위해 API Key 비용을 또 내야 하나? 라는 생각이 들었습니다.

방법이 있었습니다. Claude Agent SDK는 Anthropic API가 아니라 Claude Code CLI를 내부적으로 실행합니다. 즉, CLI에 로그인된 OAuth 토큰만 있으면 API Key 없이도 Claude를 코드에서 호출할 수 있습니다.

이 글에서는 이 구조를 활용해서 Docker 컨테이너 위에 Claude Agent HTTP 서버를 올리는 과정과, 그 과정에서 만난 삽질들을 공유합니다.


Claude Agent SDK란?

Claude Agent SDK는 Anthropic이 공식으로 제공하는 Python SDK입니다. 핵심은 query() 함수 하나로, Claude에게 프롬프트를 보내고 응답을 비동기 스트림으로 받을 수 있습니다.

from claude_agent_sdk import query, ClaudeAgentOptions

options = ClaudeAgentOptions(
    permission_mode="bypassPermissions",
    allowed_tools=["Read", "Write", "Edit", "Bash"],
)

async for message in query(prompt="hello.py 만들어줘", options=options):
    print(message)

중요한 점은, 이 SDK가 내부적으로 Claude Code CLI를 subprocess로 실행한다는 것입니다. API Key가 아니라 CLI의 인증 체계(OAuth 토큰)를 그대로 사용합니다.


전체 아키텍처

[클라이언트] → HTTP 요청 → [FastAPI 서버] → [Claude Agent SDK] → [Claude Code CLI] → [Claude]
                              (Docker 컨테이너 내부)

구성 요소는 단순합니다:

파일역할
main.pyFastAPI 서버 — /query, /query/stream 엔드포인트
entrypoint.sh컨테이너 시작 시 OAuth 토큰을 .claude.json에 주입
DockerfilePython 3.12 + Node.js 20 + 비루트 사용자 설정
docker-compose.yml환경변수, 포트, 볼륨 마운트 구성

삽질 기록: Docker에서 Claude CLI 돌리기

단순히 pip install claude-agent-sdk만 하면 될 줄 알았지만, Docker 환경에서는 예상치 못한 문제들이 있었습니다.

1. Node.js가 필요하다

Claude Agent SDK는 내부적으로 Claude Code CLI를 실행하는데, 이 CLI가 Node.js 기반입니다. Python 이미지에는 Node.js가 없으므로 직접 설치해야 합니다.

RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
    && apt-get install -y --no-install-recommends nodejs

2. 온보딩 위저드가 컨테이너를 죽인다

Claude CLI는 처음 실행할 때 대화형 온보딩을 시도합니다. TTY가 없는 Docker 컨테이너에서는 이 과정에서 exit code 1로 종료됩니다.

해결책은 ~/.claude.json에 온보딩 완료 플래그를 미리 심어두는 것입니다:

RUN echo '{"hasCompletedOnboarding": true}' > /home/claude/.claude.json

3. OAuth 토큰 주입

Claude CLI는 ~/.claude.json 파일에서 인증 정보를 읽습니다. 컨테이너 시작 시 환경변수의 토큰을 이 파일에 주입해야 합니다.

entrypoint.sh에서 jq를 사용해 처리합니다:

echo "$EXISTING" | jq \
    --arg token "$CLAUDE_CODE_OAUTH_TOKEN" \
    '. + {
        "hasCompletedOnboarding": true,
        "oauthAccount": (.oauthAccount // {
            "emailAddress": "docker@claude-agent.local",
            "organizationName": "Docker Agent"
        })
    }' > "$CLAUDE_JSON"

FastAPI 서버 구현

서버는 두 가지 엔드포인트를 제공합니다.

동기 응답 — POST /query

전체 결과를 모아서 한 번에 반환합니다. 단순한 요청에 적합합니다.

curl -X POST http://localhost:8000/query \
  -H "Content-Type: application/json" \
  -d '{"prompt": "피보나치 함수 작성해줘"}'

스트리밍 응답 — POST /query/stream

SSE(Server-Sent Events)로 메시지를 실시간 전달합니다. Claude가 도구를 사용하는 과정까지 실시간으로 확인할 수 있습니다.

curl -N -X POST http://localhost:8000/query/stream \
  -H "Content-Type: application/json" \
  -d '{"prompt": "hello.py 만들어줘"}'

스트리밍 응답에서는 텍스트, 도구 사용, 결과를 구분해서 전달합니다:

{"type": "text", "content": "파일을 작성하겠습니다."}
{"type": "tool_use", "tool": "Write", "input": {...}}
{"type": "result", "content": "hello.py를 작성했습니다."}

요청 파라미터

{
  "prompt": "수행할 작업",
  "system_prompt": "시스템 프롬프트 (선택)",
  "allowed_tools": ["Read", "Write", "Edit", "Bash", "Glob"],
  "max_turns": null,
  "model": null
}

allowed_tools로 에이전트가 사용할 수 있는 도구를 제어할 수 있고, permission_mode: "bypassPermissions"로 매번 승인 없이 자동 실행됩니다.


실행 방법

1. OAuth 토큰 생성

호스트에 Claude Code CLI가 설치되어 있어야 합니다.

claude setup-token

출력된 sk-ant-oat01-... 토큰을 복사합니다.

2. 환경변수 설정

cp .env.example .env

.env 파일에 토큰을 붙여넣습니다:

CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-여기에-토큰-입력

3. 실행

docker compose up --build

서버가 http://localhost:8000에서 시작됩니다.


이 구조의 장단점

장점

  • 추가 비용 없음 — Claude Pro/Max 구독만 있으면 됨
  • API Key 관리 불필요 — OAuth 토큰은 CLI에서 바로 생성
  • 에이전트 기능 그대로 — 파일 읽기/쓰기, 코드 실행 등 Claude Code의 도구를 모두 사용 가능
  • Docker로 격리 — 에이전트의 파일 조작이 workspace/ 볼륨 안에서만 이루어짐

주의할 점

  • 개인용 — 제3자에게 서비스하려면 별도 인증 레이어 필요
  • OAuth 토큰 만료 — 토큰이 만료되면 claude setup-token으로 재발급 필요
  • 구독 플랜 제한 — 구독 플랜의 사용량 한도가 그대로 적용됨

마치며

Claude API Key 없이도 Claude Agent를 프로그래밍적으로 활용할 수 있다는 점이 이 프로젝트의 핵심입니다. 이미 구독 중이라면, 자동화나 개인 프로젝트에 추가 비용 없이 Claude를 연동할 수 있습니다.

전체 소스 코드는 GitHub에서 확인할 수 있습니다:
👉 GitHub 레포지토리 링크

profile
꿈꾸는 개발자

0개의 댓글