프롬프트

프롬프트 (Prompts)

서버가 클라이언트에게 프롬프트 템플릿을 노출하는 표준화된 방법을 설명하는 페이지예요. 서버가 언어 모델과 상호작용하기 위한 구조화된 메시지와 지시문을 제공하고, 클라이언트가 사용 가능한 프롬프트를 발견·검색하고 인자를 제공해 커스터마이즈할 수 있게 해 줘요.

출처: 문서

본문

Model Context Protocol (MCP)은 서버가 클라이언트에게 프롬프트 템플릿을 노출하는 표준화된 방법을 제공해요. 프롬프트는 서버가 언어 모델과 상호작용하기 위한 구조화된 메시지와 지시문을 제공할 수 있게 해 줘요. 클라이언트는 사용 가능한 프롬프트를 발견하고, 그 내용을 검색하며, 인자를 제공해 커스터마이즈할 수 있어요.

참고 (Note): 간결함을 위해 이 페이지의 요청 예시는 _meta 요청 메타데이터(io.modelcontextprotocol/protocolVersion, io.modelcontextprotocol/clientInfo, io.modelcontextprotocol/clientCapabilities)를 생략해요. 모든 요청은 MUST 필수 _meta 필드를 포함해야 해요. _meta를 참조하세요.

사용자 상호작용 모델 (User Interaction Model)

프롬프트는 **사용자 통제(user-controlled)**로 설계돼요. 즉 서버에서 클라이언트로 노출되며, 사용자가 명시적으로 선택해서 사용할 수 있도록 의도된 것이에요. 이는 프롬프트를 언제 사용할지 결정하는 사람을 말하며, 내용을 누가 작성하는지는 말하지 않아요. 프롬프트 내용은 서버가 정의해요.

일반적으로 프롬프트는 사용자 인터페이스의 사용자 시작 명령(user-initiated commands)을 통해 트리거되며, 사용자가 사용 가능한 프롬프트를 자연스럽게 발견하고 호출할 수 있게 해요.

예를 들어 슬래시 명령(slash commands)으로:

(프롬프트가 슬래시 명령으로 노출된 예시 이미지)

하지만 구현자는 자신의 필요에 맞는 어떤 인터페이스 패턴으로든 프롬프트를 노출할 자유가 있어요. 프로토콜 자체는 특정 사용자 상호작용 모델을 강제하지 않아요.

기능 (Capabilities)

프롬프트를 지원하는 서버는 MUST 자신의 DiscoverResult에 prompts 기능을 선언해야 해요:

{
  "capabilities": {
    "prompts": {
      "listChanged": true
    }
  }
}

listChanged는 사용 가능한 프롬프트 목록이 바뀔 때 서버가 알림을 보낼지 여부를 나타내요.

prompts 기능을 선언하는 서버는 MUST prompts/list 요청에 요청한 클라이언트에게 현재 사용 가능한 프롬프트 집합으로 응답해야 해요. 이 집합은 MAY 비어 있을 수 있고 MAY 시간이 지나며 바뀔 수 있지만(List Changed Notification 참조), 연결별로 또는 연결의 다른 요청의 부수 효과로 MUST NOT 달라지면 안 돼요. 이 집합은 MAY 요청에 제시된 권한 부여에 따라 달라질 수 있어요. 예를 들어 호출자의 부여된 범위(granted scopes)가 허용하는 프롬프트만 반환하는 것은, 자격 증명이 요청별 입력이지 연결 상태가 아니기 때문에 허용돼요.

프로토콜 메시지 (Protocol Messages)

프롬프트 나열하기 (Listing Prompts)

사용 가능한 프롬프트를 검색하려면 클라이언트는 prompts/list 요청을 보내요. 이 작업은 pagination과 caching을 지원해요.

요청:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "prompts/list",
  "params": {
    "cursor": "optional-cursor-value"
  }
}

응답:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resultType": "complete",
    "prompts": [
      {
        "name": "code_review",
        "title": "Request Code Review",
        "description": "Asks the LLM to analyze code quality and suggest improvements",
        "arguments": [
          {
            "name": "code",
            "description": "The code to review",
            "required": true
          }
        ],
        "icons": [
          {
            "src": "https://example.com/review-icon.svg",
            "mimeType": "image/svg+xml",
            "sizes": ["any"]
          }
        ]
      }
    ],
    "nextCursor": "next-page-cursor",
    "ttlMs": 600000,
    "cacheScope": "public"
  }
}

프롬프트 가져오기 (Getting a Prompt)

특정 프롬프트를 검색하려면 클라이언트는 prompts/get 요청을 보내요. 인자는 completion API를 통해 자동 완성될 수 있어요.

요청:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "prompts/get",
  "params": {
    "name": "code_review",
    "arguments": {
      "code": "def hello():\n    print('world')"
    }
  }
}

응답:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "resultType": "complete",
    "description": "Code review prompt",
    "messages": [
      {
        "role": "user",
        "content": {
          "type": "text",
          "text": "Please review this Python code:\ndef hello():\n    print('world')"
        }
      }
    ]
  }
}

서버는 MAY 프롬프트를 해석하기 전에 추가 입력이 필요함을 나타내기 위해 prompts/get에 InputRequiredResult로 응답할 수도 있어요. 이는 다중 왕복 요청 메커니즘을 따라요. 요청을 재시도할 때 클라이언트는 요청 파라미터에 inputResponses와, 서버가 제공했다면 requestState를 포함해요.

