CPN 한국어 자습서 · 러닝패스 2 / 4 — Building with the Claude API
MCP
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분list_prompts → self.session().list_prompts() → result.prompts
get_prompt(name, args) → result.messages 반환
args 딕셔너리의 doc_id 가 서버 함수로 전달
그 값이 프롬프트 본문에 보간되어 메시지로 돌아옴
CLI: /format → 문서 선택 → user 메시지를 Claude에 직접 전달
Claude가 read_document로 내용을 읽어 Markdown 재작성
result.prompts를 반환한다.result.messages를 반환한다.get_prompt에 넘기는 딕셔너리. doc_id 등이 서버 프롬프트 함수에 키워드 인자로 전달된다./format → 문서 선택 → user 메시지 → Claude → 도구로 읽기 → Markdown 응답.마지막 작업은 클라이언트가 서버 프롬프트를 쓰게 하는 것입니다. 두 메서드면 충분합니다 — 목록을 받는 list_prompts, 인자를 넣어 가져오는 get_prompt. 도구·리소스 때와 똑같이 session()에 위임합니다.
async def list_prompts(self) -> list[types.Prompt]: result = await self.session().list_prompts() return result.prompts
get_prompt는 인자를 함께 받습니다. 이 인자들은 서버 쪽 프롬프트 함수로 들어갑니다 — format_document가 doc_id를 받기로 했으니, args에 doc_id 키가 있으리라 기대합니다. 그 값이 본문에 보간된 뒤 result.messages로 돌아옵니다.
async def get_prompt(self, prompt_name, args: dict[str, str]): result = await self.session().get_prompt(prompt_name, args) return result.messages # 보간된 메시지 → 그대로 Claude로
get_prompt(prompt_name, args)에 넘긴 args는 서버 프롬프트 함수에 키워드 인자로 전달됩니다. 함수는 그 값을 프롬프트 본문 안에서 활용하고, 보간이 끝난 메시지를 클라이언트로 돌려보냅니다.
/format 의 format은 호출할 프롬프트의 이름일 뿐입니다. 선택한 문서가 args로 들어가 서버 함수에서 본문에 보간되고, 돌아온 user 메시지가 Claude로 직행합니다.
프로젝트를 다시 실행하고 슬래시(/)를 치면 format 명령이 보입니다. 선택 후 스페이스를 누르고 문서를 고르면(예 plan.md), 그 단일 user 메시지가 Claude에 직접 전달됩니다.
$ uv run main.py > /format # 슬래시 → 명령 목록(format) > /format plan.md # 문서 선택 [Claude] read_document(doc_id="plan.md") # 먼저 내용을 읽고 [Claude] # Project Plan ## Overview - ... # Markdown으로 재작성
Claude는 이제 "문서를 Markdown으로 재서식하라"는 지시와 문서 ID를 함께 받았습니다. 그래서 먼저 read_document로 내용을 가져오고, 마지막에 그 문서의 Markdown 버전으로 응답합니다.
@mcp.prompt로 서버에 정의하면, 클라이언트가 언제든 요청할 수 있다.args가 프롬프트 함수에 키워드 인자로 제공되어 본문에 보간된다.list_prompts→result.prompts, get_prompt→result.messages 두 줄이면 끝.Q1get_prompt가 반환하는 것은?
list_prompts는 목록(result.prompts), get_prompt는 보간된 대화(result.messages)를 돌려줍니다.
Q2get_prompt("format", args)의 args는 어떻게 쓰이나요?
args의 doc_id 같은 값이 format_document(doc_id=...)로 들어가 프롬프트 본문에 끼워집니다.
Q3CLI에서 /format 실행 시 Claude가 가장 먼저 하는 일은?
프롬프트가 문서 ID만 줬으니, Claude는 먼저 내용을 읽고 그다음 Markdown으로 재작성합니다.
도구·리소스·프롬프트 세 프리미티브를 모두 클라이언트·서버에 구현했습니다. 다음 장에서 셋의 제어 주체와 쓰임을 한눈에 정리합니다. → MCP 정리
전 코스는 계속 무료입니다. 등록하면 이 코스의 남은 76개 레슨을 끝까지 읽을 수 있습니다.
이미 등록하셨다면 그때 쓰신 이메일을 넣어 주세요.