본문 바로가기
일반IT/AI

MCP 서버는 실제로 어떻게 통신할까 — JSON-RPC, stdio, Streamable HTTP를 로우레벨에서 이해하기

by gasbugs 2026. 7. 30.

ChatGPT나 Claude 같은 AI 애플리케이션에 파일 시스템, 데이터베이스, 사내 API를 연결할 때 MCP 서버라는 말을 자주 듣습니다. 이름에 ‘프로토콜’이 들어가니 TCP나 HTTP를 대체하는 새로운 네트워크 규격처럼 보이기도 하고, REST API에 도구 목록만 붙인 것처럼 느껴지기도 합니다.

 

정확히 말하면 MCP(Model Context Protocol)는 AI 애플리케이션과 외부 기능 사이의 애플리케이션 계층 RPC 규약입니다. 전송에는 기존 운영 환경에서 익숙한 프로세스 표준 입출력이나 HTTP를 사용하고, 메시지 봉투는 JSON-RPC 2.0, 도구의 입력·출력 계약은 JSON Schema를 사용합니다.

 

이 글은 2026년 7월 28일 공개된 최신 안정 사양을 기준으로 MCP 서버의 역할, 실제 바이트 스트림, HTTP 헤더와 본문, SSE 응답, 스키마 표준, 인증, 오류 처리까지 기존 IT 인력이 패킷 흐름을 그릴 수 있는 수준으로 정리합니다.

그림: MCP의 메시지 계층과 전송 계층을 분리해 본 구조

먼저 결론: MCP는 무엇이고 무엇이 아닌가

MCP를 기존 기술에 대입하면 다음과 같이 정리할 수 있습니다.

질문 정확한 답
MCP가 HTTP를 대체하는가 아니다. 원격 전송에서 HTTP를 사용한다.
MCP 자체 데이터 포맷이 있는가 있다. JSON-RPC 2.0 봉투 안에 MCP가 정의한 method, params, result, _meta를 넣는다.
직렬화 형식은 무엇인가 UTF-8 JSON이다. 이미지·오디오는 JSON 안에 MIME type과 Base64 데이터로 담을 수 있다.
입력 파라미터 규격은 무엇인가 JSON Schema이며, $schema가 없으면 2020-12를 기본 dialect로 본다.
WebSocket이 필요한가 아니다. 표준 전송은 stdio와 Streamable HTTP다. WebSocket은 별도 custom transport를 만들 때 선택할 수 있을 뿐이다.
REST API인가 아니다. 리소스 중심 HTTP API가 아니라 tools/list, tools/call 같은 메서드를 호출하는 RPC다.
gRPC와 같은가 목적은 일부 비슷하지만 Protobuf 바이너리와 HTTP/2 스트림을 강제하지 않는다.
MCP 서버가 LLM인가 아니다. LLM이 호출할 도구·리소스·프롬프트를 노출하는 어댑터 또는 서비스다.

중요한 구분은 데이터 계층과 전송 계층입니다.

MCP 데이터 계층
  JSON-RPC 2.0
  MCP 메서드와 메시지 의미
  도구·리소스·프롬프트 스키마
  오류와 메타데이터

MCP 전송 계층
  stdio
  Streamable HTTP
  또는 의미를 보존하는 custom transport

그림: MCP의 Host·Client·Server와 데이터·전송 계층 관계 · 공식 MCP Architecture 문서를 바탕으로 재구성

따라서 “MCP가 HTTP를 쓰는가?”라는 질문의 답은 원격 MCP는 HTTP를 쓰지만, MCP의 의미 자체가 HTTP에 종속되지는 않는다입니다.

Host, Client, Server의 역할

MCP 구조에는 세 역할이 등장합니다.

사용자
  ↓
Host 애플리케이션
  ├─ MCP Client A ── MCP Server: 파일 시스템
  ├─ MCP Client B ── MCP Server: GitHub
  └─ MCP Client C ── MCP Server: 사내 데이터베이스

Host는 대화 UI, LLM, 권한 승인 화면을 포함한 전체 애플리케이션입니다. MCP Client는 특정 MCP Server와 통신하는 프로토콜 구성 요소입니다. MCP Server는 외부 시스템을 tools, resources, prompts 같은 MCP 기능으로 노출합니다.

 

예를 들어 query_database라는 도구를 제공하는 MCP 서버는 데이터베이스 자체가 아닐 수 있습니다. 인증과 SQL 정책을 적용하고 기존 DB 드라이버를 호출한 뒤 결과를 MCP 형식으로 반환하는 어댑터에 가깝습니다.

