본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 08. 06:44

기존 ASP.NET Core API를 빌드 타임에 MCP 도구로 변환하기

요약

McpIt은 ASP.NET Core API를 MCP(Model Context Protocol) 도구로 자동 변환해주는 소스 생성기입니다. 속성 추가만으로 컴파일 타임에 도구를 생성하여 중복 코드를 제거하고 Native AOT 환경에서도 안전하게 작동합니다.

핵심 포인트

  • ASP.NET Core 컨트롤러를 MCP 도구로 자동 변환
  • 소스 생성기(Source Generator) 기반으로 런타임 오버헤드 제거
  • Native AOT 및 트리밍 환경 지원 (AOT-safe)
  • HTTP 메서드 기반 읽기 전용 및 멱등성 자동 설정

이미 Web API를 출시하셨나요? 이제 AI 에이전트가 이를 사용하고 싶어 합니다. 공식 MCP C# SDK를 사용하면 "엔드포인트가 있다"에서 "에이전트가 이를 호출할 수 있다"로 가는 경로가 수많은 수동 작성 보일러플레이트 (Boilerplate) 코드를 거쳐야 합니다. McpIt은 그 덩어리를 제거합니다. 속성 (Attribute) 하나만 추가하면, 컴파일 타임 (Compile time)에 도구가 자동으로 생성됩니다.

보일러플레이트 문제

공식 MCP C# SDK는 훌륭하며, Microsoft가 지원하고, 올바른 기반을 제공합니다. 하지만 에이전트가 접근하기를 원하는 모든 작업에 대해 [McpServerTool] 클래스를 직접 작성할 것을 요구합니다. 당신은 이미 그 작업을 한 번 정의했습니다. 라우트 (Route), HTTP 동사 (HTTP verb), 매개변수 (Parameters), 유효성 검사 (Validation), 비즈니스 로직 (Business logic)이 모두 컨트롤러 액션 (Controller action)에 존재합니다. 이 모든 것을 미러링하는 두 번째 병렬 클래스를 작성하고, 이 둘을 영원히 동기화 상태로 유지하는 것은 정확히 부패를 초래하는 중복의 일종입니다.

노출하고 싶은 엔드포인트가 10개라면, 10개의 추가 클래스를 작성하고 유지 관리해야 합니다. 컨트롤러에서 매개변수 이름을 변경하면, 수동으로 업데이트할 때까지 도구는 어긋나게 됩니다. 이것이 바로 McpIt이 제거하기 위해 만들어진 세금입니다.

전과 후

다음은 일반적인 ASP.NET Core 컨트롤러 액션입니다:

[ApiController]
[Route("orders")]
public class OrdersController : ControllerBase
...

다음은 동일한 액션이 AI 에이전트에 노출된 모습입니다. 속성 하나와 설명을 위한 <summary>를 추가하세요:

using McpIt;
using Microsoft.AspNetCore.Mvc;

...

이것이 변경 사항의 전부입니다. 컴파일 타임 (Compile time)에 McpIt은 getOrder를 위한 MCP 도구 클래스를 생성합니다. 액션의 HTTP 동사, 라우트 템플릿 (Route template), 매개변수, XML 요약 (XML summary)을 읽은 다음, 이를 바탕으로 도구의 입력 스키마 (Input schema)와 안전 힌트 (Safety hints)를 구축합니다. id 라우트 매개변수는 타입이 지정된 도구 인자 (Typed tool argument)가 됩니다. <summary>는 도구 설명 (Tool description)이 됩니다.

MCP 클라이언트에게 tools/list 호출은 이제 다음과 같이 반환됩니다:

{
  "tools": [
    {
...

annotations를 주목하세요. GetOrder는 GET 방식이므로, McpIt는 해당 도구를 읽기 전용(read-only) 및 멱등(idempotent) 상태로 자동으로 표시합니다. 직접 작성한 클래스도, 중복된 스키마(schema)도 필요 없습니다.

작동 원리

McpIt를 다른 대안들과 차별화하는 세 가지 요소가 있습니다.

런타임 레이어가 아닌 소스 생성기(source generator)입니다. 도구 클래스들은 빌드 타임(build time)에 존재합니다. 시작 시 어셈블리(assembly)를 스캔하는 리플렉션(reflection)이나 즉석에서 생성되는 프록시 객체(proxy object)가 없습니다. 이는 곧 AOT-safe(AOT 안전)함을 의미합니다. 즉, 리플렉션 의존도가 높은 방식이 작동하지 않는 Native AOT 및 트리밍(trimming) 환경에서도 문제없이 작동합니다.

인프로세스(in-process) 방식으로 액션을 호출합니다. 에이전트가 getOrder를 호출하면, McpIt는 실제 GetOrder 메서드를 직접 호출합니다. 라우팅(routing), 모델 바인딩(model binding), 유효성 검사(validation) 및 비즈니스 로직은 HTTP 호출자가 호출할 때와 정확히 동일하게 실행됩니다. 자신의 서버로 다시 루프를 도는 두 번째 HTTP 요청은 발생하지 않습니다. 유일하게 비교 가능한 라이브러리인 Api.ToMcp는 모든 도구 호출마다 내부적인 HTTP 셀프 콜(self-call)을 수행합니다. McpIt는 네트워크를 완전히 건너뜁니다.

컨트롤러(controllers)와 미니멀 API(minimal APIs)를 모두 지원합니다. 컨트롤러 액션이나 미니멀 API 엔드포인트에 [McpTool]을 표시하기만 하면 됩니다. 두 스타일 모두 작동합니다. Api.ToMcp는 컨트롤러만 지원합니다.

왜 직접 서버를 작성하는 대신 이것을 사용하는가

공식 SDK는 전송(transport), 프로토콜(protocol), 그리고 서빙 인프라를 제공합니다. 그것은 진정한 가치이며, McpIt는 그 위에 구축되었습니다. McpIt는 ModelContextProtocol.AspNetCore를 계층화하여 공식 SDK가 도구를 서빙할 수 있게 합니다. McpIt가 추가하는 것은 생성(generation) 단계입니다. 따라서 이미 작성한 엔드포인트를 그대로 반영하는 도구 클래스를 직접 작성할 필요가 없습니다.

노출은 선택 사항(opt-in)입니다. [McpTool] 어노테이션을 지정한 엔드포인트만 도구가 되므로, 에이전트에게 API 전체 표면(surface)을 실수로 넘겨주는 일은 발생하지 않습니다. 또한 안전 힌트는 HTTP 메서드(verb)를 통해 제공됩니다. GET과 HEAD는 읽기 전용이며 멱등(idempotent)한 반면, POST, PUT, PATCH, DELETE는 파괴적인(destructive) 작업으로 표시됩니다. 파괴적인 작업을 노출할 경우, [McpTool(AllowDestructive = true)]로 이를 승인하기 전까지 빌드 경고가 발생합니다. 빌드 타임 진단(MCPGEN001: 설명 누락, MCPGEN002: 승인되지 않은 파괴적 작업)을 통해 도구가 배포되기 전까지 도구 표면의 정직함을 유지할 수 있습니다.

설치 및 퀵스타트

dotnet add package McpIt

McpIt은 공식 MCP SDK를 전이적(transitively)으로 가져오므로, ModelContextProtocol.AspNetCore를 직접 추가할 필요가 없습니다. [McpTool][McpToolOutput] 속성(attribute)은 작은 크기의 McpIt.Abstractions 패키지에 포함되어 있으며, 이 또한 전이적으로 제공됩니다.

Program.cs에서 다음과 같이 연결합니다:

using McpIt;

var builder = WebApplication.CreateBuilder(args);
...

기존 REST API는 변경 없이 실행되며, 이제 /mcp 경로에서 MCP 서버가 서비스됩니다.

도구 표면을 가볍게 유지하기

응답 비용을 낮게 유지하는 데 도움이 되는 두 가지 추가 기능이 있습니다. [McpToolOutput]은 반환되는 형태를 결정합니다. Fields는 응답을 나열된 최상위 JSON 속성으로 투영(project)하며, MaxLength는 결과를 잘라냅니다(truncate).

[HttpGet("{id}")]
[McpTool]
[McpToolOutput(Fields = new[] { "id", "status" }, MaxLength = 500)]
...

두 번째 추가 기능은 토큰 리포트(token-report) 도구입니다. 에이전트는 사용자가 질문을 하기 전에 모든 도구의 이름, 설명, 입력 스키마(input schema)를 컨텍스트(context)에 로드하므로, 비대한 도구 표면은 실제로 반복되는 컨텍스트 비용을 발생시킵니다. mcp-token-report로 이를 측정할 수 있습니다:

dotnet tool install -g McpIt.TokenReport.Tool

mcp-token-report http://localhost:5199/mcp             # 라이브 서버 또는 저장된 tools-list.json
...

이 방식은 완전히 오프라인이며 결정론적(deterministic)이므로, --budget을 사용하여 CI 빌드에 게이트를 설정해도 안전합니다. 카운트(counts)는 오프라인 휴리스틱 토크나이저(heuristic tokenizer)에서 생성됩니다. 이는 도구를 비교하고 비대해진 부분(bloat)을 포착하기 위한 추정치이며, 정확한 과금용 수치가 아닙니다.

솔직한 현재의 한계점

McpIt은 v1.0.0 버전이며, 사전에 알아두어야 할 몇 가지 예외적인 상황들이 있습니다:

  • .NET 10을 대상으로 하며 ModelContextProtocol.AspNetCore 1.4.0을 기반으로 구축되었습니다.
  • 컨트롤러(controllers) 중심이며, 최소 API(minimal-API) 지원도 함께 제공합니다. 가장 풍부한 기능은 컨트롤러 경로에서 작동합니다.
  • 출력 형태(Output shaping)는 최선 노력(best-effort) 방식입니다. 형식이 잘못된 JSON은 재구성되지 않고 그대로 통과됩니다.
  • 토큰 카운트는 **휴리스틱 추정치(heuristic estimates)**이며, 제공업체(provider)의 정확한 과금 수치가 아닙니다.

이 중 어떤 것도 핵심 사용 사례를 막지는 않지만, 도입하기 전에 이를 알고 있어야 합니다.

사용해 보기

.NET에서의 MCP는 현재 매우 주목받고 있습니다. Visual Studio 2026에는 MCP 지원이 내장되어 출시되었고, Aspire도 이를 적극 수용하고 있으며, SDK는 1.0 버전에 도달했습니다. 이미 ASP.NET Core API를 보유하고 있다면, 이것은 "엔드포인트가 있다"에서 "에이전트가 이를 사용할 수 있다"로 가는 가장 짧은 경로입니다.

단 하나의 [McpTool] 속성(attribute), 리플렉션(reflection) 없음, 프록시(proxy) 없음, 직접 작성하는 서버 없음. 이것이 핵심 제안입니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0