공식 C# MCP SDK 1.0 출시

자세한 내용 보기: Release v1.0 of the official MCP C# SDK - .NET Blog

MCP(Model Context Protocol) C# SDK가 v1.0 마일스톤에 도달했습니다. 이번 릴리스는 MCP 스펙 2025-11-25 버전을 완전하게 지원하며, 인증 흐름 개선부터 장기 실행 요청 처리, 실험적 기능인 Tasks까지 폭넓은 변화를 담고 있습니다. 핵심 내용을 정리합니다.


1. 인증 서버 디스커버리 개선

서버가 Protected Resource Metadata(PRM) 문서를 노출하는 경로가 세 가지로 확장되었습니다.

  1. WWW-Authenticate 헤더의 resource_metadata 파라미터 (기존 방식)

  2. MCP 엔드포인트 경로 기반 well-known URL (예: /.well-known/oauth-protected-resource/public/mcp)

  3. 루트 well-known URL (예: /.well-known/oauth-protected-resource)

클라이언트는 이 세 위치를 순서대로 탐색합니다. 서버 측에서는 AddMcp 확장 메서드로 PRM을 구성하면, SDK가 well-known 경로 호스팅과 WWW-Authenticate 헤더 설정을 자동 처리합니다.

2. 도구·리소스·프롬프트에 아이콘 메타데이터 추가

tools/list, resources/list, prompts/list 응답에 아이콘 정보가 포함됩니다. 가장 간단한 방법은 McpServerToolAttributeIconSource 파라미터를 쓰는 것입니다.

[McpServerTool(Title = "날씨 조회", IconSource = "https://example.com/weather-icon.svg")]
public static string GetWeather(...)

MIME 타입, 크기 힌트, 라이트/다크 테마 구분이 필요한 경우 McpServerToolCreateOptions.Icons를 통해 프로그래밍 방식으로 구성할 수 있으며, Implementation 클래스에도 IconsWebsiteUrl 속성이 추가되었습니다.

3. 점진적 스코프 동의 (Incremental Scope Consent)

최소 권한 원칙을 MCP 인증에 적용한 기능입니다.

  • 클라이언트가 인증 없이 요청하면 서버는 401과 함께 필요한 스코프를 응답합니다.

  • 토큰에 특정 작업의 스코프가 부족하면 403 Forbidden + insufficient_scope 에러로 추가 스코프를 안내합니다.

클라이언트 SDK는 이 흐름을 자동 처리하므로 별도 코드가 필요 없습니다. 서버 측에서는 ASP.NET Core 미들웨어에서 인가 검사를 수행해야 하는데, MCP HTTP 핸들러가 도구 호출 전에 응답 헤더를 flush할 수 있기 때문에 도구 메서드 내부가 아닌 미들웨어에서 처리해야 한다는 점이 중요합니다.

4. URL 모드 Elicitation

MCP 호스트/클라이언트를 우회하여 서버와 최종 사용자 간에 대역 외(out-of-band) 상호작용을 가능하게 합니다. API 키, 서드파티 인증, 결제 정보 같은 민감한 데이터 수집에 유용합니다.

  • 클라이언트는 Capabilities.Elicitation.Url을 설정하고 ElicitationHandler를 제공합니다.

  • 서버는 Elicitation URL 엔드포인트를 정의하고, Razor Page 등으로 폼을 제공할 수 있습니다.

  • Streamable HTTP Transport의 멀티테넌트 특성상, 각 Elicitation 요청을 올바른 MCP 세션에 연결하는 상태 관리가 필수입니다.

5. 샘플링에서의 도구 호출 지원

이번 스펙에서 가장 강력한 추가 사항 중 하나입니다. 서버가 샘플링 요청에 도구를 포함시키면, LLM이 해당 도구를 호출하여 응답을 생성할 수 있습니다.