공통 메시지 봉투는 JSON-RPC 2.0이다

전송 방식이 stdio든 HTTP든 본문 메시지는 JSON-RPC 2.0을 사용합니다. 요청은 대략 다음 구조입니다.

{
  "jsonrpc": "2.0",
  "id": 42,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {
      "location": "Seoul"
    },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientInfo": {
        "name": "example-client",
        "version": "1.0.0"
      },
      "io.modelcontextprotocol/clientCapabilities": {}
    }
  }
}

각 필드의 역할은 명확합니다.

필드 의미
jsonrpc JSON-RPC 버전. MCP는 "2.0"을 사용한다.
id 요청과 응답을 연결하는 상관관계 ID. 진행 중인 요청 사이에서 고유해야 한다.
method 실행할 MCP 메서드 이름
params 메서드 인자
_meta 프로토콜 버전, 클라이언트 기능 등 MCP 메타데이터

응답은 같은 id를 돌려줍니다.

{
  "jsonrpc": "2.0",
  "id": 42,
  "result": {
    "resultType": "complete",
    "content": [
      {
        "type": "text",
        "text": "서울의 현재 기온은 27°C입니다."
      }
    ],
    "isError": false
  },
  "_meta": {
    "io.modelcontextprotocol/serverInfo": {
      "name": "weather-server",
      "version": "2.1.0"
    }
  }
}

알림은 id가 없습니다. 수신자가 응답을 보내지 않는 메시지이기 때문입니다.

{
  "jsonrpc": "2.0",
  "method": "notifications/progress",
  "params": {
    "progress": 70,
    "total": 100
  }
}

그림: JSON-RPC 요청·응답·알림의 필드와 상관관계 · 공식 MCP Architecture 문서를 바탕으로 재구성

즉 MCP가 JSON 위에 아무 규칙 없이 자유롭게 데이터를 올리는 것은 아닙니다. JSON-RPC 2.0의 요청·응답·알림 형식을 지키고, 그 안의 MCP method와 데이터 타입은 MCP 사양과 공식 스키마를 따라야 합니다.

2026 사양의 핵심 변화: 연결이 아니라 요청이 단위다

과거 MCP 자료에는 클라이언트가 initialize 요청으로 연결을 초기화하고 서버가 세션 ID를 발급하며, 서버가 클라이언트로 다시 JSON-RPC 요청을 보내는 흐름이 많이 등장합니다. 2025년 사양을 설명한 글이라면 당시에는 맞는 내용입니다.

 

하지만 2026-07-28 사양은 stateless, per-request 모델로 바뀌었습니다.

과거 모델
연결 수립 → initialize → capability 협상 → 세션 상태 유지 → 여러 호출

현재 모델
각 요청 = 프로토콜 버전 + capability + 필요한 인증·메타데이터를 자체 포함

서버는 TCP 연결이나 stdio 프로세스가 같다는 이유만으로 프로토콜 버전, 클라이언트 신원, capability를 추론하면 안 됩니다. 오래 유지해야 하는 작업 상태가 있다면 명시적인 requestState, subscription ID 같은 식별자로 표현해야 합니다.

 

현재 필수 요청 메타데이터는 다음 두 가지입니다.

"_meta": {
  "io.modelcontextprotocol/protocolVersion": "2026-07-28",
  "io.modelcontextprotocol/clientCapabilities": {}
}

clientInfo와 로그 레벨 등은 선택 사항입니다. 필수 메타데이터가 없으면 서버는 JSON-RPC -32602 Invalid params로 거절하며, HTTP 전송에서는 HTTP 400을 함께 사용합니다.

 

이 변화는 로드밸런서 뒤에서 요청을 다른 인스턴스로 보내거나 서버리스로 처리하기 쉬워진다는 장점이 있습니다. 반면 구형 SDK와 최신 서버가 섞이면 동작 방식이 크게 다르므로, 구현자는 지원하는 사양 날짜를 반드시 확인해야 합니다.

stdio 전송: 한 줄에 JSON 메시지 하나

로컬 MCP 서버에서 가장 단순한 방식은 stdio입니다. 클라이언트가 MCP 서버를 자식 프로세스로 실행하고 다음 채널을 사용합니다.

Client ── child stdin  ──> MCP Server
Client <── child stdout ── MCP Server
Client <── child stderr ── 로그