목록 변경 알림 (List Changed Notification)

사용 가능한 프롬프트 목록이 바뀌면, listChanged 기능을 선언한 서버는 SHOULD promptsListChanged: true로 subscriptions/listen 스트림을 연 클라이언트에게 알림을 보내야 해요:

{
  "jsonrpc": "2.0",
  "method": "notifications/prompts/list_changed"
}

메시지 흐름 (Message Flow)

sequenceDiagram
    participant Client
    participant Server

    Note over Client,Server: Discovery
    Client->>Server: prompts/list
    Server-->>Client: List of prompts

    Note over Client,Server: Usage
    Client->>Server: prompts/get
    Server-->>Client: Prompt content

    opt listChanged
      Client->>Server: subscriptions/listen (promptsListChanged: true)
      Server--)Client: notifications/subscriptions/acknowledged
      Note over Client,Server: Changes
      Server--)Client: notifications/prompts/list_changed
      Client->>Server: prompts/list
      Server-->>Client: Updated prompts
    end

데이터 타입 (Data Types)

Prompt

프롬프트 정의는 다음을 포함해요:

  • name: 프롬프트의 고유 식별자
  • title: 표시용 선택적 사람이 읽을 수 있는 프롬프트 이름.
  • description: 선택적 사람이 읽을 수 있는 설명
  • icons: 사용자 인터페이스에 표시하기 위한 선택적 아이콘 배열
  • arguments: 커스터마이즈를 위한 선택적 인자 목록

PromptMessage

프롬프트의 메시지는 다음을 담을 수 있어요:

  • role: 화자를 나타내는 "user" 또는 "assistant"
  • content: 다음 콘텐츠 유형 중 하나:

참고 (Note): 프롬프트 메시지의 모든 콘텐츠 유형은 audience, priority, 수정 시간에 대한 메타데이터를 위한 선택적 annotations을 지원해요.

텍스트 콘텐츠 (Text Content)

텍스트 콘텐츠는 일반 텍스트 메시지를 나타내요:

{
  "type": "text",
  "text": "The text content of the message"
}

자연어 상호작용에 가장 흔히 쓰이는 콘텐츠 유형이에요.

이미지 콘텐츠 (Image Content)

이미지 콘텐츠는 메시지에 시각 정보를 포함할 수 있게 해요:

{
  "type": "image",
  "data": "base64-encoded-image-data",
  "mimeType": "image/png"
}

이미지 데이터는 MUST base64로 인코딩되고 유효한 MIME 타입을 포함해야 해요. 이를 통해 시각 컨텍스트가 중요한 멀티모달 상호작용이 가능해져요.

오디오 콘텐츠 (Audio Content)

오디오 콘텐츠는 메시지에 오디오 정보를 포함할 수 있게 해요:

{
  "type": "audio",
  "data": "base64-encoded-audio-data",
  "mimeType": "audio/wav"
}

오디오 데이터는 MUST base64로 인코딩되고 유효한 MIME 타입을 포함해야 해요. 이를 통해 오디오 컨텍스트가 중요한 멀티모달 상호작용이 가능해져요.

리소스 링크 (Resource Links)

프롬프트 메시지는 MAY 리소스 내용을 직접 포함하지 않고 추가 컨텍스트나 데이터를 제공하기 위해 리소스에 대한 링크를 포함할 수 있어요. 이 경우 프롬프트 메시지는 클라이언트가 가져올 수 있는 URI를 반환해요:

{
  "type": "resource_link",
  "uri": "file:///project/src/main.rs",
  "name": "main.rs",
  "description": "Primary application entry point",
  "mimeType": "text/x-rust"
}

리소스 링크는 클라이언트가 사용 방법을 이해하도록 돕기 위해 일반 리소스와 같은 Resource annotations을 지원해요.

임베디드 리소스 (Embedded Resources)

임베디드 리소스는 메시지에서 서버 측 리소스를 직접 참조할 수 있게 해요:

{
  "type": "resource",
  "resource": {
    "uri": "resource://example",
    "mimeType": "text/plain",
    "text": "Resource content"
  }
}

리소스는 텍스트 또는 바이너리(blob) 데이터를 담을 수 있고 MUST 다음을 포함해야 해요:

  • 유효한 리소스 URI
  • 적절한 MIME 타입
  • 텍스트 콘텐츠 또는 base64로 인코딩된 blob 데이터

임베디드 리소스는 프롬프트가 서버 관리 콘텐츠(문서, 코드 샘플, 기타 참고 자료)를 대화 흐름에 자연스럽게 통합할 수 있게 해 줘요.

오류 처리 (Error Handling)

서버는 SHOULD 일반적인 실패 사례에 표준 JSON-RPC 오류를 반환해야 해요:

  • 유효하지 않은 프롬프트 이름: -32602 (Invalid params)
  • 필수 인자 누락: -32602 (Invalid params)
  • 내부 오류: -32603 (Internal error)

구현 고려 사항 (Implementation Considerations)

  1. 서버는 SHOULD 처리 전에 프롬프트 인자를 검증해야 한다
  2. 클라이언트는 SHOULD 큰 프롬프트 목록에 대한 페이지네이션을 처리해야 한다
  3. 양측 모두 SHOULD 기능 협상을 존중해야 한다

보안 (Security)

구현은 MUST 주입 공격이나 리소스 무단 접근을 방지하기 위해 모든 프롬프트 입력과 출력을 신중히 검증해야 해요.

더 알아보기 (Learn more)