C.W.K.
Stream
Lesson 04 of 05 · published

Lifecycle 과 Capability Negotiation

~22 min · initialize, lifecycle, capabilities, handshake

Level 0호기심 많은 독자
0 XP0/48 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

MCP session 은 4 phase: connect, initialize, operate, shutdown. 첫 번째는 transport-specific (stdio pipe 열기, HTTP connection 열기); 마지막은 graceful close. 가운데 둘이 protocol 무게 다 carry.

Initialize 가 handshake. Client 가 initialize request 보내며 protocolVersion, capabilities (e.g. sampling, roots, elicitation), clientInfo 광고. Server 가 같은 envelope 으로 답: negotiated version (양쪽 다 아는 가장 높은 거), 자기 capability, serverInfo. 이 교환 후 양쪽 다 — session 의 나머지가 뭘 쓸 수 있는지에 대한 — 정밀한 written 합의.

Handshake 가 중요한 이유는 — protocol 이 lock-step 업그레이드 없이 evolve 하게 해주는 거. 새 client 가 옛 server 와 대화 가능 — 양쪽이 광고하는 capability 만 씀. 새 server 가 — 옛 client 가 무시하는 — 실험적 capability ship 가능. MCP 의 capability 가 HTTP/REST 의 version 번호 역할 — parts 가 서로 안 깨면서 다른 속도로 움직이게 하는 방법.

Operate 는 handshake 후 모든 거: tool call, resource read, prompt request, sampling round-trip, log message, progress event. Shutdown 은 양쪽 resource 정리하는 작별; server 는 shutdown 을 — log flush 하고 file handle 놓는 — 기회로 다뤄.

Code

Wire 위 initialize handshake·json
// Client -> Server
{
  "jsonrpc": "2.0", "id": 1, "method": "initialize",
  "params": {
    "protocolVersion": "2025-11-25",
    "capabilities": {
      "sampling": {},
      "roots": { "listChanged": true }
    },
    "clientInfo": { "name": "claude-code", "version": "1.42.0" }
  }
}

// Server -> Client
{
  "jsonrpc": "2.0", "id": 1, "result": {
    "protocolVersion": "2025-11-25",
    "capabilities": {
      "tools": { "listChanged": true },
      "resources": {},
      "prompts": {}
    },
    "serverInfo": { "name": "github-mcp", "version": "0.4.0" }
  }
}
Capability 읽고 동작 gate·python
async with ClientSession(read, write) as session:
    init_result = await session.initialize()
    if "tools" not in init_result.capabilities:
        raise RuntimeError("이 server 는 tool 광고 안 함 — 잘못된 server?")
    if init_result.capabilities.get("logging"):
        await session.set_logging_level("info")  # 광고됐을 때만 안전
    tools = await session.list_tools()

External links

Exercise

아무 MCP server 돌려 (SDK 'echo' 예제, 또는 community server). Transport sniffer 나 debug logger 로 initialize request/response 캡처. Negotiated capability 읽어. 정신적으로 추론: 어떤 method 호출 안전, 어떤 게 capability 광고 안 돼서 405?

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.