TRENDSHIFT DAILY #6 · 2026-07-24 · CLAUDE-TAP · AI 에이전트 트래픽 도청기

liaohch3/claude-tap 딥다이브
— 내 코딩 에이전트가 뒤에서 뭘 주고받는지, 로컬 프록시로 전부 엿보다

claude-tap은 Claude Code·Codex·Gemini CLI 같은 AI 코딩 에이전트(AI coding agent)의 API 통신을 가로채 보여주는 로컬 프록시 + 트레이스 뷰어다. 한 문장으로 말하면 "내가 쓰는 코딩 에이전트가 서버에 실제로 보내는 시스템 프롬프트·대화 기록·툴 정의·토큰 사용량을, 내 컴퓨터 안에서 한 글자도 밖으로 흘리지 않고 낱낱이 들여다보게 해준다". claude 대신 claude-tap이라고 치기만 하면 된다.

이 프로젝트의 급소는 이것이다: 코딩 에이전트를 "블랙박스"에서 "유리 상자"로 바꿔놓는다. 우리는 에이전트가 왜 그렇게 답했는지 결과만 보고 추측하지만, claude-tap은 "매 턴마다 모델에 실제로 실린 컨텍스트"를 원본 그대로 보여준다. 게다가 16종의 서로 다른 CLI를 단 하나의 워크플로우로 다룬다.

(저장소 liaohch3/claude-tap · 언어 Python 3.11+ · 버전 v0.1.139 · claude_tap 패키지 ~30개 모듈·16,000줄+ · 지원 클라이언트 16종 · 의존성 단 3개 · ★ 2.7k · 라이선스 MIT · 원저자 liaohch3 · shallow clone 소스 직접 분석)
목차
  1. 프로젝트 한 줄 요약
  2. 왜 주목받는가 — 블랙박스를 여는 열쇠
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트
  7. 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한 줄 요약

"에이전트가 왜 저렇게 답했지?"를 추측이 아니라 증거로 푸는 도구

요즘 우리는 터미널에서 claude, codex, gemini 같은 명령을 치고 AI에게 코드를 맡긴다. 그런데 그 도구들은 안에서 무슨 일이 벌어지는지 거의 보여주지 않는다. 에이전트가 이상한 답을 하거나, 토큰을 갑자기 폭발적으로 쓰거나, 엉뚱한 파일을 건드릴 때 — 우리는 그저 결과만 보고 "왜 그랬을까"를 추측한다. 정작 모델에게 실제로 무엇이 전달됐는지는 볼 수 없다.

한 줄 비유

의사가 증상만 보고 약을 짓다가, X-ray·내시경으로 몸속을 직접 보게 된 것

코딩 에이전트를 쓰는 건 "환자의 겉모습만 보고 진단하는 것"과 같다 — 답이 이상해도 원인을 몸 밖에서 추측할 뿐이다. claude-tap은 "몸속을 찍는 영상 장비"다. 매 요청마다 모델에 실린 시스템 프롬프트, 대화 이력, 툴 목록, 파라미터를 원본 그대로 펼쳐 보여준다. 게다가 이 "영상"은 전부 내 컴퓨터 안에만 저장된다.

claude-tap이 하는 일은 명확하다. 에이전트와 API 서버 사이에 끼어 앉아(프록시) → 오가는 요청·응답을 그대로 복사해 기록하고 → 스트리밍 응답을 온전한 메시지로 재조립한 뒤 → 자기완결형 HTML 뷰어(self-contained viewer)로 펼쳐 보여준다. 핵심은 "가로채되 바꾸지는 않는다"는 것 — 통신을 있는 그대로 흘려보내면서 사본만 남긴다.

TERM
프록시 (proxy)
두 컴퓨터 사이에 끼어 앉아 통신을 중계하는 중간 서버. "대리(代理)"라는 뜻이다. claude-tap은 에이전트와 API 서버 사이의 프록시가 되어, 지나가는 데이터를 중계하면서 동시에 사본을 기록한다. 우체국이 편지를 배달하면서 겉봉을 촬영해 두는 것과 비슷하다.