wire format은 신뢰할 수 있는 양방향 바이트 스트림 위에 한 줄당 UTF-8 JSON-RPC 메시지 하나입니다.

{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{...}}}\n
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"search","arguments":{"q":"MCP"},"_meta":{...}}}\n

규칙은 엄격합니다.

  • 메시지는 개행 문자로 구분하며 메시지 내부에 실제 개행을 넣으면 안 됩니다. JSON 문자열의 줄바꿈은 \n으로 escape합니다.
  • 서버의 stdout에는 유효한 MCP 메시지만 써야 합니다.
  • 로그, 디버그 출력, 스택 트레이스는 stderr로 보냅니다.
  • 모든 응답은 하나의 stdout 채널로 섞여 오므로 id로 요청과 응답을 매칭합니다.
  • 진행 알림도 같은 채널로 오며 진행 중인 요청 또는 subscription ID와 연결합니다.
  • 취소는 notifications/cancelled 알림으로 요청 ID를 지정합니다.

stdio라고 해서 이 프레이밍이 운영체제 표준 스트림에서만 가능한 것은 아닙니다. 같은 “한 줄에 JSON 하나” 규칙을 Unix Domain Socket이나 TCP에 적용한 custom transport도 만들 수 있습니다. 다만 그것은 표준 stdio transport가 아니라 같은 프레이밍을 재사용한 사용자 정의 전송입니다.

그림: stdio 전송의 요청·응답·로그 채널과 newline 프레이밍 · 공식 MCP stdio 사양을 바탕으로 재구성

Streamable HTTP: 요청마다 POST 하나

원격 MCP 서버의 표준 전송은 Streamable HTTP입니다. 최신 사양의 핵심은 다음과 같습니다.

POST /mcp  ── JSON-RPC 요청 1 ──> JSON 한 개 또는 요청 범위 SSE
POST /mcp  ── JSON-RPC 요청 2 ──> JSON 한 개 또는 요청 범위 SSE
POST /mcp  ── JSON-RPC 알림   ──> 202 Accepted

서버는 하나의 MCP endpoint를 제공하고 모든 클라이언트 메시지는 각각 새로운 HTTP POST로 보냅니다. 요청 본문에는 JSON-RPC 객체 하나만 들어갑니다. JSON 배열을 이용한 batch나 여러 JSON-RPC 메시지를 한 POST에 넣는 방식으로 생각하면 안 됩니다.

 

실제 요청은 다음과 비슷합니다.

POST /mcp HTTP/1.1
Host: mcp.example.com
Content-Type: application/json
Accept: application/json, text/event-stream
Authorization: Bearer eyJ...
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: get_weather

{
  "jsonrpc": "2.0",
  "id": 42,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {"location": "Seoul"},
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {}
    }
  }
}

여기서 눈에 띄는 점은 일부 값이 HTTP 헤더와 JSON 본문에 중복된다는 것입니다.

HTTP 헤더 본문 원본 목적
MCP-Protocol-Version _meta.io.modelcontextprotocol/protocolVersion 사양 버전 선택
Mcp-Method method 프록시·WAF·관측 도구가 본문 파싱 없이 라우팅
Mcp-Name params.name 또는 params.uri 호출 대상 도구·리소스·프롬프트 식별

본문이 의미의 source of truth이며 서버는 헤더와 본문이 일치하는지 검증합니다. 버전이 다르면 HTTP 400과 HeaderMismatch JSON-RPC 오류를 반환합니다.

 

도구 스키마의 특정 원시 타입 필드에 x-mcp-header를 선언하면 Mcp-Param-{Name} 헤더로 복제할 수도 있습니다. 이는 로드밸런서가 지역이나 테넌트 같은 값을 기준으로 라우팅할 때 유용하지만 비밀번호, 토큰, 개인정보를 헤더로 올리면 중간 장비와 로그에 노출되기 쉬우므로 사용하면 안 됩니다.

 

한글처럼 안전한 ASCII 헤더 값으로 표현할 수 없는 값은 UTF-8 바이트를 Base64로 바꾸고 다음 sentinel 형식을 씁니다.

Mcp-Name: =?base64?{Base64EncodedValue}?=

왜 이름이 Streamable HTTP인가

서버는 요청의 성격에 따라 두 방식 중 하나로 응답합니다.

짧은 응답: application/json

HTTP/1.1 200 OK
Content-Type: application/json

{"jsonrpc":"2.0","id":42,"result":{"resultType":"complete",...}}

