MCP 서버를 직접 구현하면서 — 가이드에 없는 5가지

MCP 서버 구현의 *공식 가이드* 가 다루는 곳 + *실전에서 만난 5가지* — JSON-RPC 변환, 권한 분기, error semantics, lifecycle, 격리.

백재민
백재민
CollabOps 창업자
MCP 서버를 직접 구현하면서 — 가이드에 없는 5가지

MCP 서버를 구현해 본 적 있다면, 공식 가이드는 툴 정의 → 서버 부팅 → 연결 검증 까지 잘 안내한다. 그 후 프로덕션 배포 까지의 5가지 가 가이드에 없다.

이 글은 우리가 부딪힌 5가지의 실측 노트.

1 — JSON-RPC 의 변환 함정

MCP 는 JSON-RPC 2.0 위에 박혀 있다. 가이드는 JSON-RPC 사용을 전제. 하지만 우리 내부 RPC 가 gRPC 였음. 변환 layer 가 필요했고, 그 layer 의 세부 행동 이 까다로움.

가장 자주 깨지는 패턴:

  • streaming response — JSON-RPC 는 single response 가정. MCP 는 progress notification 으로 streaming 흉내. gRPC streaming 과 매핑 정확히 안 됨
  • cancellation — 클라이언트가 cancel 하면 progress 중단 + cleanup. JSON-RPC native 지원 X — 별도 cancel notification
  • binary 데이터 — JSON 안에서 base64 encode 필요. 큰 binary (이미지, 파일) 는 별도 transport 권장

2 — 권한 분기는 서버 단 아니라 툴 단

가이드는 서버모든 클라이언트에 모든 툴 노출 가정. 실전에서는 *같은 서버 * 가 서로 다른 권한 클라이언트부분적 툴 노출.

해결: 매 호출마다 (client, tool, args) 를 권한 평가. 우리 그래프 권한 모델이 그대로 적용. → 권한 모델을 그래프 위로

호출 수신 →
  client identity 검증 →
  tool 호출이 client 의 권한에 있는가 →
  args 가 client 의 scope 안인가 →
  실행

이 분기를 서버 코드 안에 박지 않으면 모든 호출이 같은 권한 — 보안 위험.

3 — Error semantics — JSON-RPC 코드 + MCP 의미

JSON-RPC 표준 error code (-32600 ~ -32099) + MCP 가 정의한 추가 error 종류 + 우리 도메인 error.

함정 — JSON-RPC error 만 표준화돼 있고, MCP 의 도메인 error 는 어떻게 표현할지 모호.

우리 답:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32000,                          // JSON-RPC server-defined error
    "message": "Authorization failed",
    "data": {
      "type": "mcp.authorization.denied",     // 우리 의미
      "tool": "deploy.production",
      "reason": "missing scope: prod.deploy",
      "audit_id": "audit-xyz"                 // 감사 추적용
    }
  }
}

data 안에 우리 도메인 error 의미 박음. 클라이언트가 이걸 사용해 사용자에게 정확한 메시지 표시.

4 — 서버 lifecycle

가이드 — initialize → use → terminate. 실전 — 연결이 자주 끊기고 다시 연결. 클라이언트는 상태 유지 가정, 서버는 stateless 가정. 충돌.

해결: 서버 측 세션 store 를 별도. 클라이언트의 reconnect 시 세션 ID 로 복원. 세션 안에 현재 도구 사용 권한 / 진행 중 작업 / 컨텍스트 캐시 박음.

세션 만료는 idle 30분 default. active 한 동안은 무한.

5 — 격리 — 한 클라이언트가 다른 클라이언트 영향 X

여러 클라이언트가 동시에 같은 서버 사용. 하나가 long-running tool 호출 중일 때, 다른 빠른 호출block 안 되어야.

가이드 — 동시성 전혀 다루지 않음.

우리 답:

  • 각 클라이언트의 호출을 별도 worker pool
  • 한 클라이언트의 long-running 호출은 그 클라이언트의 다음 호출만 block
  • 전역 자원 (DB connection, external API) 은 별도 rate limit 적용

이 격리 없이는 한 사용자의 무거운 요청이 전체 서비스 장애 로 확장.

5 가지 후 알게 된 것

위 5 가지를 모두 다루지 않은 MCP 서버는 PoC 환경 에서는 동작하지만, 프로덕션 배포 후 1~3개월 안에 사고가 난다. 사고 패턴은 우리가 본 것 그대로 — 권한 누수, error 해석 불가, 세션 손실, 격리 깨짐.

MCP 서버의 공식 가이드시작하기 위한 가이드지 프로덕션을 위한 가이드가 아니다.

누가 이 글을 읽으면 좋은가

지금 MCP 서버 직접 구현 또는 MCP-기반 에이전트 인프라 를 짜는 모든 팀. 위 5가지 중 2~3개 의 답이 처음부터 명시적으로 박혀 있으면 3~6개월의 재작업 을 피할 수 있다.

태그#mcp#ai-agent#protocol#implementation#devops