MCP for .NET: 실제로 작업을 수행할 수 있는 AI 에이전트
Source: Dev.to
Crysta는 실제 비즈니스에 사용할 수 있는 AI 에이전트를 직접 만들 수 있는 AI 앱입니다.
표준 챗봇과 달리, 다양한 MCP 서버를 연결하고 에이전트에게 일정 관리, 예약, 데이터 접근 등 실용적인 기능을 부여할 수 있습니다. 요컨대, Crysta는 단순히 대화만 하는 것이 아니라 실제로 업무를 수행할 수 있는 AI 에이전트를 구축하도록 도와줍니다.
사용자가 연결할 수 있는 것
MCP를 사용하면 에이전트가 다음과 같은 도구에 연결할 수 있습니다:
- Google Calendar 워크플로우
- 예약 및 일정 관리 시스템
- MCP를 통해 노출되는 비즈니스 데이터 도구
- DeepWiki와 같은 지식 도구 (MCP를 통해)
따라서 “회의 예약”과 같은 요청에만 답변하는 것이 아니라, 에이전트가 연결된 도구를 통해 실제로 작업을 수행할 수 있습니다.
.NET 개발자를 위한 중요성
MCP는 .NET 개발자에게 모든 통합을 직접 구축하지 않고도 AI 에이전트에 실제 기능을 손쉽게 추가할 수 있는 방법을 제공합니다. 각 API를 애플리케이션에 직접 연결하는 대신, MCP‑호환 도구를 연결하고 에이전트가 동일한 함수‑호출 흐름을 통해 이를 사용하도록 할 수 있습니다.
혜택
- 빠른 개발: 새로운 기능은 새로운 통합을 작성하는 것이 아니라 MCP 도구를 추가함으로써 얻습니다.
- 깔끔한 아키텍처: 에이전트는 더 많은 프롬프트 로직이나 맞춤형 연결 코드를 추가하는 것이 아니라 도구를 추가함으로써 성장합니다.
구축 방법 (고수준)
- 사용자가 에이전트에 MCP 서버 링크를 추가합니다.
- 시스템이 링크를 검증하고 도구 메타데이터를 읽어옵니다.
- 연결된 MCP 도구가 해당 에이전트의 사용 가능한 작업에 포함됩니다.
- 채팅 중에 모델이 필요할 때 해당 도구를 호출할 수 있습니다.
- 실패 및 연결 상태가 추적되어 사용자가 끊어진 링크를 빠르게 수정할 수 있습니다.
우리가 사용하는 패키지
ModelContextProtocolMicrosoft.Extensions.AIMicrosoft.Extensions.AI.OpenAIAzure.AI.OpenAI
이 조합은 .NET에서 MCP 도구 검색과 견고한 함수 호출 파이프라인을 제공합니다.
작은 코드 예제 (우리 코드 기반)
1) MCP 클라이언트 + 검증 서비스
using ModelContextProtocol.Client;
public class McpServerService : IMcpServerService
{
public async Task ValidateAndGetMcpInfoAsync(string mcpUrl)
{
if (!Uri.TryCreate(mcpUrl, UriKind.Absolute, out _))
{
return new StoredMcpServer { IsValid = false, ErrorMessage = "Invalid URL format" };
}
try
{
var transport = new HttpClientTransport(
new HttpClientTransportOptions { Endpoint = new Uri(mcpUrl) },
loggerFactory: null);
var client = await McpClient.CreateAsync(transport);
var serverInfo = client.ServerInfo;
return new StoredMcpServer
{
Url = mcpUrl,
Title = serverInfo?.Name ?? "Unknown MCP Server",
Description = serverInfo?.Title ?? "No description available",
AddedDate = DateTime.Now,
IsValid = serverInfo is not null
};
}
catch (Exception ex)
{
return new StoredMcpServer { IsValid = false, ErrorMessage = ex.Message };
}
}
public async Task CreateClientAsync(string mcpUrl, CancellationToken cancellationToken = default)
{
var transport = new HttpClientTransport(
new HttpClientTransportOptions { Endpoint = new Uri(mcpUrl) },
loggerFactory: null);
return await McpClient.CreateAsync(transport);
}
}
2) 에이전트 스킬에서 MCP 도구 로드 (런타임)
using Microsoft.Extensions.AI;
using ModelContextProtocol.Client;
private async Task> GetMcpToolsAsync()
{
if (interactiveAgent?.Skills == null) return [];
var allTools = new List();
using var scope = ServiceScopeFactory.CreateScope();
var mcpServerService = scope.ServiceProvider.GetRequiredService();
foreach (var skill in interactiveAgent.Skills)
{
if (skill.SkillType != SkillType.MCP) continue;
if (skill.SkillJson is null) continue;
var check = await mcpServerService.ValidateAndGetMcpInfoAsync(skill.SkillJson);
if (!check.IsValid) continue;
var client = await mcpServerService.CreateClientAsync(skill.SkillJson);
var tools = await client.ListToolsAsync();
allTools.AddRange(tools);
}
return allTools;
}
3) Microsoft.Extensions.AI 채팅 파이프라인에 MCP 도구 연결
using System.ClientModel;
using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;
var azureChatClient = new AzureOpenAIClient(
new Uri(endpoint),
new ApiKeyCredential(apiKey))
.GetChatClient(deployment)
.AsIChatClient();
var mcpTools = await GetMcpToolsAsync();
var chatClient = new ChatClientBuilder(azureChatClient)
.ConfigureOptions(options =>
{
options.Tools ??= [];
foreach (var tool in mcpTools)
{
options.Tools.Add(tool);
}
})
.UseFunctionInvocation(c => c.AllowConcurrentInvocation = true)
.Build();
이것이 우리가 실제로 사용하는 정확한 아이디어입니다: MCP 링크를 검증하고, 도구를 발견한 뒤, 해당 도구들을 채팅 클라이언트에 전달하여 에이전트가 호출할 수 있도록 합니다.
마무리
MCP는 우리 제품을 “답변하는 AI”에서 “행동하는 AI”로 전환했습니다.
그것이 사용자가 즉시 눈치채는 차이점입니다.
최종 결과를 보고 싶다면, 여기에서 확인하세요: