LLM 에 사내 API 몇 개를 붙이려는데 "그냥 함수 호출로 짤까, MCP 서버로 뺄까, 뺀다면 stdio 로 띄울까 원격 HTTP 로 둘까"에서 멈추는 경우가 많아요. 결론부터 말하면 MCP 를 거쳐서 생기는 지연은 호출당 3~9ms 수준이라 판단 기준이 못 되고, 진짜 비용은 모델을 부를 때마다 다시 실리는 도구 정의 토큰이에요. 도구를 여러 앱이 같이 쓰거나 남이 만든 서버를 붙일 거면 MCP, 한 앱 안의 도구 몇 개면 직접 함수 호출, 도구가 30개를 넘으면 캐싱과 도구 검색부터 챙기는 게 맞아요.
이 글은 동작 원리 대신 고를 때 필요한 숫자만 다뤄요. 공식 파이썬 SDK mcp 2.3.0 으로 지연을 Apple M1·파이썬 3.13 에서 직접 쟀고, 비용은 2026-10-27 기준 Anthropic 공식 가격표로 계산했어요. 절대 시간은 기기마다 다르니 자릿수로 읽어 주세요.
MCP 쓸까 말까 — 네 가지 방식 판단표
도구를 모델에 붙이는 방식은 크게 넷이에요. 모델이 도구 호출 JSON 을 내는 부분은 넷 다 같은 모델 API 기능이고, 도구 정의를 어디에 두고 실행 요청을 누가 배달하느냐만 달라요.
| 방식 | 도구 코드 위치 | 호출당 추가 지연(실측) | 재사용 | 잘 맞는 경우 |
|---|---|---|---|---|
| 직접 함수 호출 | 앱 프로세스 안 | 0.2µs | 그 앱만 | 앱 하나, 도구 10개 이하 |
| MCP stdio | 같은 기기 하위 프로세스 | 3.6ms (기동 2.2초) | MCP 를 말하는 모든 앱 | IDE·데스크톱 앱, 로컬 파일·CLI 도구 |
| MCP Streamable HTTP | 원격 서버 | 6.8ms + 네트워크 왕복 | 여러 앱·여러 사용자 | 사내 공용 도구, SaaS 연동 |
| Claude API MCP 커넥터 | 원격 서버, 호출은 API 가 | 내 앱 쪽 왕복 없음 | API 를 쓰는 앱 | 클라이언트 코드 없이 원격 서버를 붙일 때 |
마지막 줄은 Claude MCP 커넥터 문서에 나온 기능이에요. Messages API 요청에 원격 MCP 서버 주소를 넣으면 API 가 대신 도구 목록을 받고 호출해요. 다만 2026-10-27 기준 베타(mcp-client-2025-11-20 헤더)이고, 스펙 기능 중 도구 호출만 지원하며, 서버가 공개 HTTP 로 열려 있어야 해서 로컬 stdio 서버는 바로 붙일 수 없다고 적혀 있어요.
판단의 핵심은 재사용 범위예요. 앱 M 개와 데이터 소스 N 개를 직접 연결하면 코드가 M×N 벌, MCP 는 서버 N 개로 끝나요. 앱이 하나뿐이면 MCP 는 프로세스·직렬화·배포 단위를 하나씩 더 얹는 일이에요.
직접 잰 지연 — 직접 호출·stdio·HTTP
두 정수를 더하는 도구 하나를 MCPServer 로 만들고, 연결이 이미 열린 상태에서 500번 호출해 중앙값과 99퍼센타일을 적었어요. HTTP 는 같은 기기의 127.0.0.1 이라 네트워크 왕복은 거의 0이에요. "legacy"는 2025-11-25 이전 방식(initialize 핸드셰이크와 HTTP 세션)이고 "modern"은 2026-07-28 방식이에요. SDK 의 Client(..., mode="legacy") 로 같은 서버를 두 방식으로 불렀어요.
연결을 처음 여는 비용은 차이가 훨씬 컸어요.
| 측정 (10회 중앙값) | stdio modern | stdio legacy | HTTP modern | HTTP legacy |
|---|---|---|---|---|
| 연결 완료까지 | 2,226ms | 2,214ms | 11.6ms | 14.3ms |
| 첫 도구 결과까지 | 2,241ms | 2,228ms | 27.6ms | 44.1ms |
읽을 점은 셋이에요.
- stdio 의 비용은 호출이 아니라 기동이에요. 서버 파일을 import 하는 시간만 따로 재도 2초를 넘었어요. 데스크톱 앱처럼 한 번 띄워 오래 쓰면 문제가 안 되지만, 서버리스 함수에서 요청마다 stdio 서버를 새로 띄우면 요청당 2초가 붙어요. 이런 구조라면 HTTP 서버로 상주시키는 게 맞아요.
- HTTP 에서는 modern 이 legacy 보다 빨랐어요. 첫 결과까지 44ms 가 28ms 로 줄었고, 연결 뒤 호출도 9.0ms 에서 6.8ms 가 됐어요. legacy 는 핸드셰이크 왕복이 한 번 더 있고 서버가 세션을 관리해요. 스펙 개정 내용은 MCP 2026-07-28 변경 이력에 정리돼 있어요.
- 모델 응답에 비하면 작아요. 도구를 한 번 부르는 턴은 모델 응답을 두 번 기다려요. 모델 쪽이 수백 ms~수 초라 MCP 몫 3~9ms 는 1% 안팎이에요. 지연을 줄이려면 도구 안의 DB 쿼리·외부 API 와 모델 호출 횟수를 먼저 봐요.
원격 서버라면 여기에 네트워크 왕복이 더해지는데, 2026-07-28 방식은 버전과 능력을 매 요청 _meta 에 실어서 핸드셰이크 왕복 없이 첫 요청부터 tools/call 을 보낼 수 있어요.
비용의 진짜 주인공 — 매번 실리는 도구 정의 토큰
MCP 서버 운영비는 대개 작은 컨테이너 한두 대예요. 돈이 크게 나가는 곳은 모델 API 쪽이에요. 모델 API 는 상태가 없어서 매 호출마다 도구 정의 전체를 다시 입력 토큰으로 받아요. 에이전트가 작업 하나에 모델을 10번 부르면 도구 정의도 10번 청구돼요.
도구 하나가 몇 토큰인지 쟀어요. 고객 주문 조회 도구(인자 3개, 한국어 설명 한 문장)를 SDK 가 만든 그대로 모델 API 형식으로 옮겨 OpenAI 의 o200k 토크나이저로 셌어요. Claude 토크나이저와는 값이 다르니 자릿수로 읽어 주세요. 같은 문장이 토크나이저마다 몇 토큰이 되는지는 한국어 LLM 토큰 비용 비교에서 다뤘어요.
파이썬 SDK 는 타입 힌트로 스키마를 만들면서 인자마다 "title": "Customer Id" 같은 필드를 붙여요. 모델에게는 정보가 거의 없는 필드라 지우면 도구당 18% 가 줄어요. 정의 JSON 이 실제로 어떻게 생겼는지는 tools/list 응답을 JSON 정렬 도구에 붙여 펼쳐 보면 바로 보여요.
이제 월 비용이에요. Anthropic 가격표에서 Claude Sonnet 5.5 는 입력 100만 토큰당 2달러, 5분 캐시 쓰기 2.50달러, 캐시 읽기 0.10달러이고, 도구를 하나라도 넘기면 도구 사용 시스템 프롬프트 286토큰이 더해져요. 작업 1만 건, 작업당 모델 호출 10번, 도구 하나 160토큰으로 도구 정의 몫만 계산했어요. 캐싱은 작업마다 첫 호출에서 한 번 쓰고 나머지 9번을 읽는다고 봤어요.
계산식은 단순해요. 도구 50개면 (8,000 + 286) × 10회 × 1만 건 = 8억 2,860만 토큰이고, 2달러/100만 토큰을 곱하면 1,657달러예요. 캐싱을 켜면 작업당 8,286토큰 × 2.50달러 한 번과 × 0.10달러 아홉 번이라 282달러로 83% 줄어요. 같은 조건에서 Claude Haiku 5.5(입력 0.10달러)는 캐싱 없이 83달러, Opus 5.5(4달러)는 3,314달러예요. 모델 선택이 단가 그대로 곱해지니 도구가 많은 에이전트일수록 도구 정의를 줄이는 효과가 커요.
도구가 많을 때 — 캐싱·도구 검색·서버 쪼개기
도구 수가 늘면 돈만 드는 게 아니라 고르는 품질도 떨어져요. Claude 도구 검색 문서는 사용 가능한 도구가 30~50개를 넘으면 맞는 도구를 고르는 능력이 떨어진다고 적고 있어요. 대응은 세 가지예요.
| 대응 | 줄어드는 것 | 대가 | 쓸 때 |
|---|---|---|---|
| 프롬프트 캐싱 | 반복 호출의 입력 단가(Sonnet 5.5 는 캐시 읽기 0.05배) | 첫 쓰기 1.25배, 5분 안에 다시 와야 함 | 거의 항상. 최소 길이(Sonnet 5.5 는 512토큰) 이상일 때 |
도구 검색 + defer_loading | 모델 문맥에 올라가는 도구 수 | 검색 한 단계, 필요한 도구를 못 찾을 위험 | 도구 30개 이상 |
| 작업별 서버·도구 묶음 | 한 요청에 넘기는 도구 수 자체 | 라우팅 로직을 직접 짜야 함 | 작업 종류가 뚜렷이 나뉠 때 |
도구 검색을 쓰면 defer_loading: true 로 표시한 도구는 문맥에 올리지 않고 검색으로 찾았을 때만 펼쳐요. 문서에는 앞의 5만 5천 토큰 예시가 보통 85% 넘게 줄어든다고 나와 있고, 불러온 정의는 일반 입력 토큰으로 청구돼요. 펼친 도구를 대화 중간에 붙이는 방식이라 앞부분 캐시도 깨지지 않아요.
프롬프트 캐싱 문서에 따르면 최소 길이보다 짧은 프롬프트는 오류 없이 캐싱만 안 돼요. 응답의 cache_creation_input_tokens 와 cache_read_input_tokens 가 둘 다 0이면 캐시가 안 걸린 거예요.
2026-07-28 무상태 개정이 운영에 주는 것
원격 MCP 서버를 운영할 거라면 이번 개정이 판단을 바꿔요. MCP Streamable HTTP 전송 스펙 기준으로 정리하면 이래요.
| 운영 항목 | 2025-11-25 이전 | 2026-07-28 |
|---|---|---|
| 로드밸런서 | 같은 Mcp-Session-Id 를 같은 인스턴스로(sticky) | 아무 인스턴스나 가능 |
| 라우팅·관측 | 본문 JSON 을 열어야 메서드를 앎 | Mcp-Method·Mcp-Name 헤더로 판단 |
| 끊긴 스트림 | Last-Event-ID 로 재개 | 재개 없음, 새 id 로 재요청 |
| 서버가 사용자에게 되묻기 | 서버가 클라이언트에 요청을 보내고 대기 | input_required 결과로 끝내고 클라이언트가 재요청(MRTR) |
무상태가 됐다고 공짜는 아니에요. 세 가지를 챙겨야 해요.
- 재요청 안전성. 스트림이 끊기면 클라이언트가 새 id 로 다시 보내므로, 결제나 이슈 생성처럼 부작용이 있는 도구는 같은 요청이 두 번 와도 한 번만 처리되게 멱등 키를 받는 게 좋아요.
requestState서명. MRTR 패턴 문서는 서버가 되물을 때 진행 상태를 클라이언트에 맡기므로, 이 값을 공격자가 조작할 수 있는 입력으로 다루고 권한에 영향을 주면 HMAC 이나 AEAD 로 무결성을 보호하라고 요구해요(MUST). 짧은 만료 시간도 권해요. HMAC 값이 어떻게 생기는지는 해시 생성기의 HMAC 칸에서 키와 메시지를 넣어 확인해 볼 수 있어요.- 여러 호출에 걸친 상태. 세션이 없으니 "직전 호출에서 연 장바구니"는 서버가 핸들을 만들어 결과로 주고, 다음 호출의 인자로 받아야 해요.
원격 서버의 인증은 OAuth 기반 MCP 인가 스펙을 따르게 돼요. 토큰 만료와 갱신 주기를 정하는 기준은 액세스·리프레시 토큰 만료 시간 정하는 법과 같아요.
상황별 추천
- 사내 챗봇 하나에 조회 API 5개: 직접 함수 호출이 가장 단순해요. 다른 앱이 같은 도구를 쓰게 되면 그때 MCP 서버로 빼도 늦지 않아요.
- IDE·데스크톱 앱에서 로컬 파일·깃·CLI 를 다루는 도구: MCP stdio 예요. 기동 2초는 앱을 켤 때 한 번이고, 로그는 반드시
stderr로 보내요. stdio 전송 스펙은 서버가stdout에 MCP 메시지가 아닌 것을 쓰면 안 된다고 정해요. - 여러 팀·여러 앱이 쓰는 사내 공용 도구(검색, 티켓, 배포 조회): Streamable HTTP 서버로 상주시키고 2026-07-28 방식으로 구현해요. 인스턴스를 늘려도 sticky 설정이 필요 없어요.
- 서버리스·배치 작업에서 남이 만든 원격 MCP 서버를 쓸 때: 클라이언트 코드를 직접 운영하기 싫다면 Claude MCP 커넥터가 편해요. 베타이고 도구 호출만 된다는 제약을 감안해요.
- 도구가 30~50개를 넘는 범용 에이전트: 방식과 상관없이 캐싱과 도구 검색을 먼저 켜요. 앞의 계산에서 도구 50개는 캐싱만으로 월 1,657달러가 282달러가 됐어요.
- 모델이 도구를 자꾸 잘못 고를 때: 대개 전송 방식이 아니라 설명문과 스키마 문제예요. 출력 형식을 강제하는 쪽은 Structured Outputs vs JSON 모드 비교에서 다뤘어요.
도입 체크리스트
- 도구 정의 토큰을 재요. 모델 API 의 토큰 세기 기능이나 응답 usage 로 도구 목록 몫을 확인하고, 작업당 모델 호출 수를 곱해 월 비용을 미리 계산해요.
- 스키마를 다듬어요. 자동 생성된
title같은 필드를 빼고, 설명문은 "언제 쓰고 무엇을 돌려주는지"를 한두 문장으로 써요. - 목록 순서를 고정해요. 서버는 결정적인 순서로, 호스트는 여러 서버를 합칠 때 정렬해서 넘겨요.
- 캐시 적중을 확인해요. 첫 주에
cache_read_input_tokens비율을 기록하고, 0이면 최소 길이나 순서 변동을 의심해요. - stdio 서버의
stdout을 지켜요.print디버깅을stderr로 돌리고, 의존 라이브러리가 표준 출력에 쓰지 않는지 확인해요. - 모델이 읽을 오류 메시지를 써요. MCP 도구 스펙은 실행 실패를
isError: true결과로 돌려주라고 해요. "b 는 0 이 될 수 없어요"처럼 고칠 방법이 담겨야 모델이 인자를 바꿔 다시 불러요. - 부작용 있는 도구는 멱등 키를 받아요. 재요청이 스펙상 정상 동작이에요.
- 원격 서버는
Origin헤더를 검사해요. Streamable HTTP 스펙은 DNS 리바인딩 공격을 막으려고 서버가 모든 연결의Origin을 검증하라고 요구해요(MUST). 로컬에서 띄울 때는127.0.0.1에만 바인딩해요.
측정에 쓴 코드는 이 정도예요. 같은 서버 파일을 python server.py http 8765 로 띄우면 HTTP 쪽도 잴 수 있어요.
import asyncio, sys, time, statistics
from mcp import Client
from mcp.client.stdio import StdioServerParameters
async def warm(target, mode, n=500):
async with Client(target, mode=mode) as c:
for _ in range(20): # 예열
await c.call_tool("add", {"a": 2, "b": 3})
xs = []
for _ in range(n):
t = time.perf_counter()
await c.call_tool("add", {"a": 2, "b": 3})
xs.append((time.perf_counter() - t) * 1000)
xs.sort()
return statistics.median(xs), xs[int(n * 0.99)]
stdio = StdioServerParameters(command=sys.executable, args=["server.py"])
for target in (stdio, "http://127.0.0.1:8765/mcp"):
for mode in ("auto", "legacy"):
print(mode, asyncio.run(warm(target, mode)))
자주 묻는 질문
MCP 를 쓰면 응답이 느려지나요?
같은 기기에서 도구 한 번에 stdio 3.6ms, 로컬 HTTP 6.8ms 가 더해졌어요. 모델 응답이 수백 ms~수 초라 대부분 체감되지 않아요. 예외는 stdio 서버를 요청마다 새로 띄우는 구조로, 기동에 2초 넘게 걸려요.
도구가 몇 개를 넘으면 문제가 되나요?
Anthropic 문서는 30~50개를 넘으면 맞는 도구를 고르는 정확도가 떨어진다고 해요. 비용은 도구 수에 비례해서 늘어요. 한국어 설명이 붙은 도구 하나가 o200k 기준 약 160토큰이라, 50개면 매 호출에 8천 토큰 가까이 실려요.
프롬프트 캐싱은 MCP 도구에도 적용되나요?
네. 모델 API 입장에서는 MCP 에서 왔든 직접 짰든 같은 도구 정의예요. 요청 앞부분이 매번 같아야 하니 목록 순서만 고정하면 돼요. 예시에서 도구 50개 비용이 83% 줄었어요.
stdio 와 Streamable HTTP 중 무엇을 골라야 하나요?
서버가 사용자 기기의 파일이나 CLI 를 다루고 앱 하나가 띄워 쓰면 stdio, 여러 사용자나 여러 앱이 같이 쓰면 HTTP 예요. HTTP 는 인증(OAuth)과 Origin 검사, 멱등성 같은 운영 부담이 따라와요.
예전 방식(initialize 핸드셰이크) 서버도 계속 쓸 수 있나요?
파이썬 SDK 2.3.0 의 기본 연결은 server/discover 로 먼저 떠보고, 안 되면 예전 핸드셰이크로 내려가요. 같은 MCPServer 가 두 방식을 모두 받았어요. 새 원격 서버라면 세션 없는 2026-07-28 방식이 확장하기 쉬워요.
정리
- MCP 를 거쳐 생기는 지연은 호출당 3~9ms 라 판단 기준이 아니에요. 고르는 기준은 도구를 몇 개의 앱이 같이 쓰느냐예요. 앱 하나면 직접 함수 호출, 여러 앱이 쓰거나 남이 만든 서버를 붙이면 MCP 예요.
- 돈은 모델을 부를 때마다 다시 실리는 도구 정의 토큰에서 나가요. 도구 50개 에이전트는 Sonnet 5.5 로 월 1만 건에 약 1,657달러이고, 캐싱으로 282달러까지 내려가요. 스키마 다듬기, 목록 순서 고정, 도구 검색이 그다음이에요.
- 원격 서버는 2026-07-28 무상태 방식으로 만들면 sticky 라우팅이 필요 없어요. 대신 재요청에 대비한 멱등 키,
requestState서명,Origin검사를 챙겨요. 가격과 베타 상태는 2026-10-27 기준이니 도입 전에 공식 문서를 다시 확인해요.
더 깊이 읽기
이 글은 실무에서 판단할 때 필요한 것 위주로 정리했어요. 같은 주제의 내부 동작 원리는 devboi 기술 블로그의 MCP 동작 원리 — tools/call 흐름과 무상태 개정에서 도식과 코드로 단계별로 풀었어요.