Claude Code 소스 유출이 드러낸 아키텍처 — 4편: Bridge, MCP, 멀티 에이전트
들어가며
지금까지 세 편에 걸쳐 Claude Code의 내부를 살펴봤습니다. 에이전틱 루프(심장), 도구와 권한(손발과 안전장치), 메모리와 컨텍스트(기억)까지 다뤘습니다.
마지막 편에서는 Claude Code의 세 번째 축, 연결과 확장을 다룹니다. Claude Code가 단독으로 동작하는 CLI가 아니라 다양한 환경과 연결되는 허브로 설계되었다는 것을, 세 가지 시스템을 통해 확인합니다.
Bridge — IDE와의 양방향 통신
Bridge는 원본에서 31개 모듈로 구성된 상당히 큰 서브시스템입니다. 모듈 수로 보면 5위에 해당합니다.
Bridge 모듈 구조
bridge/
├── bridgeApi.ts # 브리지 API 호출
├── bridgeConfig.ts # 설정
├── bridgeDebug.ts # 디버깅
├── bridgeEnabled.ts # 활성화 체크
├── bridgeMain.ts # 메인 브리지
├── bridgeMessaging.ts # 메시지 전달
├── bridgePermissionCallbacks.ts # 권한 콜백
├── bridgePointer.ts # 포인터
├── bridgeStatusUtil.ts # 상태 유틸
├── bridgeUI.ts # UI 연동
├── capacityWake.ts # 용량 기반 깨우기
├── codeSessionApi.ts # 코드 세션 API
├── createSession.ts # 세션 생성
├── flushGate.ts # 플러시 게이트
├── inboundAttachments.ts # 인바운드 첨부파일
├── inboundMessages.ts # 인바운드 메시지
├── initReplBridge.ts # REPL 브리지 초기화
├── jwtUtils.ts # JWT 인증
├── pollConfig.ts # 폴링 설정
├── remoteBridgeCore.ts # 원격 브리지 코어
├── replBridge.ts # REPL 브리지
└── replBridgeHandle.ts # REPL 브리지 핸들
이 구조에서 읽히는 것은, Bridge가 단순한 "메시지 전달자"가 아니라 완전한 통신 프로토콜이라는 것입니다.
Bridge의 역할
Bridge가 하는 일을 정리하면 다음과 같습니다.
- 양방향 통신: CLI와 IDE(VS Code, JetBrains) 간 실시간 메시지 전달
- 세션 동기화:
createSession.ts,codeSessionApi.ts로 CLI 세션을 IDE에 동기화 - JWT 인증:
jwtUtils.ts로 양쪽 간 인증 보장 - 권한 위임:
bridgePermissionCallbacks.ts로 IDE 측에서 권한 판단을 할 수 있도록 콜백 제공 - 첨부파일 처리:
inboundAttachments.ts로 IDE에서 CLI로 파일/이미지 전달
capacityWake.ts가 특히 흥미롭습니다. "용량 기반 깨우기"라는 이름에서 추론하면, CLI가 유휴 상태일 때 IDE 측에서 새 요청이 오면 깨우는 메커니즘으로 보입니다. Claude Code가 항상 프로세스를 살려두는 것이 아니라, 필요할 때만 활성화되는 효율적인 설계입니다.
remoteBridgeCore.ts의 존재는 Bridge가 로컬 통신만이 아니라 원격 통신도 지원한다는 것을 보여줍니다. SSH 원격 개발 환경에서도 IDE 연동이 가능한 구조입니다.
CLI 트랜스포트 — 3중 통신 채널
Bridge 외에도, CLI 자체가 3종의 트랜스포트를 지원합니다.
| 트랜스포트 | 파일 | 특성 |
|---|---|---|
| SSE | SSETransport.ts | 단방향 서버 → 클라이언트 스트리밍 |
| WebSocket | WebSocketTransport.ts | 양방향 실시간 통신 |
| Hybrid | HybridTransport.ts | SSE + WebSocket 결합 |
Hybrid 트랜스포트가 SSE와 WebSocket을 결합한다는 것은, 네트워크 환경에 따라 최적의 통신 방식을 선택할 수 있다는 뜻입니다. SSE가 방화벽에 막히면 WebSocket으로 폴백하거나, 그 반대도 가능한 구조인 것입니다.
추가로 SerialBatchEventUploader.ts(배치 이벤트 업로드), WorkerStateUploader.ts(워커 상태 업로드), ccrClient.ts(Claude Code Remote 클라이언트)도 있습니다. CCR은 Claude Code의 원격 실행 환경을 위한 전용 클라이언트로 보입니다.
MCP 통합 — 5종 트랜스포트
MCP(Model Context Protocol)는 Claude Code가 외부 도구/서비스와 연결되는 핵심 프로토콜입니다. Rust 포트에서 MCP 통합이 3개 모듈로 구현되어 있습니다.
MCP 도구 이름 규칙
먼저 사소하지만 중요한 설계 — MCP 도구의 이름 규칙입니다.
mcp__{서버이름}__{도구이름}
예시:
mcp__blog__create_draft
mcp__grafana__search_dashboards
mcp__playwright__browser_navigate
이중 언더스코어(__)로 서버와 도구를 구분합니다. 이 네이밍 컨벤션 덕분에 모델은 도구 이름만 보고 어떤 MCP 서버의 도구인지 알 수 있습니다.
5종 MCP 트랜스포트
Rust 포트의 mcp_client.rs에서 5가지 트랜스포트가 정의되어 있습니다.
| 트랜스포트 | 설명 | 사용 사례 |
|---|---|---|
| McpStdioTransport | stdio 프로세스 통신 | 로컬 MCP 서버 (가장 일반적) |
| McpSdkTransport | SDK 기반 | 프로그래밍 방식 연동 |
| McpRemoteTransport | 원격 서버 | 원격 MCP 서버 (HTTP/SSE) |
| McpClaudeAiProxyTransport | claude.ai 프록시 | claude.ai를 통한 MCP 접근 |
| 기타 (SSE/HTTP/WS) | 표준 프로토콜 | 다양한 네트워크 환경 |
McpClaudeAiProxyTransport가 특히 주목할 만합니다. claude.ai 웹 인터페이스를 통해 MCP에 접근할 수 있는 프록시 트랜스포트입니다. 이것은 로컬 CLI뿐 아니라 웹에서도 MCP 서버를 사용할 수 있는 경로가 설계되어 있다는 뜻입니다.
MCP stdio 서버 수명주기
가장 일반적인 stdio 트랜스포트의 수명주기가 mcp_stdio.rs에 구현되어 있습니다.
McpServerManager 수명주기:
1. 서버 시작
└── 외부 프로세스 spawn (예: node, python)
2. 초기화 핸드셰이크
└── McpInitialize 메시지 교환
└── 프로토콜 버전, 기능 협상
3. 도구 목록 로딩
└── McpListTools 호출
└── 각 도구의 JSON Schema 수신
4. 도구 호출
└── McpToolCall (JSON-RPC 프로토콜)
└── 요청 → 응답 사이클
5. 서버 종료
└── 프로세스 종료 시그널
모든 통신이 JSON-RPC 프로토콜 위에서 이루어집니다. 이것이 MCP가 언어에 구애받지 않는 이유입니다 — Node.js, Python, Rust 등 어떤 언어로 작성된 서버든, JSON-RPC를 구현하기만 하면 연결됩니다.
멀티 에이전트 — 6개 빌트인 + 팀 시스템
Claude Code의 에이전트 시스템은 아키텍처 스냅샷에서 가장 정교한 부분 중 하나입니다.
AgentTool 디렉토리 구조
tools/AgentTool/
├── AgentTool.tsx # 메인 에이전트 도구
├── UI.tsx # 에이전트 UI
├── agentColorManager.ts # 에이전트별 색상 관리
├── agentDisplay.ts # 표시 로직
├── agentMemory.ts # 에이전트 메모리
├── agentMemorySnapshot.ts # 메모리 스냅샷
├── agentToolUtils.ts # 유틸리티
├── built-in/
│ ├── claudeCodeGuideAgent.ts # Claude Code 가이드
│ ├── exploreAgent.ts # 탐색 에이전트
│ ├── generalPurposeAgent.ts # 범용 에이전트
│ ├── planAgent.ts # 계획 에이전트
│ ├── resumeAgent.ts # 재개 에이전트
│ └── verificationAgent.ts # 검증 에이전트
├── forkSubagent.ts # 서브에이전트 포크
├── runAgent.ts # 에이전트 실행
├── spawnMultiAgent.ts # 멀티 에이전트 생성
└── loadAgentsDir.ts # 에이전트 디렉토리 로딩
6개 빌트인 에이전트의 역할
| 에이전트 | 추정 역할 |
|---|---|
| generalPurposeAgent | 범용 작업 수행, 가장 일반적으로 사용 |
| exploreAgent | 코드베이스 탐색, 파일 구조 파악 |
| planAgent | 구현 전략 수립, 아키텍처 설계 |
| verificationAgent | 코드 검증, 테스트 실행, 품질 확인 |
| claudeCodeGuideAgent | Claude Code 사용법 안내 |
| resumeAgent | 이전 세션 복원, 작업 이어가기 |
실제로 Claude Code에서 Agent 도구를 사용할 때 subagent_type으로 이 에이전트들을 지정할 수 있습니다. 각 에이전트는 역할에 맞는 시스템 프롬프트와 도구 세트를 가지고 있는 것으로 추정됩니다.
에이전트 생성 패턴
forkSubagent.ts와 spawnMultiAgent.ts라는 두 가지 생성 방식이 있습니다.
forkSubagent
→ 메인 에이전트에서 단일 서브에이전트를 분기
→ 1:1 위임 패턴
→ 결과를 메인 에이전트에 반환
spawnMultiAgent
→ 여러 에이전트를 동시에 생성
→ 1:N 병렬 패턴
→ 독립적으로 실행 후 결과 수집
이것이 실제 사용에서 "하나의 Agent 도구 호출로 서브에이전트를 하나 생성"하는 것과, "여러 Agent 도구를 동시에 호출하여 병렬 작업"하는 것의 내부 구현 차이입니다.
TeamCreateTool과 TeamDeleteTool
도구 스냅샷에서 TeamCreateTool과 TeamDeleteTool이 발견됩니다. 이것은 단순히 에이전트를 하나씩 생성하는 것을 넘어, 팀 단위의 에이전트 그룹을 생성하고 관리할 수 있다는 것을 의미합니다.
3편에서 살펴본 teamMemPaths.ts와 teamMemPrompts.ts가 여기와 연결됩니다. 팀에 속한 에이전트들은 공유 메모리 경로를 통해 정보를 교환할 수 있는 구조입니다.
에이전트 시각화
agentColorManager.ts와 agentDisplay.ts의 존재는 멀티 에이전트가 동시에 작업할 때 시각적으로 구분할 수 있도록 설계되었다는 것을 보여줍니다. 각 에이전트에 고유한 색상이 할당되어, 터미널에서 어떤 에이전트가 무엇을 하고 있는지 쉽게 파악할 수 있습니다.
플러그인과 마켓플레이스
원본의 커맨드 스냅샷에서 플러그인 관련 커맨드들이 발견됩니다.
플러그인 커맨드:
- DiscoverPlugins → 플러그인 검색
- ManagePlugins → 플러그인 관리
- ManageMarketplaces → 마켓플레이스 관리
- InstallAppStep → 앱 설치 단계
- PluginSettings → 플러그인 설정
- ValidatePlugin → 플러그인 검증
- PluginTrustWarning → 신뢰 경고
- PluginErrors → 오류 처리
- install → 설치
- install-github-app → GitHub App 연동
- reload-plugins → 플러그인 리로드
이 커맨드 목록에서 읽히는 것은 완전한 플러그인 생태계가 설계되어 있다는 것입니다.
- 마켓플레이스: 플러그인을 검색하고 설치할 수 있는 중앙 저장소
- GitHub App 연동: GitHub App으로 플러그인을 설치하는 경로
- 신뢰 검증:
PluginTrustWarning,ValidatePlugin으로 보안 검증 - 설정 관리: 플러그인별 설정 UI
현재 사용자에게 공개된 플러그인 기능은 제한적이지만, 내부적으로는 VS Code 확장 마켓플레이스와 유사한 수준의 인프라가 준비되어 있었다는 것을 알 수 있습니다.
원격 실행과 다중 환경
1편의 부트스트랩 6단계에서 다뤘던 모드 라우팅을 다시 살펴보면:
실행 모드:
- local → 기본 (로컬 터미널)
- remote → 원격 서버
- ssh → SSH 접속
- teleport → (미상)
- direct-connect → 직접 연결
- deep-link → 딥링크
remote/ 서브시스템(4개 모듈)에서 RemoteSessionManager.ts와 WebSocket 기반 원격 통신이 구현되어 있습니다.
이 설계는 Claude Code가 "어디서든 실행될 수 있는" 에이전트를 지향한다는 것을 보여줍니다. 로컬 터미널에서만 쓰는 것이 아니라, 원격 서버, SSH 세션, 그리고 아직 정체가 불분명한 "텔레포트" 환경에서도 동작할 수 있는 구조입니다.
모델 마이그레이션 — 코드네임의 역사
1편에서 간략히 언급했던 마이그레이션 파일들을 좀 더 깊이 살펴보겠습니다. migrations/ 서브시스템의 11개 모듈은 Claude Code가 거쳐온 모델 변경의 역사를 기록하고 있습니다.
마이그레이션 경로:
fennec → opus
└── "Fennec"이 Opus 모델의 개발 코드네임이었을 가능성
opus → opus1m
└── 1M 컨텍스트 윈도우로 확장
sonnet1m → sonnet45
└── Sonnet 4.5 출시
sonnet45 → sonnet46
└── Sonnet 4.6 출시
이 마이그레이션이 존재한다는 것은, Claude Code가 모델이 바뀔 때 단순히 모델 이름만 바꾸는 것이 아니라 설정, 프롬프트, 동작 방식도 함께 마이그레이션한다는 뜻입니다. 새 모델의 특성(컨텍스트 크기, 가격, 능력)에 맞게 내부 설정을 자동으로 조정하는 것입니다.
전체 아키텍처 조합도
4편에 걸쳐 분석한 내용을 하나의 그림으로 조합하면 이렇게 됩니다.
┌─────────────────────────────────────────────────────┐
│ 사용자 입력 │
└──────────────────────┬──────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ CLI / Bridge / Remote │
│ (SSE, WebSocket, Hybrid, DirectConnect, DeepLink) │
└──────────────────────┬──────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 부트스트랩 (7단계) │
│ 프리페치 → 환경가드 → 신뢰게이트 → 설정로딩 │
│ → 지연초기화 → 모드라우팅 → 루프진입 │
└──────────────────────┬──────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 에이전틱 루프 (ConversationRuntime) │
│ ┌───────────────────────────────────────────────┐ │
│ │ API 호출 → tool_use 추출 → 도구 실행 → 반복 │ │
│ └───────────────────────────────────────────────┘ │
│ │
│ 도구 184개 │ 권한 5단계 │ Hook │ 비용추적 │
│ 메모리 4계층 │ 컨텍스트 압축 @200K │ TODO 보존 │
│ 멀티에이전트 (fork/spawn/team) │ 6개 빌트인 │
└──────────────────────┬──────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 외부 연결 │
│ MCP (5종 트랜스포트) │ 플러그인 마켓플레이스 │
│ IDE Bridge (31모듈) │ 원격 실행 (6개 모드) │
└─────────────────────────────────────────────────────┘
시리즈를 마치며 — 설계 철학의 발견
4편에 걸쳐 Claude Code의 아키텍처를 분석하면서, 몇 가지 설계 철학이 일관되게 드러났습니다.
"자율성과 안전성의 공존"
에이전틱 루프는 usize::MAX 반복으로 최대한의 자율성을 부여하면서도, 5단계 권한 모델과 Hook 시스템으로 안전장치를 촘촘하게 갖추고 있습니다. "최대한 자율적으로 동작하되, 위험한 순간에는 반드시 사람의 판단을 받는다"는 원칙이 코드 곳곳에 스며있습니다.
"도구로 추상화한다"
파일 읽기, 웹 검색, 에이전트 생성, MCP 호출 — 모든 것이 도구라는 단일 인터페이스로 추상화됩니다. 에이전틱 루프 입장에서는 read_file이든 mcp__grafana__query_prometheus이든 같은 방식으로 호출하고 결과를 받습니다. 이 균일한 추상화가 확장성의 비결입니다.
"적절한 범위에 적절한 수명을"
4계층 메모리 시스템이 이를 보여줍니다. 모든 것을 영구적으로 저장하지도, 모든 것을 세션과 함께 버리지도 않습니다. 프로젝트 지침은 영구적으로, 학습한 패턴은 세션 간에, 작업 컨텍스트는 세션 내에, 에이전트 상태는 에이전트 내에 — 각 정보의 성격에 맞는 수명을 부여합니다.
"연결의 허브"
Bridge(31개 모듈), MCP(5종 트랜스포트), 3종 CLI 트랜스포트, 플러그인 마켓플레이스, 원격 실행 모드 — Claude Code는 단독 CLI가 아니라 다양한 환경과 연결되는 허브입니다. 512,000줄 중 상당 부분이 이 "연결"을 위한 코드입니다.
사용자로서의 감상
매일 Claude Code를 사용하면서 느끼던 여러 가지 — "왜 이건 물어보고 저건 안 물어보지?", "MCP를 많이 연결하면 왜 느려지지?", "컨텍스트가 압축되는데 왜 맥락을 잘 기억하지?", "서브에이전트는 왜 독립적으로 동작하지?" — 이런 질문들의 답이 이 아키텍처 안에 있었습니다.
도구를 잘 사용하려면 도구의 작동 원리를 이해하는 것이 도움됩니다. 이 시리즈가 Claude Code를 더 잘 활용하는 데 작은 도움이 되었으면 합니다.
시리즈 안내
1편: 512,000줄의 전체 조감도
2편: 에이전틱 루프 — 도구, 권한, 훅의 삼중주
3편: 메모리와 컨텍스트 — 잊지 않는 AI의 비밀
4편: Bridge, MCP, 멀티 에이전트 — 단순 CLI를 넘어서 (현재 글)
참고
이 시리즈는 claw-code 프로젝트의 reference_data(아키텍처 스냅샷)와 Python/Rust 재작성 코드를 기반으로 분석했습니다. 유출 시점(v2.1.88, 2026-03-31)의 스냅샷이므로 현재 Claude Code 버전과 차이가 있을 수 있습니다.
관련 글
Claude Code 소스 유출이 드러낸 아키텍처 — 1편: 512,000줄의 전체 조감도
2026년 3월 31일, npm 패키징 실수로 Claude Code의 TypeScript 소스 512,000줄이 유출되었습니다. 1,902개 파일, 34개 서브시스템, 207개 커맨드, 184개 도구 — 이 숫자들이 말해주는 AI 코딩 에이전트의 내부 구조를 조감도로 살펴봅니다.
Claude Code 소스 유출이 드러낸 아키텍처 — 2편: 에이전틱 루프, 도구, 권한의 삼중주
Claude Code의 심장은 ConversationRuntime의 무한 에이전틱 루프입니다. 184개 도구를 손과 발로, 5단계 권한 모델을 안전장치로, Hook 시스템을 감시자로 — 이 세 가지가 어떻게 맞물려 자율 에이전트를 구현하는지 살펴봅니다.
Claude Code 소스 유출이 드러낸 아키텍처 — 3편: 메모리와 컨텍스트 압축
AI 에이전트가 장시간 작업할 때 가장 큰 적은 컨텍스트 한계입니다. Claude Code는 4계층 메모리, 200K 토큰 자동 압축, 자기 치유 메모리, 지연 로딩이라는 네 가지 전략으로 이 문제를 해결합니다.