진행 상황이 있는 응답: text/event-stream

HTTP/1.1 200 OK
Content-Type: text/event-stream

data: {"jsonrpc":"2.0","method":"notifications/progress","params":{"progress":50}}

data: {"jsonrpc":"2.0","id":42,"result":{"resultType":"complete","content":[...]}}

SSE는 해당 POST 요청에 종속된 응답 스트림입니다. 진행 알림들을 보낸 뒤 반드시 최종 JSON-RPC 응답으로 끝납니다. 클라이언트가 이 SSE 연결을 닫으면 서버는 해당 요청이 취소된 것으로 처리해야 합니다.

 

장기적인 도구 목록 변경이나 리소스 변경을 받고 싶다면 별도 GET 스트림을 여는 것이 아니라 subscriptions/listen 요청을 보내 그 응답 스트림을 유지합니다. 2026 사양에서는 과거의 독립 GET SSE endpoint와 프로토콜 세션이 제거됐습니다. Last-Event-ID로 SSE 스트림을 재개하는 기능도 지원하지 않습니다.

 

따라서 운영 환경에서는 reverse proxy의 SSE buffering, idle timeout, 최대 요청 시간, 연결 종료 전파를 점검해야 합니다. HTTP/1.1에서도 가능하지만 여러 동시 스트림과 연결 효율을 고려하면 HTTP/2 지원 여부도 인프라 관점에서 확인할 가치가 있습니다. 다만 MCP 사양이 HTTP/2 자체를 필수로 강제하는 것은 아닙니다.

그림: Streamable HTTP의 요청별 JSON 응답과 SSE 스트리밍 분기 · 공식 MCP Streamable HTTP 사양을 바탕으로 재구성

Tools는 어떻게 발견하고 호출하는가

MCP 서버가 제공하는 도구를 클라이언트가 미리 하드코딩할 필요는 없습니다. tools/list로 런타임에 발견합니다.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {}
    }
  }
}

서버는 도구 이름, 설명, 입력 스키마를 반환합니다.

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resultType": "complete",
    "tools": [
      {
        "name": "get_weather",
        "description": "지역의 현재 날씨를 조회합니다.",
        "inputSchema": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "도시 이름"
            }
          },
          "required": ["location"],
          "additionalProperties": false
        }
      }
    ]
  }
}

Host는 이 설명과 스키마를 LLM에게 알려주고, 모델이 도구 호출을 제안하면 정책과 사용자 승인을 거쳐 tools/call을 전송합니다. MCP가 모델의 판단이나 승인 UI까지 강제하지는 않습니다.

JSON Schema는 어디까지 표준화돼 있는가

MCP에서 “포맷이 있는가?”라는 질문은 두 층으로 나눠야 합니다.

 

첫째, MCP 프로토콜 메시지 타입은 공식 TypeScript schema가 source of truth이며 여기서 JSON Schema가 생성됩니다. SDK 구현자는 이 스키마를 바탕으로 요청과 응답 타입을 맞출 수 있습니다.

 

둘째, 각 도구의 inputSchema와 선택적인 outputSchema도 JSON Schema입니다. $schema가 생략되면 JSON Schema 2020-12로 해석합니다. 구현체는 2020-12를 지원해야 하며, 다른 dialect를 쓴다면 $schema URI로 명시해야 합니다.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    }
  },
  "required": ["limit"],
  "additionalProperties": false
}

JSON Schema는 타입뿐 아니라 필수 필드, 범위, 문자열 패턴, 열거값, 중첩 구조를 검증할 수 있습니다. 그러나 스키마가 있다고 자동으로 안전해지는 것은 아닙니다. 외부 URL의 $ref를 자동으로 가져오면 SSRF나 공급망 문제가 생길 수 있고, 과도한 oneOf, allOf, 재귀 참조는 검증기 자원을 소모할 수 있습니다. 공식 사양도 외부 네트워크 $ref의 자동 역참조를 금지하고 깊이·시간·서브스키마 수 제한을 권고합니다.

결과 데이터는 텍스트만 가능한가

도구 결과의 content는 여러 타입을 섞을 수 있습니다.

{
  "resultType": "complete",
  "content": [
    {"type": "text", "text": "분석 결과입니다."},
    {
      "type": "image",
      "data": "iVBORw0KGgoAAA...",
      "mimeType": "image/png"
    },
    {
      "type": "resource_link",
      "uri": "file:///reports/result.json",
      "name": "result.json",
      "mimeType": "application/json"
    }
  ],
  "structuredContent": {
    "riskScore": 82,
    "severity": "high"
  },
  "isError": false
}