핵심 흐름은 다음과 같습니다:

  1. 서버가 클라이언트에 CreateMessage 요청 (프롬프트 + 도구 정의 포함)

  2. 클라이언트(LLM)가 도구 호출을 요청하는 응답 반환 (stopReason: tool_calls)

  3. 서버가 도구를 로컬 실행한 뒤, 도구 호출/응답을 포함한 새 CreateMessage 요청 발송

  4. 최종 응답이 올 때까지 반복

Microsoft.Extensions.AIIChatClientCreateSamplingHandler()를 활용하면 MCP-LLM 간 포맷 변환을 간결하게 처리할 수 있습니다. 서버 측에서는 McpServer.AsSamplingChatClient()IChatClient를 얻고, UseFunctionInvocation()으로 도구 호출을 추가하는 패턴입니다.

6. Client ID Metadata Documents (CIMD)

Dynamic Client Registration(DCR)의 대안으로, 이제 MCP에서 클라이언트 등록의 권장 방식입니다. 클라이언트가 client_id로 URL을 지정하면, 인가 서버가 해당 URL에서 JSON 메타데이터를 가져와 클라이언트를 식별합니다.

SDK는 CIMD를 먼저 시도하고, 인가 서버가 미지원 시 DCR로 폴백합니다.

7. HTTP 기반 장기 실행 요청 — 폴링 방식

HTTP 타임아웃 환경에서 장기 실행 요청을 처리하는 방식이 개선되었습니다.

  • 서버가 SSE 스트림을 열 때 Event ID가 포함된 빈 이벤트를 먼저 보냅니다.

  • 이후 서버가 언제든 스트림을 닫을 수 있고, 클라이언트는 Event ID로 재연결합니다.

  • ISseEventStreamStore 구현체를 제공하면 되며, SDK에 포함된 DistributedCacheEventStreamStoreIDistributedCache 기반으로 동작합니다.

  • 핸들러에서 context.EnablePollingAsync()를 호출하면 SSE 연결을 끊고 폴링 모드로 전환합니다.

메모리 누수 방지를 위해 세션 종료 시 스트림 삭제, 시간 기반 만료 정책, 선택적 이벤트 저장 등의 보존 전략을 고려해야 합니다.

8. Tasks (실험적 기능)

:warning: MCP 스펙 2025-11-25의 실험적 기능입니다. 향후 API 변경 가능성이 있습니다.

기존 요청에 내구성 있는 상태 추적과 지연 결과 조회를 추가하는 새로운 프리미티브입니다.

  • 클라이언트가 요청에 task 필드를 포함하면, 서버는 Task ID·상태·TTL 등의 메타데이터를 반환합니다.

  • 이후 tasks/get(상태 폴링), tasks/result(결과 조회), tasks/list(목록), tasks/cancel(취소)로 관리합니다.

  • Task 상태는 workingcompleted | failed | cancelled (+ input_required)의 생명주기를 따릅니다.

서버에서는 IMcpTaskStore를 구현하여 Task 스토어를 구성합니다. SDK에 포함된 InMemoryMcpTaskStore는 개발 및 단일 서버 배포에 적합하며, 프로덕션 멀티 서버 환경에서는 DB나 Redis 등 영속 저장소 기반 구현이 필요합니다.

비동기 메서드(Task<T>, ValueTask<T> 반환)는 자동으로 Task 지원을 선언하며, McpServerToolAttributeTaskSupport 속성으로 Forbidden, Optional, Required를 명시적으로 제어할 수 있습니다.


참고 링크


이번 릴리스는 .NET 생태계에서 MCP 서버와 클라이언트를 구축하는 데 있어 본격적인 프로덕션 레벨의 기반이 마련된 것으로 볼 수 있습니다. 특히 인증 흐름, 샘플링 도구 호출, 장기 실행 처리 패턴은 실제 엔터프라이즈 시나리오에서 바로 활용 가능한 수준입니다.

이 아티클은 생성형 AI를 통해 번역/정리했습니다.

2개의 좋아요