MCP vs A2A

는 둘 다 “가 외부와 말하는 방법”을 표준화한다. 그런데 무엇을 표준화하는지가 정반대 방향이다. 같은 기능을 둘 중 어디로 노출할지 — 이 챕터 끝나면 30초 안에 답할 수 있다.


두 프로토콜, 다른 자리

다이어그램 로딩…
표준화 대상·리소스·프롬프트
주 사용자LLM 호스트 앱 ↔ 도구에이전트 ↔ 에이전트
호출 방향LLM이 부른다동료가 위임한다
작업 모델request/response 상태 머신

한 줄: MCP는 손, A2A는 동료.


MCP가 노출하는 3대 자원

의 핵심 추상은 셋이다.

  1. — 실행 가능한 함수. 부수효과 있음.
  2. — 읽기 전용 데이터. 파일·URL·DB row.
  3. — 매개변수화된 재사용 프롬프트.

A2A의 자원은 하나다 — . 작업 단위가 더 굵고, 내부에 자체 도구·메모리·LLM 호출을 품을 수 있다.

비교 축MCP 자원 3종A2A 자원 1종
입자 크기작다 (함수 호출)크다 (전체 작업)
상태보통 무상태
호출자 부담도구 결과 조립결과만 받음

같은 기능, 어느 쪽에?

문서 요약 기능이 있다. 로 낼까, 로 낼까? 결정 기준 3가지:

  1. 재량의 폭 — LLM이 어떻게 부를지 결정해도 되면 MCP. 호출 측이 일관된 작업 정의를 원하면 A2A.
  2. 상태 보유 — 단발 함수 호출이면 MCP. 진행 추적·재개·취소가 필요하면 A2A.
  3. 결과 형태 — 즉시 응답 + LLM이 조립이면 MCP. 산출물(보고서·파일)이 필요하면 A2A .

규칙적으로 헷갈리면 이렇게: “LLM이 이 함수를 다섯 번 연달아 부를 가능성이 있나?” → 그렇다 = MCP, 아니다 = A2A.


MCP Transport: stdio vs HTTP

은 표준 두 가지를 제공한다.

거리같은 머신원격
인증OS 사용자OAuth·API Key
다중 클라이언트1:1N:1
적합로컬 도구공용 서버

MCP 서버 (Python)

공식 SDK는 mcp 패키지의 FastMCP. 한 줄, 한 줄로 띄운다. 데코레이터로 를 등록한다.

# Verified against: https://github.com/modelcontextprotocol/python-sdk
# Verified at: 2026-06-02
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("calculator")

@mcp.tool()
def add(a: int, b: int) -> int:
  """두 수를 더한다."""
  return a + b

@mcp.resource("user://{name}")
def user(name: str) -> str:
  return f"profile of {name}"

if __name__ == "__main__":
  # 로컬 stdio (Claude Desktop 등이 자식으로 띄움)
  mcp.run(transport="stdio")
  # 또는 원격 HTTP:
  # mcp.run(transport="streamable-http")

MCP 클라이언트의 모양

는 보통 호스트 앱 안에 산다. 시작 시 list_tools 목록을 받고, LLM이 부르겠다고 한 도구만 골라 call_tool로 실행한다.

# Verified against: https://github.com/modelcontextprotocol/python-sdk
# Verified at: 2026-06-02
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

async def main():
  params = StdioServerParameters(command="python", args=["server.py"])
  async with stdio_client(params) as (read, write):
      async with ClientSession(read, write) as session:
          await session.initialize()
          tools = await session.list_tools()
          print([t.name for t in tools.tools])
          r = await session.call_tool("add", {"a": 2, "b": 3})
          print(r.content)

asyncio.run(main())

A2A와 비교한 호출 흐름

다이어그램 로딩…

핵심 차이는 누가 을 부르는가다.

그래서 같은 “PDF 요약” 기능이라도, MCP는 문장 추출 도구에 가깝고, A2A는 요약 에이전트다.


Claude Desktop 통합 예

가 가장 먼저 자리잡은 곳은 Anthropic의 Claude Desktop. 설정 파일에 를 등록하면, 대화 중 목록에서 자동 라우팅한다.

{
  "mcpServers": {
    "calculator": {
      "command": "python",
      "args": ["/path/to/server.py"]
    }
  }
}

호스트 앱 → 로 자식 프로세스 띄움 → 도구 목록 가져옴 → 사용자 발화에 따라 자동 호출. 는 보이지 않게 동작한다.


같이 쓰는 경우 — MCP 안의 A2A 스킬

흥미로운 패턴: 얇은 로 감싸 에게 노출하는 것. 이렇게 하면 같은 LLM 호스트가 일반 와 동료 구분 없이 부른다.

# Verified against: https://github.com/modelcontextprotocol/python-sdk
# Verified at: 2026-06-02
from mcp.server.fastmcp import FastMCP
import httpx

mcp = FastMCP("a2a-bridge")

@mcp.tool()
async def call_researcher(topic: str) -> str:
  """A2A Researcher에게 보고서 요청."""
  body = {
      "jsonrpc": "2.0", "id": 1, "method": "message/send",
      "params": {"message": {"messageId": "m1", "role": "user",
                              "parts": [{"text": topic}]}},
  }
  async with httpx.AsyncClient() as c:
      r = await c.post("https://example.com/a2a/v1", json=body)
      return r.json()["result"]["status"]

결정표

상황선택이유
read_file, search_web작고 무상태, 이 조합
보고서 작성 작업 단위 크고 상태 추적
같은 머신 빠른 도구오버헤드 0
사내 공용 도구 게이트웨이인증·다중 클라이언트
외부 회사가 만든 에이전트A2A표준 인증·상태·취소

규칙: 사람 한 명이 손으로 할 수 있을 만큼 단순한 일은 MCP. 다른 사람을 시킬 만한 일이면 A2A.


안티 패턴 모음

큰 그림은 단순하다 — 입자 크기로 갈라라.


다음 챕터로

이제 흥미로운 경계가 보인다. 는 도구를 표준화하고, 는 에이전트를 표준화한다. 그런데 에이전트를 도구처럼 부른다면? 다음 장에서는 ··의 경계를 다시 본다.