스탠퍼드 대학교 강의 CS146S(The Modern Software Developer) 자료를 읽으면서, AI와 논의하며 MCP를 이해했습니다. 그 과정에서 제가 무엇을 오해하고 있었는지 남겨둡니다.
처음에 걸린 부분
LLM이 가진 세계 지식은 학습한 시점에서 멈춰 있습니다. 완전히 자율적으로 움직이는 시스템을 만들려면, 새로운 데이터를 실시간으로 전달하는 메커니즘이 필요합니다. MCP(Model Context Protocol)는 그를 위한 공통의 규칙입니다. 매우 간단하게 말하면, LLM에게 도구를 보여줄 때의 표준 포맷이라고 할 수 있습니다.
MCP가 없다면, AI 앱마다, 도구마다 커넥터를 작성해야 합니다. 앱이 M개, 도구가 N개라면 M×N 가지가 됩니다. MCP를 사용하면, 도구 측에서 Server를 1개, 앱 측에서 Client를 1개만 준비하면 되어 M+N으로 줄어듭니다. 인증, 에러 처리, 레이트 제한을 매번 다시 만들 필요가 없다는 것도 큰 장점입니다.
등장인물은 세 가지
Host는 Cursor나 Claude Desktop처럼 사용자가 접하는 앱입니다. Client는 그 안에 내장된 통신용 라이브러리이며, MCP Server는 개별 도구 앞에 놓이는 얇은 Wrapper에 해당합니다.
저는 처음에 Agent와 MCP Client를 같은 것으로 생각했습니다. Agent 전체 중에서 Server와 대화하는 부분을 담당하는 것이 Client라고 분리해서 이해하는 편이 나중에 설명하기가 쉽습니다.
MCP 상호작용의 흐름
'Jack에게 온 이메일을 요약해 줘'라는 요청 상황으로 추적해 보겠습니다.
- Client가 MCP Server에게 '어떤 도구들이 있어?'라고 질문합니다. Server는 도구 이름, 용도, 인수를 JSON Schema(데이터 구조 정의)로 작성된 설명서를 반환합니다. 이는 보통 세션 초기화 시점에 완료됩니다.
- 사용자가 Host에 질문을 합니다.
- Client는 질문과 도구의 설명서를 모아서 LLM에게 전달합니다. LLM은 설명서를 읽고
search_emails(from="Jack")를 호출하기로 결정하고, Tool Call(도구 호출)을 구조화된 데이터로 출력합니다. - Client가 그 Tool Call을 받아 MCP Server에 실행을 요청합니다. Server는 내부적으로 Gmail API를 호출하여 결과를 반환합니다.
- Client가 결과를 LLM에게 전달하고, LLM이 사람 친화적인 문장으로 다듬어 답변합니다.
여기서 파악해야 할 것은, LLM은 '무엇을 어떤 인수로 호출할지'를 결정만 할 뿐, 스스로 네트워크에 나가지 않는다는 점입니다. 실제로 동작하는 것은 Client가 됩니다. LLM이 두뇌, Client가 손발이라고 생각하면 이해하기 쉽습니다.
막혔던 세 가지 오해
실제로 제가 잘못했던 부분을 3가지 언급합니다.
첫 번째는 MCP Server가 사용자의 요청을 보고 사용할 API를 스스로 찾는다고 생각한 것입니다. Server는 수동적인 도구 보관소이며, 판단하지 않습니다. 어떤 도구를 선택하고 어떤 인수를 전달할지 결정하는 것은 LLM입니다.
두 번째는 tools/list를 '사용자가 넣어둔 MCP 목록을 가져오는 작업'이라고 생각했던 것입니다. 이는 특정 Server에게 '당신은 어떤 도구들을 가지고 있니?'라고 묻는 작업이며, 어느 Server를 연결할지는 Host의 설정에 따라 결정됩니다.
세 번째는 사용자가 질문하기 전에 Client가 LLM에게 Tool Call을 던지고 있다고 생각했던 것입니다. Tool Call을 출력할 수 있는 것은 LLM뿐이며, 질문 전에 Client가 하는 일은 도구 목록을 가져와 Prompt 재료를 준비하는 것까지입니다.
MCP와 API는 무엇이 다른가?
| API | MCP | |
|---|
| 사용하는 쪽 | 개발자, 기존 프로그램 | LLM, Agent |
| ... | | |
| MCP Server는 대부분의 경우 내부적으로 API를 호출합니다. 따라서 MCP는 'API를 LLM용으로 포장한 것'이라고 보면 대체로 맞습니다. 다만 '대부분의 경우'라는 것이고, 로컬 파일이나 데이터베이스를 직접 건드리는 Server도 있기 때문에 반드시 API가 뒤에 있다는 것은 아닙니다. | | |
도구가 늘어났을 때의 설계
강의에서는 MCP Server의 설계에 대해 두 가지 방향성이 나왔습니다.
1. 동작이 아닌 결과로 도구 만들기
REST API를 그대로 도구로 분해하지 않습니다. 예를 들어 송금이라면, get_users
→ list_account
→ send_payment
이렇게 3개로 나누어 Agent에게 구성시키는 것보다, send_payment(user_email)처럼 하나를 준비하는 것이 Agent가 헤매지 않게 한다. 인수에 중첩된 딕셔너리를 사용하지 않는 것, docstring이나 에러 메시지를 LLM이 읽는다는 전제하에 작성하는 것, 도구 이름에 서비스명 접두사를 붙이는 것도 언급되었다.
2. 검색과 실행을 분리하기
Server가 대량으로 늘어나면 모든 도구의 설명서를 처음부터 Prompt에 넣는 것은 너무 무겁다. 그래서 LLM에게 보여줄 도구를 search와 execute 두 개로만 만든다. LLM은 먼저 search로 필요한 도구를 찾고, 그다음 execute로 실행한다. 강의에서는 이렇게 하면 토큰이 90% 이상 줄어들고, Server의 수에도 의존하지 않게 된다고 설명되었다.
차이는 설명서를 보여주는 타이밍에 있다. 전부를 처음부터 보여줄지, 아니면 간략한 목차만 보여주고 필요할 때 내용을 가져올지. 후자가 '필요해진 후에 로드한다'는 생각이다.
Skills는 MCP 위에 무엇을 더하는가
자료에서는 Agent Skills를 특정 영역에 맞춰 코드와 Prompt를 세트로 묶어, 필요한 시점에 불러오는 표준적인 능력의 집합이라고 설명하고 있었다. 사용처로는 문서 작성, PowerPoint 작성, 데이터 분석 등이 있다.
Figma로 생각하면 이해하기 쉽다. Figma의 MCP만 있어도 Agent는 create_frame 같은 도구가 있다는 것은 알지만, 웹 페이지 설계의 작법까지는 모른다. 위치가 어긋난 사각형들이 나열된 화면이 될 수도 있다. 여기에 figma-web-design이라는 Skill을 추가한다. 1440px 루트 프레임을 만들고, 색이나 글자 규칙을 정하고, Header, Hero, Feature Grid, Footer 순서로 조합하며, Auto Layout을 활성화하는 등의 절차를 적어 놓는 것이다.
내 이해는 이렇다. MCP는 '그 도구를 사용할 수 있는지'를 결정하고, Skills는 '그 도구를 잘 사용할 수 있는지'를 결정한다.
하지만 Skill이 MCP에 반드시 의존하는 것은 아니다. Skill은 스스로 스크립트를 가질 수 있기 때문에, Figma의 REST API를 직접 호출하는 구조도 가능하다. MCP는 표준화된 도구의 통로이고, Skill은 진행 방법의 지식을 담당하며, 이 둘을 조합했을 때 가장 잘 작동한다는 정도의 설명이 정확하다.
마지막으로 세 가지를 나란히 놓아본다.
| 무엇 | 누가 사용하는가 | 주요 용도 |
|---|
| API | 앱이 외부에 공개하는 HTTP, REST, GraphQL 연결구 | 개발자, SDK |
| ... | | |
참고
CS146S The Modern Software Developer https://themodernsoftware.dev/
Discussion