API 키 없이,
AI 기능 만들기.
이미 컴퓨터에 설치된 claude CLI를 서버 코드에서 그대로 호출하면 됩니다. 발급도, 결제도, SDK도 필요 없이.
WHY THIS WORKS
개인용 로컬 도구로 “포트 관리기”라는 앱을 만들면서, AI로 이름을 추천해주는 기능을 붙이려고 했습니다. 그런데 첫 관문에서 막혔습니다 — API 키를 발급받고, 결제를 등록하고, 사용량을 관리하는 게 개인 프로젝트치고는 너무 번거로웠습니다.
그런데 이미 컴퓨터에 Claude Code가 설치되어 있다면, 별도의 API 키 없이도 로컬 서버(Node.js, Bun, PHP 뭐든)에서 Claude를 그대로 호출할 수 있다는 걸 알게 됐습니다. 포트 관리기의 AI 이름 추천 기능은 지금 정확히 이 방식으로 동작합니다. 오늘은 그 원리를 그대로 뜯어서, 누구나 자기 프로젝트에 적용할 수 있게 쉽게 설명해보겠습니다.
출력만 파싱한다.
사람이 이해할 부분
왜 되는지, 언제 쓰고 언제 쓰면 안 되는지 — 코드를 치기 전에 필요한 판단
핵심 아이디어claude는 그냥 커맨드라인 프로그램이다
API 키
CLI 세션을 재사용
단계
→ 파싱, 이게 전부
타임아웃
방지 안전장치
SDK
그대로 호출
Claude Code를 터미널에 설치하면 claude라는 실행 파일이 생깁니다. 우리가 평소에 대화하듯 쓰는 그 도구인데, 사실 이건 일반 CLI 프로그램이라서 다른 프로그램에서도 그냥 실행시킬 수 있습니다.
-p (또는 --print) 옵션을 주면, 대화형 모드로 들어가지 않고 프롬프트를 하나 던지고 → 답을 stdout으로 출력하고 → 바로 종료합니다. 즉, 서버 코드 입장에서는 “외부 프로그램 하나 실행해서 결과 텍스트 받기” 그 이상도 이하도 아닙니다.
Claude Code만의 이야기가 아닙니다. Codex CLI도 로컬에 설치되어 로그인까지 끝나 있으면 똑같은 원리로 씁니다. 대화형 세션 대신 exec 서브커맨드(별칭 e)를 쓰면 -p와 같은 역할 — “프롬프트 하나 → 최종 응답 하나 → 종료”로 동작합니다.
처음엔 그냥 which claude로 경로를 찾았습니다. 터미널에서는 잘 됐죠. 그런데 포트 관리기를 GUI 앱으로 띄우고 나니 이 함수가 계속 null을 반환했습니다. GUI 앱은 보통 .zshrc를 안 읽는 non-login 셸 환경에서 뜨기 때문에, nvm/homebrew로 설치한 claude의 PATH가 비어 있었던 겁니다. 로그인 셸(zsh -l -c)로 감싸고 나서야 사용자가 평소 터미널에서 쓰는 PATH가 그대로 재현됐습니다 — Part B의 resolveClaudePath()가 굳이 zsh -l -c를 거치는 이유가 이겁니다. codex를 GUI 앱에서 호출할 때도 완전히 같은 문제가 나므로 같은 방식으로 경로를 찾아야 합니다.
언제 쓰나장점과 주의할 점 — 쓰기 전에 판단할 것
| 기준 | 정식 Anthropic API | 로컬 claude CLI 호출 (이 글의 방식) |
|---|---|---|
| 발급 절차 | API 키 발급 + 결제수단 등록 필요 | 없음 — 이미 인증된 CLI 세션 재사용 |
| 비용 | 토큰 사용량만큼 별도 과금 | Claude Code 구독에 포함, 추가 과금 없음 |
| 배포 대상 | 웹에 배포해 불특정 다수가 쓰는 서비스 | 내 컴퓨터에서만 도는 개인용 로컬 도구 |
WHEN TO USE
API 키 관리가 필요 없다 — 이미 로컬에 설치되어 인증된 claude CLI 세션을 그대로 재사용합니다.
비용 걱정이 없다 (개인 사용 기준) — Claude Code 구독/사용량에 포함되는 방식이라, 서버용 API 과금이 따로 붙지 않습니다.
로컬 전용 도구에 적합 — 배포된 다중 사용자 웹서비스가 아니라, 내 컴퓨터에서만 도는 개인 도구(포트 관리기 같은)에 딱 맞습니다.
WHEN NOT TO
여러 사용자를 상대하는 프로덕션 서비스에는 맞지 않습니다. 이건 “내 컴퓨터에 설치된 CLI를 내 로컬 서버가 호출하는” 구조라서, 웹에 배포해 불특정 다수가 쓰는 서비스라면 정식 Anthropic API + API 키 발급이 맞는 선택입니다.
CLI가 없으면 실패합니다. resolveClaudePath()가 null을 반환하면 (Claude Code 미설치 등) 해당 기능은 503 에러를 내도록 처리해줘야 합니다.
타임아웃을 꼭 걸어주세요. 서브프로세스 호출은 응답이 안 올 수도 있으니, 강제 종료(proc.kill())하는 안전장치가 필요합니다.
AI에게 그대로 던질 부분
아래 프롬프트를 복사해서 Claude Code 같은 AI 코딩 어시스턴트에 붙여넣으면 구현됩니다
구현 프롬프트복사해서 AI 어시스턴트에 붙여넣기
이 프롬프트 안에 구현 순서, 폴백 경로, 타임아웃 값, 에러 처리까지 전부 들어 있습니다. 왜 이렇게 만들었는지가 궁금하면 위 Part A를 참고하세요.
참고 구현AI가 생성할 결과물 예시 (Bun 기준)
옵션 3개프롬프트가 지키는 조합 — 안전하고 저렴한 이유
| 옵션 | 역할 |
|---|---|
| -p | 대화형 세션 대신 “질문 하나 → 답변 하나” 모드로 실행 |
| –safe-mode | 파일 읽기/쓰기, 명령 실행 등 도구 접근을 막고 순수 텍스트 응답만 받음 — 서버에서 신뢰 안 되는 입력을 다룰 때 안전 |
| –model haiku | 이름/카테고리 추천처럼 가벼운 작업엔 가장 빠르고 저렴한 모델로 충분 |
Codex CLI로 같은 걸 하고 싶다면 대응하는 옵션은 이렇습니다. 완전히 1:1은 아니라서 차이도 같이 적었습니다.
| Codex 옵션 | Claude 대응 | 역할 · 차이점 |
|---|---|---|
| exec “…” | -p | 대화형 세션 대신 “프롬프트 하나 → 최종 응답” 후 종료 |
| –sandbox read-only | –safe-mode | 파일 쓰기·명령 실행을 막음. 단 Codex는 읽기 접근은 여전히 허용하므로 --safe-mode만큼 완전 차단은 아닙니다 — 신뢰 안 되는 입력을 다룰 땐 이 차이를 감안하세요. |
| -o <file> | 정규식으로 stdout 파싱 | --output-last-message가 최종 응답을 파일에 바로 써줍니다 — 정규식으로 JSON 블록을 긁어낼 필요가 없어서 오히려 더 간단합니다. |
| -m <model> | –model haiku | 가벼운 작업엔 저비용 모델을 지정. 정확한 모델 이름은 자주 바뀌므로 codex --help나 ~/.codex/config.toml에서 확인하세요. |
이미 있는 걸
다시 쓰면 된다.
API 키 발급도, 별도 SDK 설치도 필요 없이, 이미 여러분 컴퓨터에 있는 Claude Code를 그대로 “AI 엔진”으로 재활용하는 셈입니다. 개인용 로컬 도구를 만들 때 특히 유용한 패턴이니, 다음 사이드 프로젝트에 AI 기능을 붙이고 싶을 때 Part B의 프롬프트를 그대로 던져보세요.
새 API를 만드는 것보다, 이미 있는 인증을 재사용하는 게 더 빠르다.
답글 남기기