이름은 claude-tap이지만 Claude 전용이 아니다. Claude Code, Codex CLI, Codex App, Gemini CLI, Grok, Kimi, OpenCode, Cursor CLI, Qoder, CodeBuddy 등 16종을 지원한다. 여기서 tap은 전화 "도청(wiretap)"의 그 tap이다 — 선에 살짝 손대어(tap) 오가는 신호를 엿듣는다는 뜻.

2왜 주목받는가

"프롬프트 엔지니어링"이 유행하는 시대에, 남의 프롬프트를 훔쳐볼 수 있는 도구

2026년, 코딩 에이전트는 넘쳐난다. 그런데 정작 "이 에이전트가 내부적으로 어떤 프롬프트를 쓰는지", "매 턴 컨텍스트를 어떻게 쌓는지"는 다들 궁금해하면서도 알 방법이 없었다. claude-tap이 트렌딩에 오른 이유는 이 답답함을 정확히 긁어주기 때문이다 — "에이전트의 속을 들여다보고 싶다"는 개발자들의 공통된 욕구를 하나의 도구로 해결했다.

차별점 ① — 16종 클라이언트를 하나의 워크플로우로

비슷한 도구(예: mitmproxy, Charles Proxy)는 범용 HTTP 프록시라, 코딩 에이전트마다 인증 방식·엔드포인트·스트리밍 포맷이 제각각인 걸 일일이 사람이 맞춰줘야 한다. claude-tap은 이 지저분한 배선 작업을 클라이언트별로 미리 내장했다. --tap-client codex처럼 이름만 대면, 그 CLI의 인증 상태를 읽어 알맞은 상류(upstream)와 프록시 모드를 자동으로 골라준다.

지원 클라이언트(16종)대표 상류 / 특징
Claude CodeAnthropic API · AWS Bedrock · Vertex · DeepSeek/GLM 게이트웨이 자동 감지
Codex CLI / Codex AppOpenAI API 키 또는 ChatGPT 구독 OAuth · 앱은 백엔드 WebSocket까지 포착
Gemini CLIGoogle OAuth / Code Assist (포워드 프록시 기본)
Grok / Kimi / Kimi Code공식 CLI 프록시·네이티브 base URL 환경변수 활용
OpenCode / MiMo / Pi / Hermes / OpenClaw멀티 프로바이더 — 어떤 상류든 잡으려고 포워드 모드 기본
Cursor CLI / Qoder / Antigravity / CodeBuddybase URL 오버라이드가 없어 포워드 프록시 + 로컬 트랜스크립트 병행

차별점 ② — "진짜 인증"을 깨지 않고 가로챈다

여기가 기술적으로 가장 영리한 부분이다. ChatGPT 구독 OAuth나 AWS SigV4 서명처럼 인증이 걸린 통신은 프록시가 URL을 함부로 바꾸면 서명이 깨져 인증이 실패한다. claude-tap은 이럴 때 포워드 프록시(forward proxy) 모드로 전환해, 클라이언트가 진짜 서버 주소를 그대로 믿게 두고 중간에서 TLS만 살짝 벗겨 훔쳐본다. 덕분에 OAuth 세션을 건드리지 않는다.

차별점 ③ — 프라이버시가 기본값

트레이스는 전부 로컬 SQLite에 저장되고 호스팅 대시보드가 필요 없다. 기록 전에 Authorization·Cookie·x-api-key 같은 민감 헤더는 자동으로 가려진다(redaction). 게다가 스캐너가 /etc/passwd 같은 엉뚱한 경로로 찔러도, 알려진 API 경로가 아니면 상류로 보내지도 기록하지도 않고 404로 막는다.

GOOD
왜 이 조합이 강력한가

속을 보고 싶은 호기심(프롬프트 훔쳐보기), 디버깅의 실용성(왜 이 답이 나왔나), 자료를 밖으로 안 보내는 안전함(로컬 저장·헤더 마스킹) — 이 셋을 설치 명령 한 줄실행 명령 한 단어로 묶었다. 진입 장벽이 거의 없다는 게 트렌딩의 진짜 동력이다.

3기술 스택 전체 지도

놀랄 만큼 얇다 — 표준 라이브러리 + 딱 3개의 외부 의존성

