Capstone 13 — 레지스트리(Registry)와 거버넌스(Governance)를 갖춘 모델 컨텍스트 프로토콜(MCP) 서버

모델 컨텍스트 프로토콜(Model Context Protocol; MCP)은 더 이상 미래가 아니라, 2026년의 기본 도구 사용(tool-use) 명세(spec)가 되었습니다. Anthropic, OpenAI, Google과 주요 통합 개발 환경(IDE)이 모두 MCP 클라이언트(client)를 탑재해 출하합니다. Pinterest는 내부 MCP 서버 생태계(ecosystem)를 공개했고, AAIF 레지스트리(Registry)는 .well-known 위치에 두는 기능 메타데이터(capability metadata)를 표준화(formalize)했습니다. AWS ECS는 무상태(stateless) 배포 참조 구성을 공개했으며, Block의 goose-agent는 동일한 프로토콜(protocol)을 호스팅(hosted) 어시스턴트 내부로 가져왔습니다. 2026년의 프로덕션(production) 형태는 스트리머블 HTTP(StreamableHTTP) 전송(transport), OAuth 2.1 스코프(scope), OPA 정책(policy) 게이팅, 그리고 플랫폼 팀이 서버를 발견하고 검증하고 활성화할 수 있도록 돕는 레지스트리로 거의 정착되었습니다. 이 캡스톤(capstone)은 그 구조를 처음부터 끝까지(end-to-end) 만들어 보는 작업입니다.

유형: Capstone 언어: Python(서버, FastMCP 사용) 또는 TypeScript(@modelcontextprotocol/sdk), Go(레지스트리 서비스) 선수 지식: Phase 11(LLM 엔지니어링), Phase 13(도구와 MCP), Phase 14(에이전트), Phase 17(인프라), Phase 18(안전성) 활용되는 Phase: P11 · P13 · P14 · P17 · P18 예상 시간: 약 25시간

문제

MCP는 2026년 도구 사용의 공용어(lingua franca)가 되었습니다. Claude Code, Cursor 3, Amp, OpenCode, Gemini CLI 그리고 모든 관리형(managed) 에이전트(agent)가 이제 MCP 서버를 소비합니다. 프로덕션에서 어려운 점은 서버를 작성하는 일이 아닙니다. FastMCP 덕분에 서버를 만드는 일 자체는 쉬워졌습니다. 진짜 까다로운 부분은 엔터프라이즈 요구사항(enterprise requirement)을 만족시키며 대규모로 배포하는 일입니다. 테넌트(tenant)별 OAuth 스코프, 파괴적(destructive) 도구에 적용되는 OPA 정책, 스트리머블 HTTP 무상태 확장(stateless scaling), 발견(discovery)을 위한 레지스트리, 그리고 도구 호출별 감사 로그(audit log)가 모두 필요합니다. Pinterest의 내부 MCP 생태계와 AAIF 레지스트리 명세가 2026년의 기준선을 세웠습니다.

이 캡스톤에서는 10개의 사내(internal) 도구(Postgres 읽기 전용, S3 목록 조회, Jira, Linear, Datadog 등)를 제공하는 MCP 서버, 플랫폼 발견을 위한 레지스트리 사용자 인터페이스(UI), 파괴적 도구를 위한 사람 승인(human-approval) 게이트를 만듭니다. 부하 시험(load test)으로는 스트리머블 HTTP의 수평 확장(horizontal scaling)을 입증해야 하며, 감사 트레일(audit trail)은 엔터프라이즈 보안 검토를 통과할 수 있어야 합니다.

사전 테스트

2문제 · 이 강의를 시작하기 전에 얼마나 알고 있는지 확인해보세요

1.2026 MCP 개정판(revision)이 기존 stdio + SSE 조합 대신 스트리머블 HTTP(StreamableHTTP)를 기본 전송으로 의무화하는 이유는 무엇인가요?

2..well-known/mcp-capabilities 매니페스트(manifest)의 목적은 무엇인가요?

0/2 답변 완료

개념