텍스트는 JSON 문자열, 이미지와 오디오는 Base64 데이터와 MIME type, 파일이나 웹 자원은 URI 링크 또는 embedded resource로 표현합니다. 기계가 처리할 결과는 structuredContent에 JSON 값으로 반환하고 outputSchema로 검증할 수 있습니다.

 

여기서 structuredContent는 LLM이 schema-constrained decoding으로 만든 “structured output”과 다른 개념입니다. MCP 서버가 반환하는 도구 결과 데이터일 뿐입니다.

 

대용량 바이너리를 매번 Base64로 본문에 넣으면 크기가 약 33% 증가하고 메모리 사용량도 커집니다. 큰 파일은 접근 통제된 resource URI나 별도 객체 저장소 URL을 반환하고 클라이언트가 필요할 때 읽게 하는 설계가 더 적합할 수 있습니다.

HTTP 상태 코드와 JSON-RPC 오류는 다른 계층이다

Streamable HTTP에서는 오류가 두 층에 존재합니다.

HTTP 계층
  인증 실패, 잘못된 Origin, 지원하지 않는 endpoint,
  헤더 불일치, 전송 자체의 실패

JSON-RPC/MCP 계층
  파싱 실패, 잘못된 요청, 존재하지 않는 method,
  잘못된 params, tool 실행 오류

대표적인 JSON-RPC 표준 오류는 다음과 같습니다.

코드 의미
-32700 Parse error
-32600 Invalid Request
-32601 Method not found
-32602 Invalid params
-32603 Internal error

MCP는 헤더 불일치 -32020, 필요한 client capability 누락 -32021, 지원하지 않는 프로토콜 버전 -32022 같은 오류도 정의합니다.

 

도구 자체가 정상적으로 실행됐지만 업무 오류가 발생한 경우에는 HTTP 200과 정상 JSON-RPC 응답 안에서 isError: true를 사용할 수 있습니다. 예를 들어 “결제 카드 거절”은 네트워크 전송 실패와 다릅니다. 모니터링에서도 HTTP 성공률만 보면 MCP 도구의 업무 실패를 놓칠 수 있습니다.

인증은 HTTP에서 OAuth 2.1 계열을 사용한다

MCP 인증은 선택 사항이지만 HTTP 기반 transport가 인증을 지원한다면 최신 MCP Authorization 사양을 따르는 것이 권장됩니다. 핵심은 MCP 서버가 OAuth resource server로 동작한다는 것입니다.

MCP Client
  ├─ Protected Resource Metadata 조회
  ├─ Authorization Server Metadata 조회
  ├─ OAuth 2.1 + PKCE로 사용자 승인
  └─ Authorization: Bearer <access-token>
                         ↓
                    MCP Server

사양은 OAuth 2.1 draft, RFC 6750 Bearer Token, RFC 8414 Authorization Server Metadata, RFC 9728 Protected Resource Metadata, RFC 8707 Resource Indicators 등을 조합합니다. 클라이언트는 토큰을 query string에 넣으면 안 되며 모든 보호된 HTTP 요청에 Authorization: Bearer 헤더를 포함해야 합니다. 서버는 토큰의 audience가 자기 자신인지 검증해야 합니다.

 

stdio는 이 HTTP OAuth 흐름을 따르지 않고 프로세스 환경에서 자격증명을 받도록 권고합니다. 그렇다고 API 키를 설정 파일이나 로그에 평문으로 남겨도 된다는 뜻은 아닙니다. OS keychain, secret manager, 최소 권한 환경 변수 주입 같은 별도 운영 통제가 필요합니다.

REST, OpenAPI, gRPC, WebSocket과 비교하면

기술 주된 역할 전송·인코딩 MCP와의 차이
REST API HTTP 리소스 조작 HTTP + 주로 JSON MCP는 정해진 RPC method와 AI 도구 발견 규약을 제공
OpenAPI HTTP API의 정적 명세 YAML 또는 JSON 문서 MCP는 런타임 tools/list와 호출·결과 메시지까지 정의
JSON-RPC 2.0 RPC 메시지 봉투 전송 독립 JSON MCP가 이 봉투 위에 method와 의미를 표준화
gRPC 강타입 원격 호출 HTTP/2 + Protobuf MCP는 사람이 읽을 수 있는 JSON과 JSON Schema 중심
WebSocket 전이중 연결 전송 프레임 기반 MCP의 기본 전송이 아니며 custom transport 후보
SSE 서버에서 클라이언트로 스트리밍 HTTP text/event-stream Streamable HTTP에서 요청별 진행 알림·최종 응답에 사용

