Grok Build 소스코드 강의 · 12 / 20

MCP: 연결은 시작일 뿐입니다

실제 클라이언트는 설정 병합, OAuth, 기능 탐색, 네임스페이스 격리, 모델 가시성 제어, 상태 푸시, 연결 복구까지 처리해야 합니다. 소스코드는 이 책임을 MCP crate와 Session Actor 주변에 분산시킵니다.

Client Rolestdio / Streamable HTTPOAuthserver__tool50ms 상태 병합
01 / OBJECTIVES

학습 목표

프로토콜 역할 확인

호출 방향으로 클라이언트와 서버를 구분하고, 내부 Hub Server를 MCP Server와 동일시하는 오류를 방지합니다.

가시성 추적

도구가 tools/list에서 스냅샷, 검색 인덱스, 모델 레지스트리로 어떻게 흘러가는지 설명합니다.

복구 상태 머신 설계

OAuth, 상태 병합, 클라이언트 ID, 재시작 백오프를 단일 연결 생명주기에 배치합니다.

02 / CORE VISUAL

외부 서버에서 모델 도구까지

03 / ROLE CHECK

클라이언트와 서버: 소스코드 기준으로 역할 확정

SOURCE CONFIRMEDGrok Build은 MCP 클라이언트입니다

McpClient는 stdio 또는 Streamable HTTP 연결을 시작하고 초기화, list_tools, call_tool을 수행합니다. Computer Hub MCP Adapter 역시 MCP Server의 도구를 Hub 라우팅으로 브리징하는 것으로 설명됩니다.

NOT ESTABLISHED범용 MCP 서버 역할에 대한 소스 근거 없음

xai-grok-workspace의 Hub Server는 xAI Computer Hub 프로토콜에 속합니다. 현재 스냅샷에서 Grok Build 자체를 MCP 전송으로 임의의 MCP 클라이언트에 노출하는 진입점을 발견하지 못했으므로, 이 강의는 클라이언트 역할만 확인합니다.

04 / OAUTH

OAuth와 실제 자격증명 저장 위치

1 · 재사용 또는 갱신디스크 자격증명 읽기 후 token refresh 시도
2 · 브라우저 인증대화형 처리 필요 시 사용자 동의 흐름 시작
3 · 콜백 토큰 교환인증 코드를 액세스·갱신 토큰으로 교환
4 · 잠금 후 쓰기파일 잠금 + 원자적 저장으로 다중 프로세스 지원
CONFIG TYPES

설정 필드

oauth_client_id
oauth_client_secret_env_var
oauth_scopes
crates/codegen/xai-grok-config-types/src/mcp.rs
CREDENTIAL STORE

로컬 JSON 파일

let path = grok_home
    .join("mcp_credentials.json");
// lock + load + insert + atomic save

소스코드는 이 파일에 자격증명을 저장하며, 파일 잠금과 원자적 저장으로 동시 쓰기를 처리합니다.

crates/codegen/xai-grok-mcp/src/credentials.rs · oauth.rs
05 / VISIBILITY

도구가 모델에 가시화되는 방법

NAMESPACE

server__tool

등록명은 서버명, 예약 구분자 __, 원래 도구명으로 구성됩니다. 소스코드는 전체 이름에 구분자가 정확히 한 번만 나타나도록 요구하여 파싱 모호성을 방지하고, 두 서버의 동명 도구가 서로 다른 ToolId를 갖도록 합니다.

crates/codegen/xai-grok-mcp/src/servers.rs: into_registration
TWO AUDIENCES

모델 도구 vs. 앱 도구 분리

비활성화된 도구는 disabled_tool_registrations에 저장됩니다. model_visible이 true인 도구만 모델 측 Tool Bridge에 진입하고, ui.resourceUri가 있는 도구는 UI 알림으로 별도 라우팅될 수 있습니다.