MCP 2026 리비전(revision)은 스트리머블 HTTP를 기본 전송으로 의무화합니다. 이전의 stdio + SSE 조합과 달리 스트리머블 HTTP는 기본적으로 무상태입니다. 하나의 HTTP 엔드포인트(endpoint)가 JSON-RPC 요청(request)을 받고, 응답(response)을 스트리밍하며, 알림(notification)을 위한 장기 연결(long-lived connection)도 함께 지원합니다. 무상태라는 점은 로드 밸런서(load balancer) 뒤에서 수평 확장이 가능하다는 뜻입니다.

인가(authorization)는 도구별 스코프를 가진 OAuth 2.1로 처리합니다. 토큰(token)에는 jira:read, s3:list, postgres:query:readonly 같은 스코프가 담깁니다. MCP 서버는 세션(session) 시작 시점이 아니라 도구 호출(tool call) 시점마다 스코프를 점검합니다. 고위험 도구의 경우, 최근 N분 안에 approved:by:human으로 격상(elevate)되지 않은 스코프의 호출은 거부합니다. 이 격상은 슬랙(Slack) 검토 카드를 통해 이루어집니다.

레지스트리는 별도의 서비스(service)입니다. 모든 MCP 서버는 도구 매니페스트(tool manifest), 전송 URL, 인증 요구사항(auth requirement)을 담은 .well-known/mcp-capabilities 문서를 노출합니다. 레지스트리는 이 문서들을 폴링(polling)으로 가져와 검증하고 색인합니다. 플랫폼 팀은 레지스트리 UI에서 어떤 도구를 쓸 수 있는지, 어떤 스코프가 필요한지, 어느 팀이 소유하는지를 확인합니다.

아키텍처

MCP client (Claude Code, Cursor 3, ...)
          |
          v
StreamableHTTP over HTTPS (JSON-RPC + streaming)
          |
          v
MCP server (FastMCP) behind load balancer
          |
   +------+------+---------+----------+------------+
   v             v         v          v            v
Postgres    S3 listing  Jira       Linear     Datadog
(read-only) (paged)     (read)     (read)     (query)
          |
   +------+-------------+
   v                    v
 OPA policy gate   destructive tool MCP (separate server)
                        |
                        v
                   human approval via Slack
                        |
                        v
                   audit log (append-only, per-tenant)

  registry service
     |
     v  GET /.well-known/mcp-capabilities from each server
     v
     UI: search / validate / enable-disable / ownership

스택

  • 서버 프레임워크(server framework): Python은 FastMCP, TypeScript는 @modelcontextprotocol/sdk를 사용합니다.
  • 전송(transport): HTTPS 위에 올린 스트리머블 HTTP(StreamableHTTP)를 사용하며 무상태로 운영합니다.
  • 인증(auth): OAuth 2.1과 SPIFFE / SPIRE 기반 워크로드 아이덴티티(workload identity)를 사용합니다.
  • 정책(policy): 도구별 OPA / Rego 규칙과 요청마다 호출되는 정책 결정 서비스(policy decision service)를 사용합니다.
  • 레지스트리(registry): 자체 호스팅(self-hosted)으로 운영하며 .well-known/mcp-capabilities 매니페스트를 소비합니다.
  • 사람 승인(human approval): 파괴적 도구에는 슬랙 인터랙티브 메시지(Slack interactive message)를 사용합니다.
  • 배포(deployment): AWS ECS Fargate 또는 Fly.io 위에 올리고, 테넌트별 서버 또는 테넌트 스코핑(tenant scoping)이 적용된 공용 서버 형태로 운영합니다.
  • 감사(audit): 테넌트별 버킷(bucket)에 구조화된 JSONL을 추가 전용(append-only)으로 적재하고, 호출별 계보(per-call lineage)를 기록합니다.