기존 REST API를 MCP로 연결할 때 API를 버릴 필요는 없습니다. MCP 서버를 얇은 어댑터로 두고 내부에서는 기존 REST나 gRPC를 호출하는 구성이 일반적입니다.

LLM Host
  → MCP Client
  → MCP Server
  → 기존 REST/gRPC/DB/Queue

MCP는 백엔드 시스템을 새로 만드는 기술이라기보다, AI 애플리케이션이 그 시스템의 기능을 발견하고 호출하는 공통 인터페이스에 가깝습니다.

실제 도입 전에 확인할 후보를 추리면

기존 IT 조직이 MCP 서버를 검토할 때는 다음 항목부터 확인하는 것이 좋습니다.

1. 전송 선택

  • 한 컴퓨터에서 Host가 프로세스를 직접 실행한다면 stdio가 단순합니다.
  • 여러 사용자와 원격 서버를 연결한다면 Streamable HTTP가 적합합니다.
  • custom transport는 표준 클라이언트 호환성과 관측 도구를 잃는 비용을 먼저 계산해야 합니다.

2. 사양 버전과 SDK 호환성

  • 서버와 클라이언트가 2026-07-28 stateless 모델을 모두 지원하는지 확인합니다.
  • initialize, MCP-Session-Id, GET SSE에 의존하는 구형 구현인지 구분합니다.
  • 헤더와 본문의 프로토콜 버전 불일치를 테스트합니다.

3. 스키마 품질

  • 모든 도구에 구체적인 inputSchema를 정의합니다.
  • 가능하면 additionalProperties: false, 길이·범위·enum을 사용합니다.
  • 중요한 기계 처리 결과에는 outputSchema와 structuredContent를 제공합니다.
  • 외부 $ref, 재귀, 복잡한 조합 스키마에 자원 제한을 둡니다.

4. 권한과 안전 장치

  • 도구 목록도 토큰 scope에 맞게 최소화합니다.
  • 읽기와 쓰기 도구를 분리하고 삭제·결제·권한 변경은 사용자 승인을 받습니다.
  • LLM이 만든 인자를 신뢰하지 말고 서버에서 다시 검증합니다.
  • stdio 서버가 상속받는 환경 변수와 파일 권한을 점검합니다.

5. HTTP 운영 항목

  • Origin 검증과 localhost bind로 DNS rebinding을 방지합니다.
  • OAuth audience, scope, token 만료를 검증합니다.
  • SSE buffering, idle timeout, 연결 종료와 취소 전파를 테스트합니다.
  • Mcp-Method, Mcp-Name은 로깅하되 민감한 Mcp-Param-*은 남기지 않습니다.

6. 신뢰성과 관측성

  • JSON-RPC id로 end-to-end trace를 연결합니다.
  • HTTP 오류, JSON-RPC 오류, isError: true를 별도 지표로 집계합니다.
  • 재시도 가능한 읽기 작업과 중복 실행이 위험한 쓰기 작업을 구분합니다.
  • timeout, cancellation, 부분 진행 알림 이후 실패를 테스트합니다.

정리

MCP 서버를 로우레벨에서 보면 신비로운 AI 전용 네트워크가 아닙니다.

의미와 메시지
  MCP method + JSON-RPC 2.0

도구 계약
  JSON Schema 2020-12 기본

로컬 전송
  UTF-8 newline-delimited JSON over stdio

원격 전송
  HTTP POST + application/json 또는 request-scoped SSE

인증
  HTTP는 OAuth 2.1 계열, stdio는 실행 환경의 자격증명

MCP의 가치는 새로운 소켓이나 직렬화 포맷을 발명한 데 있지 않습니다. 기존 표준을 조합해 AI Host가 도구를 발견하고, 타입을 이해하고, 호출하고, 결과를 받는 공통 계약을 만든 데 있습니다.

 

운영자가 기억할 핵심은 세 가지입니다. MCP 데이터 계층과 전송 계층을 분리해 볼 것, 최신 사양의 stateless 요청 모델과 구형 세션 모델을 혼동하지 말 것, 스키마가 있어도 권한·검증·승인·관측을 서버 외부와 내부에서 함께 강제할 것입니다.

참고 자료