👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
Add MCP to Existing .NET REST Endpoints

Add MCP to Existing .NET REST Endpoints

Author - Abdul Rahman (Bhai)

MCP

1 Articles

Improve

Table of Contents

  1. What we gonna do?
  2. Why we gonna do?
  3. How we gonna do?
  4. Summary

What we gonna do?

Your existing REST APIs work great for web and mobile apps. But what if AI agents and chatbots could use them too—without you rewriting everything? That's exactly what the Model Context Protocol (MCP) enables. In this article, let's learn how to add MCP capabilities to your existing ASP.NET Core REST APIs, turning them into AI-ready backends with minimal effort.

Why we gonna do?

Here's the thing: many organizations already have robust REST APIs powering their applications. These APIs handle everything from customer data to order processing to reporting. But now, there's a growing need to enable AI agents, chatbots, and LLMs to interact with these same systems.

Without MCP, you'd face a challenging choice: either rebuild your APIs specifically for AI consumption, or create complex integration layers that duplicate your existing logic. Neither option is appealing.

Real-World AI Use Cases

Think about these practical scenarios that are happening right now:

  • Sales Assistant: An AI that updates your CRM, schedules follow-ups automatically, and provides sales briefs without manual data entry.
  • KPI Dashboard Agent: A chatbot that proactively monitors key performance indicators and alerts you when metrics fall out of range.
  • Customer Support Copilot: An AI that handles 80% of routine support inquiries by directly accessing order status, shipping dates, and account information.
  • Document Generation: Automated creation of reports by merging templates with data from multiple backend systems.
  • Procurement Automation: AI agents that create purchase orders, verify budgets, and route approvals to the right people.

That's why MCP matters. It's an open-source standard that lets you bolt AI capabilities onto your existing REST APIs. Your current endpoints keep working for your web and mobile apps, while AI agents can now access the same functionality through a standardized protocol designed specifically for AI interaction.

How we gonna do?

Understanding MCP

Before we dive into implementation, let's understand what MCP actually is. The Model Context Protocol is an open-source standard introduced by Anthropic that enables bidirectional communication between AI systems and external data sources.

MCP connects three types of components:

  • AI Clients: ChatGPT, Claude, AI agents, development tools like VS Code
  • MCP Protocol: The standardized communication layer in the middle
  • MCP Servers: Your backend systems - databases, APIs, SaaS products, productivity tools

The beauty of MCP is that it's bidirectional—data flows both ways. AI agents can read data from your systems and also make updates, all through a consistent protocol.

MCP vs REST: Similarities and Differences

If you're thinking "isn't this just REST for AIs?"—you're partially right. Let's break down the key differences:

Aspect REST MCP
Audience Developers, service integrations LLMs, AI agents, humans via chatbots
Discoverability Optional (OpenAPI/Swagger) Required, runtime discoverable
Contracts URL endpoints, HTTP verbs, status codes Named tools, JSON schemas, structured results
Transport HTTP only Standard I/O, Streamable HTTP, or custom
Orchestration Manual code to stitch calls together AI agents handle multi-step workflows
Streaming Uncommon First-class citizen
Authentication Built-in (OAuth, JWT, etc.) Depends on transport (OAuth available with HTTP)

The key insight: MCP servers automatically version themselves. When an AI client connects, it discovers all available tools in real-time. No manual documentation updates needed.

MCP Transport Options

MCP supports three transport mechanisms:

  • Standard I/O: Best for local scenarios where your AI and MCP server run on the same machine. Uses standard input/output for fast, secure interprocess communication.
  • Streamable HTTP: Essential for remote scenarios. Uses HTTP POST for sending data and server-sent events for receiving streamed responses. Works with existing OAuth infrastructure and network proxies.
  • Custom Transports: The spec allows custom implementations for specialized use cases, though details are left to implementers.

Setting Up Your .NET Project

Let's walk through adding MCP to an existing ASP.NET Core REST API. We'll use a simple to-do API as our example, but the principles apply to any REST API you've already built.

First, ensure you have .NET 10 or later installed. The MCP C# SDK has significant improvements in .NET 10, including better OAuth support, structured outputs, and simplified APIs.

Step 1: Install the MCP SDK

Add the MCP C# SDK to your project:


dotnet add package ModelContextProtocol.AspNetCore
            

Step 2: Configure MCP in Program.cs

In your Program.cs, add the MCP server configuration. This sets up the MCP endpoint and tells it where to find your tools:


using Microsoft.Extensions.AI.MCP;

var builder = WebApplication.CreateBuilder(args);

// Existing services
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// Add MCP Server
builder.Services.AddMcpServer()
    .WithHttpTransport()
    .WithToolsFromAssembly();

var app = builder.Build();

// Existing middleware
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

// Map MCP Server
app.MapMcpServer("/mcp");

// Your existing REST endpoints
app.MapEndpoints();

app.Run();
            

Here's what's happening:

  • AddMcpServer(): Registers the MCP server services
  • WithHttpTransport(): Configures HTTP streaming for remote access
  • WithToolsFromAssembly(): Automatically discovers tools marked with MCP attributes
  • MapMcpServer("/mcp"): Exposes the MCP endpoint at /mcp

Step 3: Create Your Existing REST Endpoints

Let's look at a typical REST API setup. Here's a simple to-do API with standard endpoints:


public static class TodoEndpoints
{
    public static void MapEndpoints(this IEndpointRouteBuilder app)
    {
        var group = app.MapGroup("/api/todos");

        group.MapGet("/", GetAllTodos);
        group.MapPost("/", CreateTodo);
        group.MapPatch("/{id}/complete", MarkComplete);
        group.MapPatch("/{id}/incomplete", MarkIncomplete);
    }

    private static async Task<IResult> GetAllTodos(TodoStore store)
    {
        var todos = await store.GetAllAsync();
        return Results.Ok(todos);
    }

    private static async Task<IResult> CreateTodo(CreateTodoRequest request, TodoStore store)
    {
        var todo = await store.AddAsync(request.Title, request.IsComplete);
        return Results.Created($"/api/todos/{todo.Id}", todo);
    }

    private static async Task<IResult> MarkComplete(int id, TodoStore store)
    {
        var todo = await store.UpdateCompleteStatusAsync(id, true);
        return Results.Ok(todo);
    }

    private static async Task<IResult> MarkIncomplete(int id, TodoStore store)
    {
        var todo = await store.UpdateCompleteStatusAsync(id, false);
        return Results.Ok(todo);
    }
}
            

These endpoints work great for web and mobile clients. Now let's add MCP capabilities without touching this code.

Step 4: Create MCP Tools

Here's where the magic happens. Create a separate class for your MCP tools with attribute-based discovery:


using Microsoft.Extensions.AI.MCP;

[McpServerToolType]
public class TodoMcpTools
{
    private readonly TodoStore _store;

    public TodoMcpTools(TodoStore store)
    {
        _store = store;
    }

    [McpServerTool(
        Description = "Get all to-do items, optionally filtered by completion status. " +
                     "Pass true for completed items, false for incomplete items, or omit to get all items.")]
    public async Task<IEnumerable<Todo>> GetTodos(
        [Description("Filter by completed status: true for completed items, false for incomplete items, or omit to get all items")]
        bool? complete = null)
    {
        var todos = await _store.GetAllAsync();
        
        if (complete.HasValue)
        {
            return todos.Where(t => t.IsComplete == complete.Value);
        }
        
        return todos;
    }

    [McpServerTool(
        Description = "Create a new to-do item with the specified title and completion status.")]
    public async Task<Todo> CreateTodo(
        [Description("The title or description of the to-do item")]
        string title,
        [Description("Whether the to-do is already complete (default: false)")]
        bool isComplete = false)
    {
        return await _store.AddAsync(title, isComplete);
    }

    [McpServerTool(
        Description = "Mark a to-do item as complete by its ID.")]
    public async Task<Todo> MarkTodoComplete(
        [Description("The unique identifier of the to-do item")]
        int id)
    {
        return await _store.UpdateCompleteStatusAsync(id, true);
    }

    [McpServerTool(
        Description = "Mark a to-do item as incomplete by its ID.")]
    public async Task<Todo> MarkTodoIncomplete(
        [Description("The unique identifier of the to-do item")]
        int id)
    {
        return await _store.UpdateCompleteStatusAsync(id, false);
    }
}
            