claude-tap의 기술 선택에는 뚜렷한 철학이 있다: "가볍고, 설치가 쉽고, 어디서나 돌아간다". 네트워크 도구인데도 무거운 프레임워크가 하나도 없다. 전부 Python 비동기 표준 위에 얹혀 있다.

백엔드 — 비동기 프록시 엔진 (Python)

레이어기술역할
런타임Python 3.11+ (개발 3.13)전 계층이 asyncio 기반 단일 프로세스 비동기
HTTP/WSaiohttp 3.14프록시 서버·상류 클라이언트·SSE/WebSocket 중계·뷰어 웹서버까지 모두 담당
암호화cryptography ≥42포워드 프록시용 CA·호스트 인증서를 코드로 생성(MITM TLS)
압축backports-zstdzstd 응답 해제(3.14 미만 파이썬 보완) · gzip/zlib은 표준
저장SQLite (sqlite3 표준)트레이스를 traces.sqlite3 단일 DB에 기록(스키마 v4)
패키징setuptools-scm · uv/pipgit 태그에서 버전 자동 산출 · uv tool install 권장
비유

보통 이런 도구는 "프레임워크 뷔페"를 차린다 — 웹서버 하나, HTTP 클라이언트 하나, 암호화 라이브러리 하나, 각각 다른 벤더. claude-tap은 aiohttp라는 만능 칼 하나로 서버·클라이언트·스트리밍·웹뷰어를 전부 해낸다. 의존성이 3개뿐이라 pip install 한 번이면 끝나고, 충돌날 부품 자체가 적다.

프론트엔드 — 의존성 제로 뷰어 (바닐라 웹)

뷰어는 React도 번들러도 쓰지 않는다. viewer.htmldashboard.html바닐라 JS·CSS를 직접 넣고, 파이썬이 트레이스 데이터를 주입해 단일 HTML 파일 하나로 뽑아낸다. 그래서 결과물을 이메일로 보내거나 CI 아티팩트로 올려도 어디서든 브라우저만 있으면 열린다.

뷰어 구성내용
viewer.html / .py내보내기용 정적 뷰어 — 구조적 diff·검색·툴 인스펙터·토큰 분석·다크모드
dashboard.html저장된 여러 세션을 브라우징하는 대시보드(클라이언트 실행 없이도 열람)
viewer_i18n.json8개 언어(영어·简体中文·日本語·한국어·Français·العربية·Deutsch·Русский)
라이브 모드live.py가 SSE로 브라우저에 실시간 push — 실행 중 새 요청이 즉시 뜸

인프라/플랫폼 통합

순수 CLI 도구를 넘어 OS별 통합까지 챙긴다. macOS에서는 macos_app.py·macos_bundle.py메뉴바 앱을 빌드해준다(claude-tap build-macos-app). Apple Silicon용으로 파이썬까지 통째로 넣은 self-contained 번들도 만들 수 있어, 파이썬이 없는 동료에게도 .app 하나만 건네면 된다.

TERM
SSE (Server-Sent Events)
서버가 클라이언트로 한 방향 실시간 스트림을 밀어 보내는 웹 표준. AI 응답이 글자 단위로 "타이핑되듯" 흘러오는 게 바로 이것이다. claude-tap은 이 스트림을 두 번 쓴다 — ① 에이전트↔모델 응답을 이 포맷으로 받아 재조립하고, ② 자기 라이브 뷰어에서 브라우저로 갱신을 밀 때도 SSE를 쓴다.

4아키텍처 심화 분석

두 가지 프록시 모드 — 이 도구의 심장

claude-tap의 모든 것은 "어떻게 통신 중간에 끼어들 것인가"로 귀결된다. 그런데 클라이언트마다 사정이 다르다. 어떤 CLI는 "서버 주소를 바꿔줄게"라는 환경변수를 순순히 받아들이고, 어떤 CLI는 주소를 절대 못 바꾸게 막혀 있다. 그래서 두 가지 프록시 모드를 준비했다.

모드 1 — 리버스 프록시 (reverse proxy)

base URL 환경변수(ANTHROPIC_BASE_URL 등)를 지원하는 클라이언트에 쓴다. 에이전트에게 "진짜 서버 대신 내 로컬 주소를 보라"고 알려주는 방식이다. 가장 깔끔하다 — 요청 하나당 트레이스 하나가 온전히 남는다.

