AI 클라이언트를 더 스마트하게 만드는 5가지 간과된 MCP 기능
요약
Model Context Protocol(MCP) 서버 구축 시 간과하기 쉬운 5가지 핵심 기능을 소개합니다. 도구 주석(Annotations)과 구조화된 결과(Structured Results)를 활용하여 AI 클라이언트가 도구의 동작 방식을 더 명확하게 이해하고 상호작용하도록 만드는 방법을 다룹니다.
핵심 포인트
- 도구 주석을 통해 읽기 전용, 멱등성, 파괴적 동작 여부 등의 컨텍스트 제공 가능
- 주석은 보안 보장이 아닌 클라이언트의 실행 계획을 돕는 '힌트'로 활용해야 함
- structuredContent를 사용하여 텍스트 대신 JSON 형태의 구조화된 데이터 반환 가능
- MCP 사양을 활용하면 클라이언트의 도구 사용 효율성과 사용자 경험을 개선할 수 있음
모두가 MCP 서버를 구축하고 있습니다.
대부분의 대화는 전송(transports), 인증(authentication), OAuth, 그리고 도구 노출에 초점을 맞춥니다. 이러한 주제들은 중요하지만, 최근 몇 개의 MCP 서버를 구축하면서 저는 사양(specification)의 다른 부분에서 제가 감탄하게 된 것을 발견했습니다. 이 부분은 그다지 많은 주목을 받지 않는 것 같습니다.
흥미로운 점은 이것들이 숨겨진 API가 아니라는 것입니다. 이미 Model Context Protocol (MCP) 사양이나 그 공식 확장 기능의 일부입니다.
아래의 어떤 기능도 사용자의 도구가 무엇을 하는지를 변경하지 않습니다.
이것들은 클라이언트가 서버와 어떻게 명확하게 이해하고 상호작용할 수 있는지를 바꿉니다.
1. 도구 주석(Tool Annotations)
이 기능은 이 게시물의 영감을 준 부분입니다.
MCP는 readOnlyHint, idempotentHint, destructiveHint, 그리고 openWorldHint와 같은 주석을 통해 도구의 동작 방식을 설명할 수 있게 해줍니다.
{
"annotations": {
"readOnlyHint": true,
...
클라이언트에게 도구가 무엇을 하는지만 알려주는 대신, 그것이 어떻게 동작하는지도 알려주고 있는 것입니다.
몇 가지 예시가 있습니다:
readOnlyHint: 도구가 환경을 수정하지 않음을 나타냅니다.idempotentHint: 동일한 인자로 쓰기 도구를 반복적으로 호출해도 환경에 추가적인 영향이 없음을 나타냅니다.destructiveHint: 잠재적으로 파괴적인 업데이트와 추가적인 업데이트를 구별합니다.openWorldHint: 해당 도구가 외부 엔티티의 개방된 세계(open world)와 상호작용할 수 있는지 여부를 나타냅니다.
예를 들어, 웹 검색 도구는 개방된 세계에서 작동하는 반면, 고정된 로컬 메모리 저장소에 접근하는 도구는 폐쇄적인 영역(closed domain)에서 작동합니다.
이것들은 단순한 부울 값처럼 보일 수 있지만, 실행을 계획하거나 사용자에게 도구를 제시하거나 확인 흐름을 설계할 때 클라이언트에게 유용한 컨텍스트를 제공할 수 있습니다.
주목할 만한 몇 가지 세부 사항이 있습니다.
idempotentHint와 destructiveHint는 읽기 전용(read-only)이 아닌 도구에 대해서만 의미가 있습니다. 또한, destructiveHint: false는 해당 도구가 추가적인 업데이트만 수행함을 의미합니다.
가장 중요한 점은, 이것들이 보안 보장이 아닌 **힌트 (hints)**라는 사실입니다. 클라이언트는 신뢰할 수 없는 서버의 어노테이션 (annotations)에 기반하여 보안에 민감한 결정을 내려서는 안 됩니다. 인증 (Authentication), 권한 부여 (authorization), 사용자 동의 (user consent), 그리고 결정론적 안전장치 (deterministic safeguards)는 여전히 중요합니다.
2. 구조화된 도구 결과 (Structured Tool Results)
많은 MCP 도구들이 여전히 텍스트만을 반환합니다.
Found 12 matching documents.
이는 인간에게는 완벽하게 작동합니다.
하지만 클라이언트의 경우, 기저에 있는 데이터를 구조화된 형태로 받는 것이 유익할 때가 많습니다.
MCP 도구는 structuredContent를 통해 JSON 값을 반환할 수 있습니다.
{
"structuredContent": {
"documents": [
...
이 값은 반드시 객체 (object)일 필요는 없습니다. 배열 (array), 문자열 (string), 숫자 (number), 불리언 (boolean), 또는 null을 포함한 모든 유효한 JSON 값일 수 있습니다.
구조화된 데이터는 클라이언트가 결과를 검증하거나, 인터페이스를 렌더링하거나, 데이터를 다른 워크플로 (workflow)로 전달하거나, 또는 모델이 자연어 응답을 파싱 (parsing)하지 않고도 개별 필드를 다룰 수 있도록 더 쉽게 만들어 줍니다.
하위 호환성을 위해, 명세서(specification)는 직렬화된 JSON을 일반 텍스트 콘텐츠 블록으로도 함께 반환할 것을 권장합니다.
여기서 용어상의 구분이 하나 유용합니다: MCP의 structuredContent는 구조화된 도구 결과 (structured tool result)입니다. 이는 LLM의 구조화된 출력 (structured output)이나 스키마 제약 모델 생성 (schema-constrained model generation)과는 동일한 것이 아닙니다.
📖 MCP specification: Structured Content
3. 출력 스키마 (Output Schemas)
구조화된 데이터를 반환한다면, 클라이언트에게 그것이 어떤 형태인지 알려주어야 합니다.
클라이언트가 tools/list를 통해 도구를 발견할 때, 각 도구의 inputSchema를 받게 됩니다.
도구는 또한 outputSchema를 노출할 수 있습니다.
{
"name": "search_documents",
"inputSchema": {
...
이는 클라이언트가 도구를 호출하기 전에 structuredContent의 예상되는 형태를 검사할 수 있음을 의미합니다.
출력 스키마 (output schema)가 정의되어 있다면, 서버는 이에 부합하는 구조화된 콘텐츠 (structured content)를 반환해야 합니다. 클라이언트는 결과를 검증 (validate)할 것을 권장합니다.
이는 다음과 같은 사항들을 지원할 수 있습니다:
- 응답 검증 (Response validation)
- 타입이 지정된 통합 (Typed integrations)
- 더 예측 가능한 클라이언트 측 처리 (More predictable client-side handling)
- 더 풍부한 인터페이스 (Richer interfaces)
- 더 명확한 도구 문서화 (Clearer tool documentation)
저는 이를 다음과 같이 생각하는 것을 좋아합니다:
구조화된 콘텐츠 (Structured content)는 당신이 무엇을 반환했는지 클라이언트에게 알려줍니다. 출력 스키마 (output schema)는 당신이 반환하기 전에 클라이언트에게 무엇을 기대해야 하는지 알려줍니다.
이 두 기능은 서로를 아주 잘 보완합니다.
📖 MCP specification: Output Schema
4. 진행 상황 보고 (Progress Reporting)
모든 작업이 1초 만에 끝나지는 않습니다.
저장소 (repository) 인덱싱, 수천 개의 파일 처리, 또는 대규모 AI 워크플로 (workflow) 실행을 생각해 보세요.
진행 상황 보고 (progress reporting)가 없다면, 사용자는 작업이 계속 진행 중이라는 표시도 없이 로딩 스피너 (loading spinner)만 바라보게 될 수 있습니다.
MCP는 오래 걸리는 요청 (long-running requests)에 대해 선택적인 진행 상황 알림 (progress notifications)을 지원합니다.
클라이언트가 진행 상황 업데이트를 원할 경우, 요청 메타데이터 (request metadata)에 고유한 progressToken을 포함합니다.
{
"_meta": {
"progressToken": "index-repository-123"
...
그러면 서버는 해당 토큰과 연관된 notifications/progress 메시지를 보낼 수 있습니다.
{
"method": "notifications/progress",
"params": {
...
클라이언트가 토큰을 제공하더라도 서버가 반드시 진행 상황 알림을 보내야 하는 것은 아닙니다. 만약 알림을 보낸다면, 진행 상황 값 (progress value)은 각 알림마다 증가해야 합니다. 작업량을 알 수 없는 경우 총량 (total)은 선택 사항입니다.
때때로 좋은 UX (User Experience)는 단순히 일을 빠르게 만드는 것이 아닙니다.
기다림을 덜 미스터리하게 만드는 것에 관한 것입니다.
5. 태스크 (Tasks)
어떤 작업들은 작업이 완료될 때까지 요청을 열어두어서는 안 됩니다.
MCP Tasks는 CI 파이프라인 (CI pipelines), 배치 처리 (batch processing), 외부 작업 (external jobs), 승인 워크플로우 (approval workflows) 또는 모델 학습 (model training)과 같이 오래 걸리는 작업에 대해 비동기 실행 (asynchronous execution)을 제공합니다.
Tasks는 핵심 프로토콜 (core protocol)의 일부라기보다 공식적인 MCP 확장 (extension)입니다. 클라이언트 (client)와 서버 (server) 모두 이 확장에 대한 지원을 선언해야 합니다.
서버가 지원되는 요청이 오래 걸릴 것이라고 판단하면, 최종 결과 대신 지속 가능한 태스크 핸들 (durable task handle)을 반환할 수 있습니다.
그러면 클라이언트는 다음과 같은 작업을 수행할 수 있습니다:
- 태스크 식별자 (task identifier) 수신
tasks/get을 사용하여 태스크 폴링 (polling)- 재연결 후 폴링 재개
tasks/update를 통해 요청된 입력 제공tasks/cancel을 통해 취소 요청- 태스크가 완료되었을 때 최종 결과 검색
Tasks는 또한 working, input_required, completed, failed, cancelled와 같은 상태를 노출할 수 있습니다.
폴링 (Polling)이 기본 메커니즘입니다. 서버는 지원되는 경우 추가적으로 태스크 알림 (task notifications)을 제공할 수 있습니다.
이 모델은 기저의 작업이 네트워크 연결보다 오래 지속되거나 사람의 입력을 기다리는 동안 일시 중지될 수 있는 경우 특히 유용합니다.
마치며
MCP를 단순히 도구 (tools)를 노출하기 위한 프로토콜로 생각하기 쉽습니다.
하지만 저는 그 이상이라고 생각합니다.
MCP는 클라이언트가 해당 도구를 이해하고 작동하도록 돕는 프로토콜이기도 합니다.
도구가 환경을 수정하는지, 반복적인 호출이 추가적인 효과를 갖는지, 어떤 출력 형태 (output shape)를 기대할 수 있는지, 구조화된 데이터 (structured data)를 어떻게 소비하는지, 그리고 오래 걸리는 작업을 어떻게 추적하는지를 아는 클라이언트는 이름과 설명만 받는 클라이언트보다 훨씬 더 많은 컨텍스트 (context)를 갖게 됩니다.
그 점이 제가 매력적이라고 느끼는 부분입니다.
이 프로토콜은 단순히 기능 (capabilities)을 설명하는 것이 아닙니다.
동작 (behavior)과 실행 패턴 (execution patterns)을 설명하는 것이기도 합니다.
이러한 기능 중 일부는 구현하는 데 적은 노력만 필요합니다. 반면 Tasks와 같은 기능은 클라이언트와 서버 모두로부터 더 깊은 지원을 필요로 합니다.
그럼에도 불구하고, 이러한 기능들은 더 예측 가능한 통합 (integration)과 더 나은 사용자 경험으로 이어질 수 있기 때문에 이해할 가치가 있습니다.
만약 여러분이 오늘 MCP 서버를 구축하고 있다면, 도구 (tool)의 이름, 설명, 그리고 입력 스키마 (input schema) 그 이상을 살펴보는 데 약간의 시간을 더 투자할 가치가 있습니다.
그 결과로 여러분의 클라이언트 (client)는 서버를 더 잘 이해할 수 있게 될 것이며, 사용자들은 더 투명하고 신뢰할 수 있는 경험을 얻을 수 있을 것입니다.
MCP의 다른 어떤 부분들이 더 많은 관심을 받을 가치가 있다고 생각하시는지 여러분의 의견을 듣고 싶습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기