직접 만들기

  1. 도구 표면(tool surface) 정의. 10개의 사내 도구를 노출합니다. Postgres 읽기 전용 쿼리, S3 객체 목록 조회, Jira 검색·조회, Linear 검색·조회, Datadog 지표 쿼리, PagerDuty 온콜(on-call) 조회, GitHub 읽기 전용, Notion 검색, Slack 검색, Salesforce 읽기를 포함합니다. 각 도구는 타입을 가진 스키마(typed schema)와 스코프 라벨(scope label)을 가집니다.

  2. FastMCP 서버. 도구를 마운트(mount)합니다. 스트리머블 HTTP 전송을 구성하고, OAuth 토큰 인트로스펙션(token introspection)과 스코프 강제(scope enforcement)를 위한 미들웨어(middleware)를 추가합니다.

  3. OPA 정책. 도구별 Rego 정책을 작성합니다. 어떤 스코프가 호출을 허용하는지, 어떤 개인 식별 정보(Personally Identifiable Information; PII) 익명화(redaction)를 적용하는지, 어떤 페이로드 크기 상한(payload-size cap)을 적용하는지 정의합니다. 모든 도구 호출마다 결정 서비스(decision service)를 호출합니다.

  4. 레지스트리 서비스. Go 또는 TypeScript로 별도의 서비스를 구현합니다. 등록된 서버의 .well-known/mcp-capabilities를 폴링으로 가져와 JSON 스키마(JSON Schema)로 검증하고, 목록(list) · 검색(search) · 검증(validate) · 활성화/비활성화(enable-disable) UI를 제공합니다.

  5. 기능 매니페스트(capability manifest). 각 서버는 .well-known/mcp-capabilities를 노출합니다. 이 문서에는 도구 목록, 인증 요구사항, 전송 URL, 소유 팀(owner team), 서비스 수준 목표(SLO)가 포함됩니다.

  6. 파괴적 도구 분리. Jira 이슈 생성, Linear 이슈 생성, Postgres 쓰기처럼 상태(state)를 변경하는 도구는 별도의 두 번째 MCP 서버에 둡니다. 더 엄격한 인증 흐름(auth flow)을 적용하고, 토큰은 15분 이내에 슬랙 카드(Slack card)로 격상된 approved:by:human 스코프를 함께 가져야 합니다.

  7. 감사 로그(audit log). 테넌트별로 추가 전용 JSONL을 남깁니다. 형식은 {timestamp, user, tool, args_redacted, response_redacted, outcome}입니다. 기록 전에 Presidio로 PII를 익명화합니다.

  8. 부하 시험(load test). 스트리머블 HTTP 위에서 100개의 동시 클라이언트(concurrent client)를 띄웁니다. 두 번째 레플리카(replica)를 추가했을 때 세션 고정(session stickiness) 없이 로드 밸런서가 트래픽을 재분배하는 모습을 보여 줍니다.

  9. 적합성 시험(conformance tests). 공식 MCP 적합성 테스트 묶음(conformance suite)을 두 서버 모두에 대해 실행합니다. 모든 필수(mandatory) 항목을 통과해야 합니다.

사용해보기

$ curl -H "Authorization: Bearer eyJhbGc..." \
       -X POST https://mcp.internal.example.com/ \
       -d '{"jsonrpc":"2.0","method":"tools/call",
            "params":{"name":"postgres.readonly","arguments":{"sql":"SELECT 1"}}}'
[registry]  기능 검증 완료: postgres.readonly v1.2
[policy]    스코프 postgres:query:readonly 존재 — 허용
[audit]     기록됨: user=u42 tool=postgres.readonly outcome=ok
response:   { "result": { "rows": [[1]] } }

산출물 만들기

outputs/skill-mcp-server.md가 제출 산출물의 형태를 정의합니다. 사내 도구를 위한 프로덕션급 MCP 서버와 레지스트리, 감사 계층(audit layer)을 OAuth 2.1 스코프와 OPA 게이팅 위에서 만들어 내는 것이 목표입니다.

가중치평가 항목측정 방법
25명세 적합성(Spec conformance)스트리머블 HTTP 전송과 기능 매니페스트가 MCP 적합성 테스트를 통과
20보안(Security)모든 도구에 대한 스코프 강제, OPA 적용 범위, 비밀(secret) 위생
20관측 가능성(Observability)PII 익명화가 적용된 도구 호출별 감사 로그
20확장(Scale)100 클라이언트 부하 시험에서 수평 확장 시연
15레지스트리 사용자 경험(Registry UX)발견 / 검증 / 활성화-비활성화 워크플로 시연
100

