본문 바로가기
C.W.K.
Stream
Lesson 05 of 05 · published

Production Shipping Checklist

~24 min · production, checklist, launch

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

모르는 사람한테 MCP server 를 내놓는 건 혼자 쓰려고 돌리는 것과는 아예 다른 종류의 일이야. 아래 점검표는 실제 production 사고를 막아준 것들만 추린, 가장 짧은 목록이야. 여기서 하나를 건너뛰면 언젠가 누군가의 한 주가 망가져.

  1. Protocol revision 을 못박고 문서에 적어둘 것. README 와 manifest 에 적고 initialize 때 확인까지 해. Spec 이 움직이면 의식적으로 올려 — 최신을 조용히 따라가지 마.
  2. Stdio server 는 진단을 전부 stderr 로. 코드를 훑어서 print(, 라이브러리 기본 출력, 디버거 출력, tqdm 진행 막대를 다 잡아내. Stdout 은 선이야.
  3. HTTP server 는 로컬이면 127.0.0.1 에 붙이고, 언제나 Origin/Host 를 검사하고, TLS 뒤에 둘 것. Track 7 의 로컬 함정은 선택 사항이 아니야.
  4. OAuth scope 를 좁게. 요청하는 scope 하나하나가 훗날 유출 사고의 크기가 돼. 돌아가는 선에서 가장 작은 묶음을 기본으로 삼아.
  5. Tool annotation 을 정직하게. destructiveHint, openWorldHint, idempotentHint 는 host 한테 중요한 정보야. 거짓말하면 목록에서 내려가.
  6. Write tool 에는 덧붙이기만 하는 audit log 를. 관측용 log 와 따로 두고, 경계에서 민감한 값을 지워.
  7. 모든 외부 write 에 idempotency key 를. Stripe 처럼 (conversation/session/proposal) 을 키로 삼아. 네트워크가 한 번 튀는 일은 production 에서 드물지 않아.
  8. README 에 compatibility 표를. Revision 셋 × 주요 client 셋 × transport 둘. 안 해본 칸은 표시해.
  9. Commit 마다 도는 smoke test 를. Server 띄우기, tool 목록, tool 하나 호출, 종료. 더 정교한 건 덤이고, 이 최소한이 회귀의 9 할을 잡아.
  10. 공개 changelog 와 deprecation 안내를. Spec 과 같은 어휘를 써 — "1.5.0 부터 deprecated, 1.7.0 에서 제거" 에 그동안 둘 다 쓸 수 있다는 안내까지.

두 번 읽어. 목록이 더 길어지진 않아. 이걸 지킨 server 는 몇 해를 살고, 건너뛴 server 는 이 quest 같은 데 전쟁 이야기로 실려.

Code

Smoke-test pytest fixture·python
import pytest, asyncio
from mcp.client.stdio import StdioServerParameters, stdio_client
from mcp.client.session import ClientSession

@pytest.mark.asyncio
async def test_smoke():
    params = StdioServerParameters(command="uvx", args=["my-mcp-server"])
    async with stdio_client(params) as (read, write):
        async with ClientSession(read, write) as s:
            init = await s.initialize()
            assert init.protocolVersion in {"2025-06-18","2025-11-25"}
            tools = await s.list_tools()
            assert any(t.name == "get_stock_price" for t in tools.tools)
            res = await s.call_tool("get_stock_price", {"symbol": "AAPL"})
            assert "AAPL" in res.content[0].text

External links

Exercise

네가 짠 server 를 들고 위 열 항목을 점검해봐. 체크가 안 되는 항목 하나하나가 아직 남은 출시 작업이야. 목록이 깨끗해졌을 때만 release 날짜를 잡아.

Progress

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

댓글 0

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

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