1. 왜 별도의 프로토콜이 필요한가
이 모듈에서 우리는 마침내 MCP (Model Context Protocol)가 무엇이며 ChatGPT App 스택에 어떻게 들어맞는지 이해하게 됩니다. 먼저 아키텍처에서 MCP의 위치를 고정하고, “전형적인 REST”와 비교한 뒤, 프로토콜의 주요 엔터티인 tools, resources, prompts를 살펴보겠습니다.
일반적인 웹 서비스를 만든다고 가정해 봅시다. 익숙한 방식대로 여러분은 REST API를 올립니다. /api/gifts, /api/users, /api/orders 같은 엔드포인트가 있고, 각 엔드포인트는 고유한 입력/출력 포맷, 오류 코드, 인증 방식을 가집니다. 익숙하긴 하지만 한 가지 문제가 있습니다. 여러분은 각 클라이언트에게 무엇을 어떻게 구현했는지 설명해야 합니다. 문서, OpenAPI, 예제, SDK — 이 모든 것이 필요한 이유는 API 포맷을 여러분이 직접 정의했기 때문입니다.
ChatGPT App에서는 상황이 더 복잡해집니다. 여러분의 클라이언트는 프런트엔드뿐만 아니라 모델 자체이기도 합니다. 모델은 다음이 필요합니다:
- 어떤 작업이 가능한지 파악하기;
- 각 작업에 필요한 인수가 무엇인지 이해하기;
- 대화 중에 이 작업들을 호출하기 — 때로는 여러 번, 때로는 다른 매개변수로;
- 구조화된 응답을 해석하고, 사용자에게 무엇을 보여줄지와 다음 발화를 위한 컨텍스트로만 무엇을 사용할지 결정하기.
각 개발자가 자신만의 API 포맷을 만든다면, 모델은 통합 지옥에 빠집니다. App마다 커스텀 클라이언트, 엄청난 “보일러플레이트”, 그리고 취약한 로직이 필요해질 것입니다. 이 문제는 프로토콜이라는 아이디어로 해결됩니다.
MCP (Model Context Protocol)은 LLM 클라이언트(ChatGPT, IDE 플러그인, 에이전트 등)가 여러분의 도구 및 데이터 서버와 통신하는 표준 방식을 정의한 공개 사양입니다. 서버가 자신의 도구, 리소스, 프롬프트를 선언하는 공통 언어를 제공하며, 클라이언트는 그것들을 호출하고 결과를 받습니다.
직관적으로 MCP는 AI 세계의 USB‑C 포트와 같습니다. 여러분이 “USB 플래시 드라이브”(서비스, 데이터베이스, CRM, 검색 엔진)를 만든다면 표준 커넥터 하나만 구현하면 됩니다. 그러면 어떤 “노트북”(ChatGPT, 다른 에이전트, IDE)도 커스텀 케이블 없이 여러분에게 연결될 수 있습니다.
2. 높은 시야에서 보기: ChatGPT App 아키텍처에서 MCP의 위치
그림을 고정하기 위해, 이제는 MCP 레이어를 명시해서 이미 익숙한 아키텍처를 떠올려 봅시다.
여러분이 이미 본 멘탈 모델은 이렇습니다. 사용자는 ChatGPT와 대화하고, 대화 안에서 위젯(Apps SDK)이 렌더링되며, 어딘가 밖에는 여러분의 백엔드가 존재합니다. 이제 MCP를 추가하고 모든 것을 레이어로 나눠봅시다.
간단한 다이어그램은 다음과 같습니다:
사용자
↓ (자연어)
ChatGPT (모델 + UI)
↓ (MCP를 통한 tool calls)
ChatGPT 내부의 MCP 클라이언트
↓ (JSON-RPC, MCP)
여러분의 MCP 서버 (backend)
↓
여러분의 DB / 외부 API / 큐
여기서 “ChatGPT 내부의 MCP 클라이언트”는 여러분의 MCP 서버와 프로토콜로 통신하는 플랫폼 내부 구성 요소를 의미합니다. 이 클라이언트는 디스커버리를 수행하고, 도구를 호출하며, 리소스를 읽습니다.
Apps SDK 관점에서 최소한의 ChatGPT App은 세 가지 컴포넌트로 구성됩니다. 첫째 — 도구를 선언하고 구조화된 데이터를 반환하는 MCP 서버. 둘째 — ChatGPT 내부에서 렌더링되고 이 데이터를 window.openai를 통해 읽는 UI 번들(위젯). 셋째 — 어떤 도구를 언제 호출하고 사용자에게 어떻게 응답할지 결정하는 모델 자체입니다.
여기서 중요한 점은 다음과 같습니다. 이전 모듈들에서는 Apps SDK와 위젯 수준, 즉 도식의 상단에서 많이 작업했습니다. 이제 우리는 MCP 서버 레벨로 내려갑니다 — 이것이 ChatGPT 및 여러분의 App을 사용하려는 다른 모든 클라이언트와의 공식적인 “대화의 언어”입니다.
3. MCP vs “전형적인 REST”: 무엇이 다른가
위의 그림에서 MCP가 ChatGPT App 아키텍처에서 어디에 있는지 확인했습니다. 이제 “자체 REST” 접근법과 MCP를 조심스럽게 비교해 보겠습니다. 왜 ChatGPT Apps 맥락에서 두 번째가 거의 항상 이기는지 이해할 수 있을 것입니다.
REST 접근에서는 엔드포인트, 요청/응답 포맷을 여러분에게 편한 방식으로 설계합니다. 여러분과 작업하려는 클라이언트는 URL, 메서드, 스키마, 오류 코드를 알아야 합니다. 때로는 OpenAPI가 도움이 되고, 때로는 단순히 README에 요청 예시를 던져 넣기도 합니다. 모델은 이 모든 것을 스스로 이해하지 못합니다. “엄마에게 50세 생일 선물 골라줘”를 구체적인 HTTP 요청으로 바꾸어 주고, 다시 JSON 응답을 대화에 적합한 데이터로 바꾸어 주는 코드 레이어가 필요합니다.
MCP에서는 모든 것이 다릅니다. 프로토콜 자체가 다음을 규정합니다:
- 클라이언트가 어떻게 여러분의 도구 목록을 알아낼 수 있는지;
- JSON Schema로 인수와 결과를 어떻게 기술하는지;
- 리소스와 프롬프트를 어떻게 기술하는지;
- 도구 호출과 그 응답이 어떻게 생겼는지.
덕분에 ChatGPT 및 다른 MCP 클라이언트는 자동으로 다음을 수행할 수 있습니다:
- discovery 실행 — 여러분에게 어떤 tools/resources/prompts가 있는지 알아냄;
- 각 도구에 대한 내부 매개변수 스키마를 구성;
- 커스텀 하드코드 클라이언트 로직 없이 호출;
- 메타데이터를 캐시하고 앱 검색/랭킹에 활용.
차이를 간단한 표로 정리할 수 있습니다.
| 질문 | 자체 REST / gRPC | MCP |
|---|---|---|
| 클라이언트는 여러분이 무엇을 할 수 있는지 어떻게 알나요? | 문서, README, OpenAPI에서 | 표준 discovery 메서드( tools/resources 목록 )를 통해 |
| 누가 매개변수를 기술하나요? | 여러분이 임의로(JSON, FormData 등) | 도구 필드의 JSON Schema |
| 모델은 함수를 어떻게 호출하나요? | 여러분의 커스텀 클라이언트 코드 경유 | MCP 프리미티브를 통해 직접 |
| 클라이언트 측 보일러플레이트는 얼마나 있나요? | 많고 서비스마다 다름 | 모든 MCP 서버에 공통인 하나의 프로토콜 |
| 복수 클라이언트 지원 | 클라이언트마다 SDK를 작성해야 함 | MCP 서버는 자체 문서화를 제공하며, 클라이언트는 로직을 재사용 가능 |
감정적으로 표현하자면: REST는 “각자도생”, MCP는 “모델과 데이터와 소통하는 생태계 구성원 모두의 합의”입니다.
4. MCP의 주요 엔터티: tools, resources, prompts
이제 MCP의 세 주인공 — 도구(tools), 리소스(resources), 프롬프트(prompts)를 이름대로 불러 봅시다.
Tools: 이미 익숙한 액션
tools는 모듈 4에서 이미 다뤘습니다. 거기서 우리는 도구를 정의하고, 이름과 설명, JSON Schema 인수를 제공했으며, 모델은 callTool을 통해 그것을 호출했습니다. MCP 레벨에서 도구는 명확한 계약을 가진 서버 사이드 연산입니다:
- 이름과 설명(모델과 UX/디스커버리를 위해);
- 인수를 위한 JSON Schema;
- 결과 구조에 대한 JSON Schema 또는 설명;
- 추가 메타정보(예: Apps SDK의 특정 UI 컴포넌트와의 바인딩).
MCP 서버는 최소한 “도구 목록 요청”에 응답하고 “도구 호출”을 처리하여 구조화된 결과를 반환할 수 있어야 합니다.
우리의 학습용 Gift 도우미 애플리케이션에는 예를 들어, suggest_gifts라는 도구가 있다고 합시다. 이는 나이, 성별, 예산, 몇 가지 선호도를 받아 추천 선물 목록을 반환합니다.
MCP 서버 코드에서의 가상의 TypeScript 스케치(의사 코드/스텁)는 대략 다음과 같을 수 있습니다:
// 의사 코드, 최종 SDK API 아님
const suggestGiftsTool = defineTool({
name: "suggest_gifts",
description: "받는 사람의 파라미터에 따라 선물 아이디어를 추천합니다",
inputSchema: z.object({
age: z.number(),
relation: z.enum(["friend", "partner", "parent"]),
budgetUsd: z.number(),
}),
handler: async (input) => {
// TODO: 여러분의 비즈니스 로직
return { items: [] };
},
});
실제 시그니처는 다음 강의에서 다루겠지만, 여기서 중요한 아이디어는 이것입니다. 도구는 단순한 REST 엔드포인트가 아니라, 선언된 스키마를 가진 프로토콜의 구성 요소입니다.
리소스(resources): ID/URI로 접근 가능한 데이터
MCP의 리소스(resources)는 사용 가능한 데이터를 기술하는 방법입니다. 파일, 디렉터리, DB 레코드, 위키 페이지, 심지어 검색 인덱스 결과까지 포함합니다. 클라이언트는 다음을 할 수 있습니다:
- 리소스 목록을 가져오기;
- ID/URI로 특정 리소스를 읽기;
- 때로는 — 그 위에서 검색을 수행하기.
무언가를 “하는” tools와 달리, resources는 대개 무언가를 “저장”합니다. 예를 들어 Gift App에서는 상품 카탈로그를 리소스 gift_catalog로 표현할 수 있습니다. 모델은 여기에 접근해 사용 가능한 카테고리, 필터, 가격대 등을 파악합니다.
코드에서 개념적으로는 다음처럼 보일 수 있습니다:
const giftCatalogResource = defineResource({
uri: "catalog://gifts",
description: "추천에 사용할 수 있는 선물 카탈로그",
read: async () => {
// 카탈로그 구조를 반환합니다
return { categories: [], priceRanges: [] };
},
});
아직 MCP 메시지 포맷의 세부로 들어가지는 않지만, 핵심은 이렇습니다. 리소스는 주소 지정 가능한 엔터티이며, MCP 서버는 이를 참조할 수 있고 클라이언트는 읽어 컨텍스트의 일부로 사용할 수 있습니다.
Prompts: 미리 준비된 힌트
MCP 맥락에서 Prompts는 서버가 클라이언트에게 제공할 수 있는 요청/지시 템플릿입니다. 예를 들어 gift_followup 프롬프트를 선언해, 도구를 호출하기 전에 모델이 사용자에게 받는 사람에 대한 세부사항을 어떻게 추가로 물어봐야 하는지를 기술할 수 있습니다.
프로토콜의 전형적인 예에서는 서버가 프롬프트 이름, 목적, 때로는 매개변수를 제공합니다. 클라이언트는 프롬프트 목록을 요청하고, 필요한 것을 선택하여 모델 요청에 끼워 넣을 수 있습니다.
이것이 ChatGPT App에 왜 유용할까요? 첫째, 복잡한 프롬프트를 클라이언트 사이에서 재사용하는 표준 방법입니다. 둘째, MCP는 이런 프롬프트를 임의의 코드 구석에 숨기지 않고, 명시적이고 계약의 일부로 만듭니다.
Capabilities: 여러분이 지원하는 것의 선언
마지막으로 네 번째 요소는 capabilities입니다. 이것은 단순한 선언입니다. 서버가 tools, resources, prompts, 알림 등 어떤 엔터티를 지원하는지와 어떤 메서드를 구현하는지를 말합니다. 클라이언트는 이를 통해 무엇을 할 수 있고 무엇을 할 수 없는지 추측할 필요 없이 서버의 역량에 맞춰 자신의 동작을 조정할 수 있습니다.
실제로 ChatGPT가 여러분의 MCP 서버에 연결될 때, 먼저 “핸드셰이크”를 수행하고 capabilities 목록을 받은 뒤, “좋아, 너의 도구와 리소스를 보여줘”라고 요청합니다.
5. MCP는 현재 App에 어떻게 통합되는가
겉보기엔 조금 추상적으로 들리지만, 사실 여러분은 이미 Apps SDK를 통해 MCP를 접했습니다. 지금 작성한 Apps SDK와 어떻게 맞물리는지부터 이해해 봅시다. 방금 소개한 엔터티들을 현재 App 템플릿과 연결해 보겠습니다.
템플릿에서 이미 구현한 체인을 떠올려봅시다:
- 위젯은 window.openai 또는 준비된 훅을 통해 도구 이름과 인수로 callTool을 호출합니다.
- ChatGPT 내부의 Apps SDK가 이를 App의 서버 측 호출로 변환합니다.
- 서버는 도구를 실행하고 ToolOutput을 반환합니다. 여기에는 structuredContent, content, _meta가 포함됩니다.
- 위젯은 ToolOutput을 받아 UI를 렌더링합니다.
비밀은 2–3단계가 MCP 대화로 구현되어 있다는 점입니다. 여러분의 Next.js 템플릿에는 엔드포인트(일반적으로 app/mcp/route.ts 또는 유사한 파일)가 있으며, 이것이 바로 MCP 서버입니다. 이 서버는:
- 여러분의 도구를 등록하고;
- JSON Schema로 이를 기술하며;
- 핸들러를 구현하고;
- ChatGPT의 MCP 요청 list tools와 call tool에 응답합니다.
즉, 템플릿을 사용하는 지금도 이미 MCP를 “자동으로” 다루고 있는 셈입니다. 프로토콜의 많은 마법은 SDK 내부에 숨겨져 있습니다.
모듈 6의 목적은 MCP를 “마법의 블랙박스”로 여기지 않고, 이를 의식적으로 설계할 수 있게 되는 것입니다:
- 도구를 추가하고 버저닝하기;
- tools뿐 아니라 resources와 prompts도 사용하기;
- MCP 로그를 읽고 이해하기;
- 필요하다면 Next.js 템플릿 밖에서 별도의 MCP 서버를 띄우기(예: ML 모델용 Python 서비스나 사내 DB 접근 전용 서비스).
6. 서로 다른 역할의 관점에서 본 MCP: 프로덕트 vs 개발자
MCP가 프로덕트 매니저에게 주는 것과 엔지니어에게 주는 것을 따로 정리하면 유용합니다.
MCP — 프로덕트를 위해
제품 관점에서 MCP는 여러분의 서비스를 ChatGPT, 기타 LLM 클라이언트, IDE 플러그인, 사내 에이전트 등 다양한 클라이언트에 대한 “플러그인 모듈”로 만드는 방법입니다. 한 번 서버의 역량을 tools/resources/prompts 세트로 기술해 두면, 어떤 클라이언트라도 다음을 할 수 있습니다:
- 자동으로 여러분의 서비스를 발견하고;
- 어떤 문제를 해결하는지 이해하며;
- 필요한 연산을 안전하게 호출합니다.
ChatGPT App의 경우, 이는 앱이 선택될 확률을 높여 주기도 합니다. 모델은 여러분의 도구 메타데이터를 사용해 언제 사용자에게 앱을 제안할지, 그리고 어떻게 적절히 표시할지 판단합니다.
한 마디로 요약하면: MCP는 여러분의 서비스를 특정 한두 클라이언트용 커스텀 통합이 아니라, 생태계의 표준 “블록”으로 만들어 줍니다.
MCP — 개발자를 위해
엔지니어 관점에서 MCP는 계약이자 프로토콜입니다. 다음 질문에 답합니다:
- 도구를 어떤 포맷으로 선언해야 하는가?
- 인수를 어떻게 기술하고 결과를 어떻게 반환해야 하는가?
- 클라이언트가 내가 리소스와 프롬프트를 지원한다는 것을 어떻게 알게 되는가?
- 네트워크를 오가는 JSON은 정확히 어떤 형태인가?
이러한 프로토콜이 있으면 더 쉬워집니다:
- 서로 다른 언어로 서버를 작성하기(TypeScript와 Python용 공식 SDK가 있음);
- MCP Inspector 또는 유사한 도구로 애플리케이션을 디버깅하기;
- 팀 간 책임을 나누기: 한 팀은 데이터/도구가 있는 MCP 서버를 만들고, 다른 팀은 Apps SDK 위젯을 만들며, 세 번째 팀은 같은 MCP 서버 위에 자체 에이전트를 구축할 수 있습니다.
7. 작은 실전 관점: 우리의 첫 번째 MCP 서버
이 강의에서는 의도적으로 메시지 포맷과 서버 구현의 디테일로 들어가지 않습니다 — 다음 주제의 재료입니다. 하지만 미리 우리가 어디로 가는지 감을 잡기 위해, TypeScript로 된 최소 MCP 서버의 전체 구조를 보는 것이 도움이 됩니다.
현실에서는 공식 MCP TypeScript 라이브러리가 서버 생성, tools/resources/prompts 등록, 트랜스포트(보통 HTTP 또는 SSE) 구동을 위한 프리미티브를 제공합니다.
가상의 의사 예시는 다음과 같을 수 있습니다:
// 이것은 개념적 예시이며, SDK API는 나중에 다룹니다
import { createServer } from "@modelcontextprotocol/sdk";
const server = createServer({
name: "gift-genius",
version: "1.0.0",
});
// 도구 등록
server.tool("suggest_gifts", {
description: "받는 사람의 선호에 따라 선물을 추천합니다",
inputSchema: {/* ... */},
handler: async (input) => {
// 여러분의 로직
return { items: [] };
},
});
// 트랜스포트 시작(예: HTTP)
server.listen(3001);
중요한 점: 여기 어디에도 ChatGPT, Apps SDK, 또는 특정 프런트엔드가 언급되지 않습니다. MCP 서버는 자족적입니다. 그저 MCP 요청에 응답할 줄 알 뿐입니다. ChatGPT App은 그러한 서버를 사용할 수 있는 클라이언트 유형 중 하나일 뿐입니다.
이 강의에서는 Next.js 템플릿을 사용하며, MCP 서버는 프로젝트의 일부로 존재합니다. 하지만 이것만이 가능한 유일한 방식은 아닙니다.
8. 생태계에서의 MCP: Apps SDK, Agents SDK, 그리고 ACP
MCP를 “Apps SDK만의 기능”으로 보지 않기 위해, 더 넓은 그림 속에서 바라보는 것이 좋습니다.
첫째, Apps SDK는 ChatGPT와 외부 서비스 사이의 표준 브리지로서 MCP에 직접 의존합니다. 공식 문서는 Apps SDK가 모든 MCP 서버와 함께 작동한다고 강조합니다. 프로토콜 자체는 도구를 기술하고 구조화된 데이터를 반환하며 UI에서 렌더링할 컴포넌트를 지정할 수 있게 합니다.
둘째, 별도의 모듈에서 다룰 Agents SDK 역시 MCP 서버에 연결할 수 있습니다. 이는 동일한 비즈니스 로직을 가진 MCP 서버를 다음과 같이 재사용할 수 있음을 의미합니다:
- 여러분의 App 일부로 ChatGPT 내부에서;
- 예컨대 제품 백그라운드나 배치 모드에서 동작하는 자율 에이전트 내부에서.
셋째, 구매와 Instant Checkout에 필요한 ACP(Agentic Commerce Protocol)는 논리적으로 MCP 접근 위에 구축됩니다. 모델과 에이전트는 커머스 도구를 호출하며, 이들 역시 표준화된 계약으로 기술됩니다.
이러한 방식으로 MCP는 UI(Apps SDK), 에이전트 시나리오(Agents SDK), 커머스(ACP)가 그 위에 구축되는 토대가 됩니다. MCP를 확실히 이해한다면 나머지는 더 명확하고 예측 가능해집니다.
프리미엄 노트: 형식적으로 ACP는 사양으로서 반드시 의존하지는 않습니다 MCP에. 하지만 실제 구현에서는 ACP 도구가 대개 모델을 통해 MCP 인터페이스로 호출될 가능성이 큽니다. 두 접근은 매우 아름답게 겹쳐지므로, 우리가 기다릴 시간은 그리 길지 않을 것입니다.
9. 실전에 앞선 작은 “머릿속” 연습
다음 강의에서 MCP 메시지 포맷으로 뛰어들기 전에, 몇 가지 사고 실험을 해보는 것이 좋습니다. 이렇게 하면 “전형적인 REST”에서 “프로토콜 + 계약”으로 사고를 전환하는 데 도움이 됩니다.
여러분의 Gift App에 연결하려는 클라이언트가 ChatGPT뿐 아니라 VS Code용 IDE 플러그인과 Slack의 사내 어시스턴트라고 상상해 보세요. 이들 모두가 여러분의 서비스에 대해 알아야 할 것을 한 문장으로 설명해 보세요. 아마도 답은 대략 이럴 것입니다. “우리에게는 suggest_gifts 도구가 있고 이런 매개변수가 있으며, 선물 카탈로그는 이런 리소스로 접근 가능하다.” 이것이 바로 MCP가 형식화하는 내용입니다.
또한 두 문장으로 정리해 보세요:
- 여러분 App의 프로덕트를 위해 MCP란 무엇인가(힌트: 다양한 클라이언트를 위해 기능을 “패키징”하는 표준 방법);
- 개발자를 위해 MCP란 무엇인가(힌트: 명확한 tools/resources/prompts 프리미티브를 가진 JSON‑RPC 프로토콜).
이것을 막힘없이 설명할 수 있다면 — 이미 MCP를 자신 있게 다룰 준비의 반은 끝났습니다.
위의 모든 것을 하나의 명제로 요약하면: MCP는 또 하나의 상위 API가 아니라, 여러분의 로직과 LLM 클라이언트 사이의 기본 계약입니다. 다음 강의에서는 프로토콜 내부를 들여다보겠습니다. MCP 메시지 포맷, 핸드셰이크/capabilities를 분석하고, 인스펙터를 통해 트래픽을 관찰하는 법을 배워 이 모든 원칙을 추상론이 아닌 실전 도구로 만들겠습니다.
10. MCP를 둘러싼 흔한 실수와 오해
오류 №1: MCP를 “내 REST 위에 얹는 또 하나의 API 레이어”로 간주하기.
때때로 이런 유혹이 생깁니다. “이미 REST가 있으니, MCP 호출을 REST로 변환하고 그 반대로 바꿔주는 얇은 어댑터만 두고 잊자.” 형식적으로 가능하지만, 그러면 종종 기존 API의 특이점이 MCP 내부로 “침투”하기 시작합니다. 이상한 타입, 비구조적 응답, 명시적 스키마 부재 등입니다. 시간이 지나면 어댑터만 거대해지고 MCP의 이점은 줄어듭니다. MCP를 기본 계약으로 보고, 기존 REST는 아직 필요하다면 내부 구현 디테일로 취급하는 편이 낫습니다.
오류 №2: MCP가 “ChatGPT Apps 전용”이라고 생각하기.
MCP는 ChatGPT, IDE 플러그인, 자율 에이전트 등 어떤 LLM 클라이언트에도 통용되는 공개 프로토콜입니다. 특정 App 하나만을 염두에 두고 MCP 서버를 설계하면 스스로를 제약하게 됩니다. “이 서버는 다른 클라이언트도 사용할 수 있다”라고 생각하고, 도구와 리소스를 조금 더 범용적으로 설계하는 편이 훨씬 유리합니다.
오류 №3: JSON Schema를 무시하고 인수를 “말로만” 설명하기.
SDK가 어딘가에서 “임의의 JSON”을 전달하게 해 준다 하더라도, 인수와 결과의 스키마를 성실히 기술하는 수고를 아끼지 마세요. 이는 모델이 여러분의 도구를 올바르게 호출하는 능력, 자동완성과 디스커버리 품질, 그리고 인스펙터를 통한 디버깅 편의에 직결됩니다. 기술되지 않았거나 잘못 기술된 인수는 불가사의한 tool‑call 오류로 가는 직행로입니다.
오류 №4: MCP를 “마법의 트랜스포트”로 여기고 로그를 보지 않기.
모든 것이 잘 동작할 때는 MCP가 생각할 필요 없는 보이지 않는 무언가처럼 느껴질 수 있습니다. 문제는 무언가가 고장 나는 순간입니다. MCP 구조를 이해하지 못하면 “이게 Apps SDK 문제인가? 모델 문제인가? 내 백엔드 문제인가?”를 오래 추측하게 됩니다. 초기에 MCP 메시지와 로그를 보는 습관은 무의미한 삽질의 시간을 줄여 줍니다.
오류 №5: 복잡한 워크플로를 REST로만 설계하고 MCP 프리미티브를 무시하기.
여러 단계의 시나리오(선물 검색 → 선호도 확인 → 선택 → 주문 처리)가 생기면, “그냥 하나의 큰 REST 엔드포인트를 만들자”라는 생각이 들 수 있습니다. 하지만 ChatGPT Apps 맥락에서는 관리성이 자주 떨어집니다. 모델은 중간 단계를 덜 잘 이해하고, MCP 클라이언트는 리소스와 프롬프트를 재사용할 기회를 잃습니다. 기능을 여러 개의 잘 기술된 tools/resources로 나누고, 시스템 프롬프트와 올바른 기술로 로직을 연결하는 편이 훨씬 좋습니다.
GO TO FULL VERSION