crates/codegen/xai-grok-shell/src/session/acp_session_impl/mcp.rs
SEARCH SNAPSHOT

대규모 MCP 도구를 Prompt에 상시 포함할 필요는 없습니다

ToolMetadataSnapshot은 도구 및 서버 메타데이터를 저장합니다. BM25 인덱스는 qualified name 또는 도구명으로 정확히 매칭한 후 검색 결과를 반환합니다. mcp_initialized는 기능 탐색 완료 여부를 검색 레이어에 알립니다.

pub struct ToolMetadataSnapshot {
    pub tools: Vec<ToolMetadata>,
    pub servers: Vec<ServerMetadata>,
    pub mcp_initialized: bool,
}
crates/codegen/xai-grok-shell/src/session/tool_index.rs
06 / RECOVERY

상태 병합과 재시작 보호

Initializing핸드셰이크 시작
Ready기능 사용 가능
NeedsAuth인증 대기 중
Unavailable연결 끊김
Disabled설정으로 비활성화
50 MS COALESCE

동일 키에서 최신 이벤트만 유지

mcp_dispatcher(server_name, event_kind)를 키로 50ms tumbling window 내에서 last-write-wins를 적용합니다. 고빈도 tools/list_changed 이벤트는 최종적으로 ACP 상태를 한 번만 푸시합니다.

IDENTITY GUARD

오래된 연결 끊김이 새 연결을 삭제하지 못하도록

dead client 제거 전 client_id를 비교합니다. 연결 끊김 이벤트가 이미 교체된 이전 클라이언트에 속하면 현재 클라이언트를 유지하고 오래된 상태를 폐기합니다.

RESTART POLICY

전송 방식에 따라 다른 복구 동작

stdio 자동 재시작은 고정 백오프 1s → 4s → 16s를 사용하며 종료 중, 비활성화, 설정 제거 등의 가드를 확인합니다. HTTP는 클라이언트 내 복구를 먼저 시도하며 독립적인 백오프를 사용합니다. 재연결 성공 후 도구를 재탐색·재등록하고 스냅샷을 갱신합니다.

crates/codegen/xai-grok-shell/src/session/mcp_dispatcher.rs · mcp_restart.rs · acp_session_impl/mcp_snapshot.rs
07 / LAB

실습: 복구 가능한 클라이언트 설계하기

30 MIN

제출물
상태 다이어그램 + 6개 테스트

  1. 설정 로딩, 연결, OAuth, 기능 탐색, 등록, 검색, 호출을 포함하는 상태 다이어그램을 그리세요.
  2. disabled, app-only, model-visible 세 가지 도구 경로를 추가하세요.
  3. 이름이 같은 두 도구를 설계하고 qualified name으로 충돌을 해결할 수 있음을 검증하세요.
  4. tools/list_changed 이벤트 100개를 시뮬레이션하고 50ms 병합 후 예상 알림 수를 적으세요.
  5. 오래된 클라이언트 연결 끊김 이벤트가 늦게 도착하는 상황을 시뮬레이션하고, client_id 가드가 새 연결을 어떻게 보호하는지 설명하세요.
  6. stdio와 HTTP 각각에 대해 복구 가능한 테스트 하나와 재시도 중단 조건 하나를 작성하세요.
Takeaway

MCP 통합의 엔지니어링 부담은 프로토콜 주변부에 집중됩니다. 네이밍, 가시성, ID, 상태 병합, 복구 전략이 함께 결정하는 것은 연결이 장기적으로 안정적으로 작동할 수 있는지 여부입니다.

소스코드 스냅샷 참고:이 페이지는 로컬 grok-build-main의 MCP, config-types, shell session, computer-hub adapter 소스코드를 기반으로 정리되었습니다. 코드 조각은 교육용으로 발췌한 것입니다. MCP 서버 역할에 관한 결론은 보수적 기준으로 적용되며, 내부 Hub Server는 범용 MCP Server의 증거로 보지 않습니다.