┌──────────────┐ ①http://127.0.0.1:PORT ┌───────────────────┐ ②실제 상류로 ┌──────────────┐ │ Claude Code │ ───────────────────────▶ │ claude-tap │ ───────────────▶ │ api.anthropic│ │ (에이전트) │ │ 리버스 프록시 │ │ .com │ │ │ ◀─────────────────────── │ · 헤더 마스킹 │ ◀─────────────── │ (진짜 서버) │ └──────────────┘ ④응답 스트림 그대로 │ · 요청/응답 기록 │ ③응답 └──────────────┘ └─────────┬─────────┘ ANTHROPIC_BASE_URL 을 │ 기록 로컬 주소로 바꿔치기 ▼ ┌───────────────────┐ │ traces.sqlite3 │ ← SSE 재조립 후 저장 └───────────────────┘

포인트는 strip_path_prefix 같은 경로 정규화다. 예컨대 Codex OAuth는 /v1/*로 요청을 보내지만 상류는 이미 /codex 백엔드라 /v1을 떼줘야 한다. 이런 클라이언트별 규칙이 ClientConfig에 선언돼 있다.

모드 2 — 포워드 프록시 + MITM TLS (forward proxy)

주소를 못 바꾸는(멀티 프로바이더거나 OAuth/서명이 걸린) 클라이언트에 쓴다. 이때는 HTTPS_PROXY 환경변수와 우리 CA 인증서를 자식 프로세스에 심어, 클라이언트가 진짜 서버 주소를 그대로 믿으면서 실제로는 우리 프록시를 거치게 한다.

①CONNECT api.openai.com:443 ┌───────────────────────────────┐ ┌──────────────┐ ───────────────────▶ │ claude-tap 포워드 프록시 │ │ Codex CLI │ ②200 Connection │ │ │ (에이전트) │ ◀─────Established─── │ ③우리 CA로 서명한 가짜 │ │ │ │ 호스트 인증서를 제시 │ │ HTTPS_PROXY │ ④TLS 핸드셰이크 ────▶ │ (클라이언트는 진짜인 줄 앎) │ │ + 우리 CA │ │ │ │ │ ⑤암호 터널 안의 │ ⑥평문 요청을 읽어 기록 후 │ 진짜 TLS로 │ │ 평문 HTTP 요청 ──▶ │ 상류로 재전송 │ ─────────────▶ api.openai.com └──────────────┘ └───────────────────────────────┘
TERM
MITM (Man-In-The-Middle) TLS 종료
암호화된 HTTPS를 중간에서 일단 복호화했다가 다시 암호화해 전달하는 기법. 보통은 "공격"에 쓰이는 말이지만, 여기서는 내가 내 컴퓨터에서 내 트래픽을 보려고 스스로에게 적용한다. 핵심 부품이 "CA 인증서" — 이걸 내 기기가 신뢰하게 만들어야 가짜 인증서가 통한다. claude-tap이 cryptography로 CA를 직접 굽는 이유다.

인증서는 어떻게 만들어지나 (certs.py)

첫 실행 때 ~/.claude-tap/자체 서명 CA(ca.pem + ca-key.pem, 유효기간 5년, RSA-2048)를 한 번 굽는다. 이후 접속하는 호스트마다 이 CA로 서명한 인증서를 즉석에서 만들어(1년 유효) 메모리에 캐시한다. macOS에서 환경변수 CA를 무시하는 일부 앱(예: Antigravity)은 시스템 키체인이 아니라 사용자 로그인 키체인에만 CA를 신뢰 등록한다 — sudo 없이, 최소 권한으로.

공통 파이프라인 — 가로챈 뒤에 벌어지는 일

요청/응답 바이트 │ ▼ ┌─────────────────┐ 민감 헤더 마스킹 ┌──────────────────┐ 스트리밍이면 │ filter_headers │ ───────────────────▶ │ 경로 allowlist │ ─────────────────┐ │ authorization → │ (Authorization, │ 아는 API 경로만 │ ▼ │ 앞 12자 + ... │ x-api-key 등) │ 통과, 나머지 404 │ ┌──────────────────┐ └─────────────────┘ └──────────────────┘ │ SSEReassembler │ │ │ 조각 이벤트를 │ ▼ │ 완전한 응답으로 │ ┌─────────────────┐ 포터블 압축 ┌──────────────────┐ │ 재조립 │ │ TraceWriter │ ◀──── blob 중복제거 ─ │ compact_trace │◀───────┤ (Anthropic/ │ │ SQLite 기록 + │ │ (.ctap.json 내보내기) │ OpenAI 포맷 모두)│ │ 통계 누적 │ ─── LiveServer로 ───▶ 브라우저 SSE push └──────────────────┘ └──────────────────┘ └─────────────────┘
설계 패턴 · 핵심 3가지

이 코드에서 배울 만한 설계 결정

① 클라이언트별 설정을 데이터로 (ClientConfig dataclass): "코덱스는 이렇게, 제미나이는 저렇게" 같은 분기를 코드가 아니라 선언적 데이터로 표현했다. base_url_env, default_proxy_mode, strip_path_prefix, auto_trust_ca_macos 같은 필드만 채우면 새 클라이언트가 추가된다. 16종을 감당하는 비결.

② "가로채되 바꾸지 않는다": 상류로 보내는 원본 바이트는 절대 훼손하지 않고, 트레이스용 사본만 파싱한다(_parse_request_body_for_trace). 그래서 프록시가 끼어도 에이전트 동작이 달라지지 않는다.

③ 포맷 차이를 한 곳에서 흡수: Anthropic·OpenAI Responses·OpenAI Chat Completions·AWS Bedrock EventStream까지 응답 포맷이 다 다른데, SSEReassemblerusage.normalize_usage"내부 표준 형태" 하나로 정규화한다. 뷰어는 포맷을 신경 쓸 필요가 없다.

5디렉토리 구조 해부

~30개 모듈이 "가로채기 → 기록 → 보여주기" 세 덩어리로 나뉜다
claude-tap/ ├── claude_tap/ ← 본체 패키지 (약 16,000줄) │ │ ┌─ [1] 실행·설정 계층 ──────────────────────────────── │ ├── cli.py (1092줄) CLI 진입점 · 인자 파싱 · 오케스트레이션 │ ├── cli_clients.py (2125줄) ★16종 클라이언트 설정·상류 자동감지(ClientConfig) │ ├── cli_update.py ( 78줄) self-update (uv/pip 감지) │ │ ┌─ [2] 가로채기 계층 (프록시) ───────────────────────── │ ├── proxy.py ( 900줄) 리버스 프록시 · 헤더 마스킹 · 경로 allowlist │ ├── forward_proxy.py (1319줄) 포워드 프록시 · CONNECT · MITM TLS 종료 │ ├── ws_proxy.py ( 609줄) WebSocket 중계(Codex App 등) │ ├── certs.py ( 277줄) CA·호스트 인증서 생성(cryptography) │ ├── sse.py ( 575줄) SSE 재조립기 — 스트림을 완전한 응답으로 │ ├── bedrock.py ( 68줄) AWS EventStream 바이너리 디코드 │ ├── upstream.py ( 119줄) 상류 URL 조립 · 에러 포맷 │ │ ┌─ [3] 저장·직렬화 계층 ─────────────────────────────── │ ├── trace_store.py (1543줄) SQLite 저장소(traces.sqlite3, 스키마 v4) │ ├── trace.py ( 174줄) TraceWriter — 비동기 기록 + 통계 │ ├── compact_trace.py ( 309줄) 포터블 압축 번들(.ctap.json, blob 중복제거) │ ├── export.py ( 367줄) JSONL/compact → HTML 내보내기 │ ├── history.py ( 43줄) 세션 정리 · 레거시 마이그레이션 │ ├── prompt_snapshot.py ( 537줄) capture-only 프롬프트 export(Phistory 연동) │ │ ┌─ [4] 보여주기 계층 (뷰어) ─────────────────────────── │ ├── viewer.py / .html (1220줄) 자기완결 HTML 뷰어 생성 · 구조적 diff │ ├── dashboard.py / .html (1350줄) 저장 세션 브라우징 대시보드 │ ├── live.py ( 781줄) LiveViewerServer — SSE 실시간 push │ ├── shared_dashboard.py ( 464줄) 공유 대시보드 서비스 │ ├── viewer_i18n.json 8개 언어 번역(한국어 포함) │ │ ┌─ [5] 플랫폼 통합 ──────────────────────────────────── │ ├── macos_app.py ( 840줄) macOS 메뉴바 앱 · Start/Stop Monitor │ ├── macos_bundle.py ( 373줄) .app 번들 빌드(self-contained 옵션) │ └── cursor_transcript.py ( 206줄) Cursor 로컬 트랜스크립트 import ├── docs/ ← 공개 문서(README 자산·support-matrix) ├── .agents/ ← 유지보수자용 규칙·스킬(공개 docs와 분리) ├── tests/ ← pytest(단위·통합·real E2E) ├── scripts/ ← CI 게이트 스크립트(커버리지·스크린샷 검증) ├── pyproject.toml ← 의존성 3개 · ruff · pytest · 커버리지 게이트 └── README.md / README_zh.md ← 영·중 이중 문서(필수 규칙)

구조가 말해주는 이야기는 분명하다. "가로채기(proxy)"가 가장 두껍고(코어), "설정(cli_clients)"이 그 다음이다. 16종 클라이언트의 제각각인 인증·엔드포인트를 흡수하는 cli_clients.py(2,125줄)가 단일 최대 모듈이라는 게, 이 프로젝트의 진짜 난이도가 "프록시 그 자체"보다 "현실의 도구들을 다 맞춰주는 것"에 있음을 보여준다.

비유

공항의 보안 검색대를 떠올리면 된다. 실제로 짐을 통과시키는 X-ray 기계(proxy)는 한 대지만, 나라마다 다른 여권·비자·언어를 처리하는 입국 심사 매뉴얼(cli_clients)이 훨씬 두껍다. claude-tap도 "찍는 장치"는 단순하고, "온갖 여행객을 응대하는 규칙"이 방대하다.

6학습 포인트

이 레포 하나로 배울 수 있는 것들 — 네트워크·비동기·보안이 한자리에

배울 것 ① — 프록시와 MITM의 원리

"HTTPS는 암호화돼서 못 본다"는 통념을 forward_proxy.py + certs.py가 실물로 깨준다. CONNECT 터널링, TLS 종료, CA로 호스트 인증서를 즉석 발급하는 과정을 200줄 남짓한 읽을 만한 코드로 볼 수 있다. Charles·mitmproxy가 안에서 뭘 하는지 궁금했다면 최고의 교재다.

배울 것 ② — asyncio 스트리밍의 정석

AI 응답은 SSE 스트림으로 온다. 이걸 "다 받고 나서" 처리하면 라이브 뷰어가 불가능하다. claude-tap은 조각이 도착하는 즉시 클라이언트로 흘려보내면서 동시에 사본을 재조립한다(sse.pyfeed_bytes). 지연을 안 만들면서 가로채는 비동기 패턴의 좋은 예다.

배울 것 ③ — "설정을 데이터로" 만드는 확장 설계

16종을 if client == ... 분기로 짰다면 코드가 지옥이 됐을 것이다. ClientConfig dataclass 하나로 새 클라이언트 = 새 데이터 한 줄이 되도록 만든 설계는, 어떤 프로젝트에서든 재사용할 수 있는 확장 지점(extension point) 패턴이다.

배울 것 ④ — 오픈소스 "프로다움"의 표준

코드 밖도 배울 게 많다. docs/support-matrix.md는 (클라이언트 × 인증 × 상류 × 전송)의 검증된 조합을 표로 관리하고, "프록시/라우팅 변경 시 해당 행을 전부 재검증"을 규칙으로 못박았다. 커버리지 게이트(신규 코드 80%), 이중 언어 문서, real E2E 증거(가짜 스크린샷 금지) 같은 성숙한 프로젝트 운영을 통째로 관찰할 수 있다.

주의
이건 "공격 도구"가 아니다 — 하지만 CA는 신중히

claude-tap은 내 기기에서 내 트래픽을 보는 도구다. 하지만 원리상 로컬에 신뢰된 CA를 설치한다는 점은 이해하고 있어야 한다. 이 CA 개인키(~/.claude-tap/ca-key.pem)가 유출되면 남이 내 기기의 HTTPS를 위조할 수 있으니, 키 파일을 공유하거나 복사해 옮기지 말 것. 남의 기기·회사 자산에 무단으로 트래픽 가로채기를 적용하는 건 당연히 금물이다.

실습 아이디어(맛보기)

7시스템 요구사항

거의 없다 — 그게 장점이다
항목요구사항
Python3.11 이상(3.11 / 3.12 / 3.13 분류자 명시, 개발 3.13)
설치uv tool install claude-tap(권장) 또는 pip install claude-tap
외부 의존성단 3개 — aiohttp · cryptography · backports-zstd
OSmacOS · Linux · Windows(윈도우는 claude-tap.exe 경로 이슈 안내 있음)
대상 클라이언트추적하려는 CLI(claude/codex/gemini …)는 별도로 설치·로그인돼 있어야 함
저장 공간트레이스는 ./.traces에 SQLite로 · 기본 최근 50세션 유지(--tap-max-traces로 조절)
네트워크기본 127.0.0.1 바인딩(로컬 전용) · 프록시-온리 모드에선 0.0.0.0
macOS 앱메뉴바 앱 빌드 시 · self-contained 번들은 Apple Silicon(PyInstaller)

요구사항이 이렇게 얇은 건 의도된 설계다. 디버깅 도구는 "쓰고 싶은 순간 바로 써져야" 가치가 있다 — 무거운 셋업이 필요하면 정작 급할 때 안 쓰게 된다. claudeclaude-tap으로 바꿔 치는 마찰 없는 진입이 이 도구의 철학이다.

8직접 해볼 수 있는 실습 과제

난이도별 5개 — 그냥 읽지 말고 손으로 가로채 보기
난이도 ★ · 입문

1. 내 에이전트의 "숨은 시스템 프롬프트" 훔쳐보기

uv tool install claude-tapclaude-tap으로 평소처럼 한 번 대화한다. 종료하면 뜨는 HTML 뷰어에서 첫 요청을 열어 system 프롬프트tool 정의 목록을 읽어본다. "에이전트가 실제로 뭘 아는지"를 처음으로 눈으로 확인하는 경험. 코드 한 줄 안 짜도 된다.

난이도 ★★ · 초급

2. 턴별 컨텍스트 증가를 diff로 추적

여러 번 주고받은 세션에서 구조적 diff 버튼을 눌러, 매 요청마다 어떤 메시지·툴 결과가 새로 붙는지 본다. 그리고 뷰어의 토큰 사용량 분석(입력·출력·캐시 읽기·캐시 생성)을 보며 "어디서 토큰이 폭발하는지" 짚어본다. 프롬프트 캐시가 어떻게 동작하는지 감이 잡힌다.

난이도 ★★★ · 중급

3. 다른 에이전트로 갈아 끼워 프롬프트 비교

--tap-client codex, --tap-client gemini 등으로 서로 다른 CLI를 같은 작업에 돌린 뒤, 각자의 시스템 프롬프트·툴 스키마를 나란히 비교한다. "어느 에이전트가 컨텍스트를 더 알뜰하게 쓰는가"를 추측이 아니라 원본 증거로 판정해 본다.

난이도 ★★★★ · 중상급

4. 코드 읽고 "새 클라이언트" 이해하기

cli_clients.pyClientConfigCLIENT_CONFIGS를 읽고, 기존 클라이언트 하나가 어떤 필드로 정의됐는지 표로 정리한다. 그런 다음 docs/support-matrix.md와 대조하며 "리버스 vs 포워드 모드가 왜 그렇게 정해졌는지"를 스스로 설명해 본다. 확장 설계를 읽는 훈련.

난이도 ★★★★★ · 고급

5. 미니 MITM 프록시 직접 구현

certs.py(CA 생성) + forward_proxy.py(CONNECT·TLS 종료)를 참고해, aiohttp + cryptography로 100줄짜리 미니 MITM 프록시를 스스로 짜본다. 로컬에서 자기 자신의 HTTPS 요청 하나를 가로채 헤더를 콘솔에 찍는 것까지가 목표. 성공하면 "HTTPS를 못 본다"는 통념이 완전히 깨진다. 반드시 내 기기·내 트래픽으로만.

9관련 기술 심화 학습 로드맵

claude-tap을 완전히 소화하기 위한 4주 코스
주차주제학습 내용
1주차HTTP·TLS 기초HTTP 메서드·헤더·상태코드 / TLS 핸드셰이크 / CONNECT 터널링 / 인증서 체인과 CA의 역할. 도구: curl -v, openssl s_client
2주차프록시와 MITM포워드 vs 리버스 프록시 차이 / mitmproxy로 실습 / certs.py 읽으며 CA·호스트 인증서 생성 원리 이해 / 왜 SigV4·OAuth는 URL을 못 바꾸는지
3주차Python asyncio 스트리밍asyncio 태스크·큐 / aiohttp 서버+클라이언트 / SSE·WebSocket 파싱 / sse.py의 재조립 로직 정독 / "흘리면서 복사"하는 비차단 패턴
4주차LLM API·컨텍스트 엔지니어링Anthropic Messages·OpenAI Responses/Chat 포맷 차이 / 툴 콜·툴 결과 구조 / 토큰·프롬프트 캐시 / claude-tap 뷰어로 실제 트래픽을 뜯어보며 "컨텍스트 설계" 감각 익히기

이 순서를 밟으면 claude-tap은 단순한 "편리한 도구"가 아니라 네트워크·비동기·보안·LLM을 잇는 살아있는 교과서가 된다. 각 주차의 개념이 정확히 어느 소스 파일에 구현돼 있는지 대응되기 때문에, "이론 → 실제 코드" 왕복 학습이 가능하다.

10핵심 키워드 사전

이 레포를 읽을 때 걸려 넘어지는 용어를 한 번에
용어의미
프록시(proxy)두 컴퓨터 사이에서 통신을 중계하는 중간 서버. claude-tap의 핵심 형태
리버스 프록시클라이언트가 "프록시를 진짜 서버로 알고" 접속. base URL 바꿔치기 방식
포워드 프록시클라이언트가 진짜 주소를 믿되 HTTPS_PROXY로 우리를 거침. 주소 못 바꾸는 CLI용
MITM / TLS 종료암호화 트래픽을 중간에서 복호화→재암호화. 여기선 "내 기기, 내 트래픽" 자기 관찰용
CA 인증서다른 인증서를 서명·발급하는 최상위 인증서. 기기가 신뢰해야 MITM이 통함
CONNECTHTTPS 프록시에게 "목적지로 터널을 뚫어달라"고 요청하는 HTTP 메서드
SSE서버가 클라이언트로 한 방향 실시간 스트림을 밀어보내는 표준. AI 응답 스트리밍의 정체
재조립(reassemble)조각조각 오는 스트림 이벤트를 누적해 "완전한 응답 하나"로 복원. SSEReassembler
트레이스(trace)요청-응답 한 쌍의 기록. 시스템 프롬프트·툴·메시지·토큰까지 담김
redaction(마스킹)저장 전에 민감 헤더(Authorization·x-api-key 등)를 가리는 처리
allowlist아는 API 경로만 통과시키는 목록. 스캐너의 엉뚱한 경로는 404로 차단
upstream(상류)프록시가 최종적으로 요청을 전달하는 진짜 API 서버
strip_path_prefix리버스 모드에서 경로 앞부분(예 /v1)을 떼는 정규화 규칙
ClientConfig16종 클라이언트의 인증·엔드포인트·프록시 모드를 담은 선언적 설정 dataclass
compact trace(.ctap.json)blob 중복을 제거한 포터블 트레이스 번들. 나중에 HTML로 렌더 가능
self-contained 뷰어외부 의존성 0인 단일 HTML. 어디서든 브라우저만으로 열림
EventStream(Bedrock)AWS Bedrock의 바이너리 스트림 포맷. bedrock.py가 디코드해 토큰·모델 추출

11참고 링크

원문으로 더 파고들기