연습문제

  1. (쉬움) 새 도구로 Confluence 검색을 추가합니다. 코어 서버를 손대지 않고 레지스트리 검증 흐름을 통해 배포되도록 만듭니다.

  2. (중간) email, ssn, phone이라는 이름의 컬럼(column)이 Postgres 쿼리 결과에 포함될 때 그 값을 익명화하는 OPA 정책을 작성합니다. 시험용 프로브 쿼리(probe query)로 동작을 확인합니다.

  3. (중간) 스트리머블 HTTP와 stdio를 로컬 지연 시간(latency) 관점에서 벤치마크합니다. 호출별 p50과 p95 값을 보고합니다.

  4. (어려움) 테넌트별 쿼터(quota)를 구현합니다. 도구별, 테넌트별로 분당 최대 N개의 호출만 허용하고, 두 번째 OPA 규칙으로 강제합니다.

  5. (어려움) mcp-conformance-tests의 MCP 적합성 테스트 묶음을 실행하고, 발생하는 모든 실패(failure)를 수정합니다.

핵심 용어

용어흔한 설명실제 의미
스트리머블 HTTP(StreamableHTTP)"2026 MCP 전송 방식"무상태 HTTP에 스트리밍을 결합한 전송이며, 네트워크 상의 서버에서는 SSE와 stdio를 대체한다.
기능 매니페스트(capability manifest)"Well-known 문서"도구 목록, 인증, 전송 URL을 담은 .well-known/mcp-capabilities 문서이다.
OPA / Rego"정책 엔진(policy engine)"외부 규칙을 기준으로 도구 호출의 허용 여부를 판단하는 오픈 폴리시 에이전트(Open Policy Agent)이다.
스코프 격상(scope elevation)"사람 승인(approved-by-human)"슬랙 승인 절차로 짧은 시간만 부여되는 스코프이며, 파괴적 도구에 요구된다.
레지스트리(registry)"도구 발견(tool discovery)"MCP 서버의 기능 매니페스트를 색인하는 서비스이다.
워크로드 아이덴티티(workload identity)"SPIFFE / SPIRE"OAuth 토큰 발급을 위한 암호학적 서비스 아이덴티티이다.
적합성 테스트 묶음(conformance suite)"명세 테스트(spec test)"스트리머블 HTTP 전송과 도구 매니페스트의 정확성을 검증하는 공식 MCP 테스트 묶음이다.

더 읽을거리

실습 코드

이 강의의 실습 코드 1개

main
Code

산출물

이 강의에서 생성된 프롬프트, 스킬, 코드 산출물 1개

mcp-server-platform

Deploy a production MCP server with StreamableHTTP, OAuth 2.1 scopes, OPA policy, human-approval gate for destructive tools, and a registry for discovery.

Skill

확인 문제

3문제 · 모두 맞추면 완료 표시가 가능합니다

1.파괴적 도구(Jira 생성, Postgres 쓰기)는 더 엄격한 인증이 적용된 별도의 MCP 서버에 있습니다. 같은 서버에서 권한 플래그를 사용하지 않고 분리하는 이유는 무엇인가요?

2.감사 로그(audit log)는 호출별로 {timestamp, user, tool, args_redacted, response_redacted, outcome}을 기록합니다. 로깅 전에 인수와 응답을 Presidio로 익명화(redact)하는 이유는 무엇인가요?

3.부하 시험은 스트리머블 HTTP를 통해 100개의 동시 클라이언트를 실행합니다. 두 번째 레플리카를 추가하면 세션 고정 없이 트래픽을 분배합니다. 세션 고정 없는 확장이 MCP 서버에 중요한 이유는 무엇인가요?

0/3 답변 완료

추가 문제 풀기

AI가 강의 내용을 바탕으로 새로운 문제를 생성합니다