실습 노트

MCP 서버를 붙일 때 먼저 나눌 것: 도구·리소스·프롬프트

MCP 서버를 만들거나 고를 때 자주 섞이는 도구·리소스·프롬프트의 역할을 공식 사양 기준으로 나눠 정리했습니다.

보일러플레이트MCP · AI 에이전트 · API 설계 · 자동화

MCP 서버를 처음 붙일 때 가장 먼저 생기는 혼동은 기능을 전부 "AI가 쓸 수 있는 것"으로 뭉뚱그리는 데서 시작합니다. 파일을 읽는 기능, 캘린더 일정을 만드는 기능, 자주 쓰는 프롬프트를 제공하는 기능이 한 화면에 보이면 모두 같은 종류처럼 느껴집니다.

공식 Model Context Protocol(MCP) 사양에서는 이 셋을 다른 표면으로 나눕니다. **도구(tools)**는 모델이 호출해 작업을 실행하는 기능이고, **리소스(resources)**는 애플리케이션이 읽을 수 있는 컨텍스트이며, **프롬프트(prompts)**는 사용자가 선택해 대화에 넣는 재사용 가능한 템플릿입니다. 2025-06-18 공식 사양의 서버 기능 구분을 기준으로 정리해봤습니다.

한 줄로 나누면 이렇습니다

표면 누가 시작하나 역할 예시
도구 모델 외부 작업을 호출 파일 저장, API 요청, 일정 생성
리소스 애플리케이션 읽을 컨텍스트를 제공 파일 내용, 문서, 데이터베이스 조회 결과
프롬프트 사용자 정해진 입력 형식을 선택 코드 리뷰 템플릿, 문서 요약 양식

여기서 "누가 시작하나"가 실무에서 특히 중요합니다. 도구는 모델이 필요하다고 판단해 호출할 수 있지만, 리소스는 호스트 애플리케이션이 모델의 컨텍스트에 포함할 대상을 결정합니다. 프롬프트는 사용자가 목록에서 골라 대화 시작점으로 쓰는 쪽에 가깝습니다.

도구는 실행 경계를 만든다

MCP 사양의 도구는 서버가 모델에 노출하는 실행 가능한 함수입니다. 도구에는 이름과 설명이 있고, 입력 인자를 JSON Schema로 설명할 수 있습니다. 클라이언트는 tools/list로 사용 가능한 도구를 확인하고, 모델이 선택하면 tools/call로 호출합니다. 자세한 요청·응답 형태는 공식 Tools 사양에 나와 있습니다.

예를 들어 다음 기능은 도구로 보는 편이 자연스럽습니다.

  • 특정 폴더에 파일을 저장한다.
  • GitHub 이슈를 만든다.
  • 외부 API에 데이터를 전송한다.
  • 데이터베이스의 레코드를 수정한다.

공통점은 호출 결과만 받는 것이 아니라 외부 상태가 바뀔 수 있다는 것입니다. 그래서 도구 이름과 설명만 대충 쓰면 안 됩니다. 어떤 입력을 받는지, 실패했을 때 무엇을 반환하는지, 되돌릴 수 있는지, 권한이 필요한지를 함께 설계해야 합니다.

읽기 기능도 도구로 만들 수 있습니다. 다만 단순히 문서나 데이터를 읽어 컨텍스트로 넣는 목적이라면 리소스가 더 맞을 수 있습니다. 반대로 검색 조건을 받아 매번 계산하거나, 권한 확인과 함께 동작하거나, 결과를 만들기 위해 서버 로직을 실행해야 한다면 도구로 노출하는 쪽이 명확합니다.

리소스는 읽을 대상을 설명한다

리소스는 서버가 제공하는 읽기 전용 데이터의 표면입니다. 각 리소스는 URI로 식별되고, 클라이언트는 resources/list로 목록을 확인하거나 resources/read로 내용을 읽습니다. 파일 하나의 URI일 수도 있고, 애플리케이션이 해석할 수 있는 커스텀 URI일 수도 있습니다. 세부 규칙은 공식 Resources 사양에 정리되어 있습니다.

리소스로 생각하기 쉬운 것은 다음과 같습니다.

  • 프로젝트의 README.md
  • 특정 문서의 현재 내용
  • 사용자가 선택한 회의록
  • 서버가 제공하는 고정된 참고 자료

리소스는 "모델이 알아서 실행하는 함수"라기보다 호스트가 컨텍스트로 가져올 수 있는 데이터 주소입니다. 따라서 파일을 수정하는 동작을 리소스로 감싸면 역할이 흐려집니다. 읽기는 리소스, 수정은 도구로 분리하면 사용자가 승인해야 하는 작업과 단순 참고 자료를 구분하기 쉬워집니다.

리소스 URI가 실제 파일 경로를 그대로 노출해야 한다는 뜻도 아닙니다. 서버는 docs://project/intro 같은 URI를 정의하고 내부에서 데이터 저장소를 조회할 수 있습니다. 외부에 어떤 데이터를 공개할지와 내부 저장 방식을 분리할 수 있다는 점이 핵심입니다.

프롬프트는 기능이 아니라 선택 가능한 시작점이다

프롬프트는 사용자가 선택해 대화에 넣는 템플릿입니다. 클라이언트는 prompts/list로 프롬프트 목록을 보고, 사용자가 고른 프롬프트를 prompts/get으로 가져옵니다. 매개변수를 받아 같은 작업의 시작 문장을 상황에 맞게 만들 수도 있습니다. 기준은 공식 Prompts 사양에서 확인했습니다.

예를 들어 MCP 서버가 다음 프롬프트를 제공할 수 있습니다.

  • review-code: 언어와 파일 경로를 받아 코드 리뷰 요청문을 만든다.
  • summarize-meeting: 회의록 리소스를 요약하는 대화 시작점을 만든다.
  • explain-error: 오류 메시지와 실행 환경을 넣어 분석 요청문을 만든다.

프롬프트는 모델에게 권한을 주는 기능이 아닙니다. 프롬프트 자체가 파일을 저장하거나 API를 호출하지도 않습니다. 다만 프롬프트가 도구와 리소스를 어떻게 사용하게 할지 안내하는 출발점이 될 수 있으므로, 이름과 설명이 실제 동작을 과장하지 않아야 합니다.

같은 기능을 어디에 둘지 판단하는 기준

새 기능을 MCP 서버에 추가할 때는 아래 순서로 질문하면 됩니다.

1. 외부 상태를 바꾸는가?

파일 쓰기, 게시, 삭제, 일정 생성처럼 상태를 바꾼다면 우선 도구 후보입니다. 호출 시점과 입력값을 확인할 수 있고, 클라이언트가 사용자 승인 흐름을 적용하기도 쉽습니다.

2. 읽기만 하는가?

변경 없이 문서·파일·데이터를 제공한다면 리소스 후보입니다. URI로 대상을 구분할 수 있고, 애플리케이션이 필요한 자료를 선택해 컨텍스트로 넣을 수 있습니다.

3. 사용자가 반복해서 고르는 입력 양식인가?

같은 종류의 요청을 매번 처음부터 작성하는 대신 사용자가 선택할 템플릿이 필요하다면 프롬프트 후보입니다. 실행 기능을 프롬프트 안에 숨기기보다, 실제 실행은 별도의 도구에 맡기는 편이 역할 분리가 잘 됩니다.

4. 서버가 계산·검색·권한 확인을 해야 하는가?

단순한 정적 읽기가 아니라 검색어를 해석하고 결과를 계산하거나 권한에 따라 다른 값을 반환한다면 도구로 분리하는 편이 안전합니다. 이름이 "읽기"여도 서버에서 실행이 일어나는 기능이면 리소스라고 단정하지 않는 것이 좋습니다.

연결 순서도 기능 구분만큼 중요하다

세 기능의 목록을 바로 호출하기 전에 MCP 연결은 초기화 과정을 거칩니다. 공식 라이프사이클 사양은 클라이언트가 initialize 요청으로 프로토콜 버전과 기능을 협상하고, 서버가 응답한 뒤 클라이언트가 notifications/initialized를 보내는 흐름을 설명합니다. 이 과정이 끝난 뒤에 서버 기능을 사용하는 구조입니다. 공식 Lifecycle 사양을 함께 확인했습니다.

공식 스키마 저장소의 2025-06-18 타입 정의에도 프로토콜 버전이 2025-06-18로 기록되어 있고, 요청과 응답은 JSON-RPC 2.0 형태로 정의되어 있습니다. 구현할 때는 서버가 지원하는 문서 버전과 실제 라이브러리 버전을 따로 확인해야 합니다. 공식 스키마 TypeScript 원문은 타입과 메서드 형태를 직접 확인할 때 유용합니다.

제가 MCP 기능을 설계할 때 남길 표

기능을 하나 추가할 때 아래 표를 먼저 채우면 모델에게 무엇을 노출하는지 덜 헷갈립니다.

질문 기록할 내용
표면 도구 / 리소스 / 프롬프트
시작 주체 모델 / 애플리케이션 / 사용자
상태 변경 없음 / 있음, 변경 대상
입력 이름, 타입, 필수 여부, 허용 범위
출력 텍스트, 구조화 데이터, 오류 형태
권한 필요한 계정·범위·승인 단계
원문 해당 기능을 확인한 공식 문서 URL

이 표에서 상태 변경이 "있음"인데 표면이 리소스로 적혀 있거나, 사용자가 선택하는 템플릿인데 도구로 적혀 있다면 다시 나눠볼 만합니다. 물론 모든 구현이 하나의 표면만 써야 한다는 뜻은 아닙니다. 검색 도구가 결과를 반환하고, 그 결과를 리소스 URI로 다시 읽게 하는 식으로 여러 표면이 이어질 수도 있습니다.

MCP를 붙이는 일은 서버 하나를 추가하는 것으로 끝나지 않습니다. 모델이 실행할 수 있는 것, 애플리케이션이 읽을 수 있는 것, 사용자가 선택할 수 있는 것을 구분해 노출하는 작업입니다. 도구는 실행, 리소스는 컨텍스트, 프롬프트는 시작점으로 기억해두면 MCP 서버의 기능 목록을 볼 때도 구조가 먼저 보입니다.