byteforce

CPN 한국어 자습서 · Introduction to Model Context Protocol

3 · Connecting with MCP clients

클라이언트의 프롬프트

Prompts in the client

서버에 정의한 프롬프트를 클라이언트가 쓰도록 두 함수를 구현합니다. list_prompts로 목록을 받고, get_prompt에 인자를 넘겨 보간된 메시지를 가져옵니다. CLI에서 /format → 문서 선택 → 그 user 메시지를 Claude에 직접 전달하면 끝입니다.

전체 내레이션영상 나레이션 한국어 번역 (전체)

Stephen Grider · Anthropic 기술 스태프

마지막 주요 작업은 MCP 클라이언트에 기능을 구현하는 것입니다. 서버에 정의된 모든 프롬프트를 목록으로 받고, 특정 프롬프트를 변수까지 보간해서 가져오게 합니다.

먼저 list_prompts를 구현합니다. 주석을 지우고, result = await self.session().list_prompts() 를 쓴 뒤 result.prompts 를 반환합니다. 그게 거의 전부입니다.

다음은 get_prompt입니다. 개별 프롬프트를 가져올 때는 인자를 함께 받습니다. 이 인자들은 결국 서버 쪽 프롬프트 함수 안으로 들어갑니다. 예를 들어 format_document는 doc_id를 받기로 했으니, 이 args 딕셔너리에 doc_id 키가 있을 것으로 기대합니다. 그 값이 해당 함수로 전달되고, 프롬프트 본문에 보간됩니다.

get_prompt 함수 안에서는 result = await self.session().get_prompt(prompt_name, args) 로 결과를 받습니다 — 가져올 프롬프트 이름과 인자를 넘깁니다. 그리고 result.messages 를 반환합니다. 이 메시지들은 Claude에 곧장 넣고 싶은 일종의 대화를 이룹니다. 클라이언트 쪽은 이게 전부입니다.

이제 CLI에서 테스트합니다. 프로젝트를 다시 실행하고 슬래시(/)를 치면 format 명령에 접근할 수 있습니다. format은 사실 우리가 호출할 프롬프트의 이름일 뿐입니다. 그걸 선택하고 스페이스를 누르면 문서를 하나 고르라고 합니다. plan.md를 고르고 엔터를 칩니다.

그러면 그 전체 프롬프트 — 사실상 단 하나의 user 메시지 — 를 Claude에 직접 넣습니다. 이제 Claude는 문서를 Markdown으로 재서식하라는 지시와, 재서식할 문서의 ID를 함께 받았습니다. 그래서 가장 먼저 그 문서 내용을 가져와야 하고, read_document 도구로 그렇게 합니다. 마지막으로 Claude는 그 문서의 Markdown 버전으로 응답합니다 — 마크다운 문법이 잔뜩 들어간 문서가 나옵니다.

잘 동작했으니 프롬프트를 빠르게 복습합니다. 우리는 MCP 서버의 목적과 관련 있는 프롬프트를 쓰고 평가하는 것에서 시작합니다. 여기서는 문서 서버를 만들고 있었으니, 문서를 다른 스타일로 재작성하는 기능이 자연스럽게 어울립니다.

프롬프트를 구성했으면 MCP 서버 안에 프롬프트로 정의하고, 클라이언트는 언제든 그 프롬프트를 요청할 수 있습니다. 요청할 때 인자를 몇 개 넘기면, 그 값이 프롬프트 함수에 키워드 인자로 제공되고, 함수는 그 값을 프롬프트 본문 안에서 활용합니다.

이 장에서 배우는 것What you'll learn

약 5분
1

list_promptsself.session().list_prompts()result.prompts

2

get_prompt(name, args)result.messages 반환

3

args 딕셔너리의 doc_id 가 서버 함수로 전달

4

그 값이 프롬프트 본문에 보간되어 메시지로 돌아옴

5

CLI: /format → 문서 선택 → user 메시지를 Claude에 직접 전달

6

Claude가 read_document로 내용을 읽어 Markdown 재작성

먼저 짚고 갈 용어
list_prompts
서버에 정의된 프롬프트 목록을 받는 클라이언트 메서드. result.prompts를 반환한다.
get_prompt
이름과 인자로 특정 프롬프트를 가져오는 메서드. result.messages를 반환한다.
args (인자)
get_prompt에 넘기는 딕셔너리. doc_id 등이 서버 프롬프트 함수에 키워드 인자로 전달된다.
result.messages
서버가 돌려준, 보간이 끝난 메시지 리스트. 그대로 Claude에 전달한다.
슬래시 명령 흐름
/format → 문서 선택 → user 메시지 → Claude → 도구로 읽기 → Markdown 응답.

클라이언트의 두 함수

list_prompts & get_prompt

마지막 작업은 클라이언트가 서버 프롬프트를 쓰게 하는 것입니다. 두 메서드면 충분합니다 — 목록을 받는 list_prompts, 인자를 넣어 가져오는 get_prompt. 도구·리소스 때와 똑같이 session()에 위임합니다.

mcp_client.py · list_prompts
async def list_prompts(self) -> list[types.Prompt]:
    result = await self.session().list_prompts()
    return result.prompts

get_prompt는 인자를 함께 받습니다. 이 인자들은 서버 쪽 프롬프트 함수로 들어갑니다 — format_documentdoc_id를 받기로 했으니, argsdoc_id 키가 있으리라 기대합니다. 그 값이 본문에 보간된 뒤 result.messages로 돌아옵니다.

mcp_client.py · get_prompt
async def get_prompt(self, prompt_name, args: dict[str, str]):
    result = await self.session().get_prompt(prompt_name, args)
    return result.messages   # 보간된 메시지 → 그대로 Claude로

인자가 본문으로 들어가는 흐름

args → interpolation

get_prompt(prompt_name, args)에 넘긴 args는 서버 프롬프트 함수에 키워드 인자로 전달됩니다. 함수는 그 값을 프롬프트 본문 안에서 활용하고, 보간이 끝난 메시지를 클라이언트로 돌려보냅니다.

인자 보간 흐름 · 단계를 눌러 보세요

/formatformat은 호출할 프롬프트의 이름일 뿐입니다. 선택한 문서가 args로 들어가 서버 함수에서 본문에 보간되고, 돌아온 user 메시지가 Claude로 직행합니다.

CLI에서 실행

/format in the CLI

프로젝트를 다시 실행하고 슬래시(/)를 치면 format 명령이 보입니다. 선택 후 스페이스를 누르고 문서를 고르면(예 plan.md), 그 단일 user 메시지가 Claude에 직접 전달됩니다.

터미널 · /format plan.md
$ uv run main.py

> /format            # 슬래시 → 명령 목록(format)
> /format plan.md    # 문서 선택

[Claude] read_document(doc_id="plan.md")   # 먼저 내용을 읽고
[Claude] # Project Plan
         ## Overview
         - ...                            # Markdown으로 재작성
Claude가 하는 일

Claude는 이제 "문서를 Markdown으로 재서식하라"는 지시와 문서 ID를 함께 받았습니다. 그래서 먼저 read_document로 내용을 가져오고, 마지막에 그 문서의 Markdown 버전으로 응답합니다.

정리 & 점검

Recap & check
프롬프트 복습
  • 서버 목적과 맞닿은 프롬프트를 먼저 쓰고 평가한다(여기선 문서 재서식).
  • 그 프롬프트를 @mcp.prompt로 서버에 정의하면, 클라이언트가 언제든 요청할 수 있다.
  • 요청 시 넘긴 args가 프롬프트 함수에 키워드 인자로 제공되어 본문에 보간된다.
  • 클라이언트는 list_promptsresult.prompts, get_promptresult.messages 두 줄이면 끝.

Q1get_prompt가 반환하는 것은?

Q2get_prompt("format", args)args는 어떻게 쓰이나요?

Q3CLI에서 /format 실행 시 Claude가 가장 먼저 하는 일은?