Let's break down what makes this work:

  • [McpServerToolType]: Marks this class as containing MCP tools. The SDK's assembly scanner finds this attribute automatically.
  • [McpServerTool]: Marks each method as an MCP tool. The Description property is crucial—it tells the LLM what the tool does and how to use it.
  • [Description]: Documents each parameter. Be explicit! The more detail you provide, the better the AI understands when and how to use each parameter.

Notice how the MCP tools mirror your REST endpoints but with potentially different business logic. You might want to:

  • Expose only certain operations to AI agents
  • Apply different validation rules
  • Return data in AI-optimized formats
  • Add additional guardrails or rate limiting

Step 5: Test with an AI Client

Now let's see it in action. Open Claude Desktop (or any MCP-compatible AI client) and configure it to connect to your MCP server. You can interact naturally with your API:


You: Do I have anything to do right now?

Claude: [Calling GetTodos tool...]
Yes, you have one incomplete to-do: "Demo https://ilovedotnet.org"
Would you like me to mark it as completed?

You: Yes, please do that. I'm just finishing the demo now.

Claude: [Calling MarkTodoComplete tool with id=1...]
Done! I've marked "Demo https://ilovedotnet.org" as complete. Your to-do list is now clear.

You: Do I have anything else to do?

Claude: [Calling GetTodos with complete=false...]
Nope, your to-do list is clear. All tasks are complete!
            

The AI agent is making real API calls through your MCP server, using the same underlying data store and business logic as your REST endpoints.

Key Features of the MCP C# SDK

The MCP C# SDK provides several powerful features:

  • Attribute-Based Discovery: Just add attributes to your methods, and they're automatically discovered and exposed as MCP tools.
  • Microsoft.Extensions.AI Integration: Works seamlessly with the broader .NET AI ecosystem.
  • Multiple Transports: Standard I/O for local scenarios, HTTP for remote access.
  • Client Support: You can also build MCP clients in C# to consume other MCP servers.
  • Standards Compliant: Works with any MCP server or client, regardless of implementation language.

This is perfect if you want to quickly enable AI access to specific operations without modifying your application code.

Best Practices

When adding MCP to your existing REST APIs, keep these principles in mind:

  • Be Explicit in Descriptions: The quality of your tool descriptions directly impacts how well AI agents can use them. Don't skimp on details.
  • Separate Concerns: Keep your MCP tools separate from your REST endpoints. This gives you flexibility to apply different business rules or expose different capabilities.
  • Consider Security: Apply appropriate authentication and authorization. Just because an AI can call your API doesn't mean it should have unrestricted access.
  • Start Small: Begin with read-only operations, then gradually add write capabilities as you build confidence.
  • Monitor and Log: Track how AI agents use your APIs. This helps you optimize descriptions and identify potential issues.

Summary

Adding MCP capabilities to your existing ASP.NET Core REST APIs is straightforward with the MCP C# SDK. By adding a few attributes and configuration lines, you can enable AI agents and chatbots to interact with your backend systems using the same data and business logic that powers your web and mobile applications.

The key benefits:

  • Minimal Code Changes: Your existing REST endpoints remain untouched
  • Standards-Based: MCP is an open-source protocol that works with any compatible AI client
  • Runtime Discoverability: Tools automatically version themselves—no manual documentation needed
  • Flexible Security: Apply OAuth and other authentication mechanisms appropriate to your needs
  • Production Ready: Built on .NET's robust infrastructure with improvements in .NET 10

Whether you're building sales assistants, customer support copilots, or automated procurement workflows, MCP provides the bridge between your existing APIs and the world of AI agents. Start with read-only operations, test thoroughly, and gradually expand capabilities as you see what's possible.

The future of software isn't just about APIs for machines or UIs for humans—it's about enabling AI agents to work alongside both. MCP gets you there without reinventing everything you've already built.

👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
  • MCP
  • MCP
  • Model Context Protocol
  • REST API
  • AI Integration
  • ASP.NET Core
  • C# SDK
  • AI Agents
  • Chatbots
  • API Management