# Xây MCP server trong ASP.NET Core từ đầu

[Waqas Anwar](https://homus.dev/speakers/waqas-anwar) · [EzzyLearning](https://homus.dev/orgs/ezzylearning)

> Dựng MCP server trong ASP.NET Core bằng C# SDK chính thức: đăng ký server, viết MCP tool gọi service có sẵn, tách MCP khỏi business logic.

Topics: Dev Tools, Agents

Canonical: https://homus.dev/talks/build-an-mcp-server-in-asp-net-core-from-scratch

## 1. Đưa business functionality của app ASP.NET Core tới AI assistant

Waqas Anwar mở video bằng một câu hỏi: sẽ thế nào nếu ứng dụng ASP.NET Core của bạn có thể expose business functionality của nó trực tiếp cho một AI assistant? Thay vì viết custom integration riêng cho từng ứng dụng AI, bạn có thể expose ứng dụng của mình qua MCP, tức Model Context Protocol (theo Waqas, video đăng ngày 17/10/2026).

![Slide: một ASP.NET Core Application nhận hai mũi tên Custom code for Claude và Custom code for Gemini](https://homus.dev/photos/a9jQ-f1YxfU-0123.jpg)

Slide mở đầu: một ASP.NET Core Application, với hai mũi tên ghi "Custom code for Claude" và "Custom code for Gemini". Mỗi AI client cần một đoạn code tích hợp riêng, đúng vấn đề Waqas đặt ra (video đăng ngày 17/10/2026).

Trong video này, anh sẽ build một MCP server trong ASP.NET Core từ đầu, và người xem sẽ học cách expose business functionality cùng các tình huống ứng dụng thực tế qua MCP server đó.

## 2. Video này sẽ làm gì

Sau lời chào, Waqas nhắc lại: trong video tutorial này, anh sẽ build một MCP server bằng ASP.NET Core và C#. Anh bắt đầu từ một ứng dụng ASP.NET Core đơn giản, tạo một MCP tool lấy thông tin sản phẩm (product information) từ database, rồi expose chức năng đó qua một MCP endpoint.

![Waqas Anwar nói trước camera trong phòng làm việc](https://homus.dev/photos/a9jQ-f1YxfU-0030.jpg)

Waqas Anwar nói trước camera ở phần giới thiệu, trước khi chuyển sang slide và code.

Điều quan trọng nhất, theo anh: video sẽ tập trung vào code và architecture, thay vì dành phần lớn thời lượng cho lý thuyết MCP. Đến cuối video, người xem sẽ hiểu MCP nằm ở đâu trong một ứng dụng .NET thật, và làm thế nào để expose những capability sẵn có của ứng dụng cho các AI client.

## 3. MCP server là gì

Waqas định nghĩa: một MCP server là một chương trình đóng vai trò cây cầu chung (universal bridge), nối các AI model như Claude với các tool, database và nguồn dữ liệu bên ngoài (theo Waqas, video đăng ngày 17/10/2026).

![Slide What is MCP Server: Claude và Gemini cùng đi qua một khối MCP để tới ASP.NET Core Application](https://homus.dev/photos/a9jQ-f1YxfU-0107.jpg)

Slide "What is MCP Server?": Claude và Gemini không còn nối thẳng vào ứng dụng bằng code riêng, mà cùng đi qua một khối MCP ở giữa để tới ASP.NET Core Application (video đăng ngày 17/10/2026).

Trước khi có Model Context Protocol, developer phải viết code riêng cho từng app AI, từng tool hay từng API. Theo anh, MCP server chuẩn hoá phần giao tiếp này: bạn viết integration code một lần dưới dạng MCP server, và bất kỳ AI client nào tương thích cũng hiểu và dùng được nó ngay (video đăng ngày 17/10/2026).

## 4. Hai pha: discovery và execution

Workflow ở mức high level, theo Waqas (video đăng ngày 17/10/2026), gồm hai pha. Pha đầu là **discovery**: AI client kết nối tới một MCP server và hỏi server đó có những tool và dữ liệu nào.

![Slide How It Works: Claude gửi mũi tên Discovery tới khối MCP Server có Tools và Resources mờ](https://homus.dev/photos/a9jQ-f1YxfU-0143.jpg)

Slide "How It Works": Claude gửi yêu cầu "Discovery" tới MCP Server; bên trong server là Tools, còn Resources đang hiện mờ. Bên trái là ứng dụng mà server đứng trước (video đăng ngày 17/10/2026).

Tiếp theo là pha **execution**: server expose các capability như đọc file, truy vấn database hay chạy một số function cụ thể. Trong lúc trao đổi, client và server nói chuyện với nhau bằng những định dạng gọn nhẹ như JSON-RPC. Chúng có thể chạy local ngay trên máy của bạn, hoặc chạy remote qua internet (theo Waqas, video đăng ngày 17/10/2026). Tài liệu architecture của MCP cũng ghi các message dùng định dạng JSON-RPC 2.0 trên mọi transport (đọc ngày 29/10/2026).

## 5. Ba thành phần cốt lõi: tools, resources, prompts

Các thành phần cốt lõi mà một MCP server expose là tools, resources và prompts (theo Waqas, video đăng ngày 17/10/2026):

- **Tools** là những hành động AI có thể thực hiện, ví dụ chạy một truy vấn tìm kiếm trên database hay cập nhật một spreadsheet (theo Waqas, video đăng ngày 17/10/2026).

- **Resources** là dữ liệu AI có thể đọc, ví dụ tài liệu, file code hay database schema (theo Waqas, video đăng ngày 17/10/2026).

- **Prompts** là các template dùng lại được, để dẫn dắt cuộc giao tiếp giữa MCP server và các AI client (theo Waqas, video đăng ngày 17/10/2026).

![Slide Core Components Exposed by MCP Server: Tools, Resources, Prompts](https://homus.dev/photos/a9jQ-f1YxfU-0223.jpg)

Slide "Core Components Exposed by MCP Server": Tools, "Actions the AI can perform"; Resources, "Data the AI can read"; Prompts, "Reusable templates to guide interactions" (video đăng ngày 17/10/2026). Trang server concepts của MCP cũng chia server thành đúng ba building block này (đọc ngày 29/10/2026).

## 6. Chúng ta sẽ build gì

Trước khi viết dòng code nào, Waqas giải thích thứ sắp build. Hãy tưởng tượng ta đã có sẵn một ứng dụng ASP.NET Core chứa products và orders (mô tả video gọi đây là một ví dụ product-management thực hành; dữ liệu là mẫu). Bình thường, một ứng dụng khác sẽ tương tác với hệ thống này qua REST API (theo Waqas, video đăng ngày 17/10/2026).

![Slide What Are We Building: Normal Application qua Web API và AI Application qua MCP cùng vào ASP.NET Core, rồi Application/Business Logic, rồi Database](https://homus.dev/photos/a9jQ-f1YxfU-0303.jpg)

Slide "What Are We Building?": Normal Application đi vào ASP.NET Core qua "Web API", AI Application đi vào qua "MCP"; cả hai cùng dùng chung lớp Application/Business Logic và Database. Ba gạch đầu dòng dưới nhánh MCP: "Discover tool", "Understand what it does", "What parameters it accepts" (video đăng ngày 17/10/2026).

Nhưng theo Waqas, một ứng dụng AI không nhất thiết cần một REST API truyền thống cho mọi tương tác. Với MCP, ta có thể expose những capability cụ thể của ứng dụng dưới dạng tool mà AI client có thể discover và invoke. AI client discover được tool đó, hiểu nó làm gì, nó nhận những parameter nào, và cuối cùng invoke nó khi thích hợp (theo Waqas, video đăng ngày 17/10/2026).

## 7. Project ASP.NET Core và một NuGet package duy nhất

Anh bắt đầu với một ứng dụng ASP.NET Core chuẩn. Anh dùng .NET 10, và đã tạo một ứng dụng ASP.NET Core dạng minimal, vì như vậy demo tập trung được vào MCP. Trước hết, anh xem cần NuGet package nào để build một MCP server: anh chỉ thêm đúng một package, `ModelContextProtocol.AspNetCore`, vào ứng dụng này (demo trong video đăng ngày 17/10/2026).

![Visual Studio mở file project AspNetMcpServer với TargetFramework net10.0 và PackageReference ModelContextProtocol.AspNetCore](https://homus.dev/photos/a9jQ-f1YxfU-0323.jpg)

File project của solution AspNetMcpServer trong Visual Studio: target `net10.0` và một `PackageReference` duy nhất tới `ModelContextProtocol.AspNetCore`, phiên bản 2.2.0 trên màn hình. Solution Explorer bên phải có các thư mục Application, Domain, Infrastructure, Tools và file Program.cs (demo trong video đăng ngày 17/10/2026).

Nội dung file project trên màn hình:

```

net10.0
enable
enable

```

Theo Waqas (video đăng ngày 17/10/2026), đây là thư viện ASP.NET Core chính thức cho Model Context Protocol. Nó cho phép developer .NET build và host các MCP server chạy trên HTTP, đồng thời chuẩn hoá cách ứng dụng kết nối tới nguồn dữ liệu, tool và application context. README của MCP C# SDK mô tả package này là "the library for HTTP-based MCP servers" (đọc ngày 29/10/2026).

Điểm quan trọng ở đây, theo anh, là ta dùng phần tích hợp ASP.NET Core do MCP SDK cung cấp, chứ không tự implement giao thức MCP. Phần tích hợp này cho ta toàn bộ hạ tầng cần thiết để expose ứng dụng thành một MCP server (theo Waqas, video đăng ngày 17/10/2026).

## 8. Product model và product service

Trong ứng dụng, Waqas tạo một product model rất nhỏ với vài thuộc tính cơ bản: id, name, price và stock quantity. Với demo này, anh giữ dữ liệu trong bộ nhớ (in memory). Anh nói thêm: trong một ứng dụng thật, phần này đương nhiên có thể là EF Core, Dapper, một service khác, hay một application layer có sẵn (demo trong video đăng ngày 17/10/2026).

File `Product.cs` trong thư mục Domain trên màn hình:

```
namespace AspNetMcpServer.Domain
{
public sealed record Product(
int Id,
string Name,
decimal Price,
int StockQuantity);
}
```

Tiếp theo, anh tạo một abstraction là product service trong thư mục Application. Interface này chỉ expose hai method: `GetProduct` và `SearchProducts`. Phần implementation nằm trong thư mục Infrastructure, và ở đó anh tạo một danh sách sản phẩm mẫu trong bộ nhớ (demo trong video đăng ngày 17/10/2026).

![ProductService.cs với danh sách bốn sản phẩm mẫu và hai method GetProduct, SearchProducts](https://homus.dev/photos/a9jQ-f1YxfU-0443.jpg)

File `ProductService.cs` trong Infrastructure: danh sách bốn sản phẩm mẫu (Mechanical Keyboard, Wireless Mouse, USB-C Monitor, Laptop Stand) cùng hai method `GetProduct` và `SearchProducts` (demo trong video đăng ngày 17/10/2026).

```
using AspNetMcpServer.Application;
using AspNetMcpServer.Domain;

namespace AspNetMcpServer.Infrastructure
{
public sealed class ProductService : IProductService
{
private readonly List _products =
[
new(1, "Mechanical Keyboard", 120, 25),
new(2, "Wireless Mouse", 45, 100),
new(3, "USB-C Monitor", 350, 12),
new(4, "Laptop Stand", 80, 40)
];

public Product? GetProduct(int id)
{
return _products.FirstOrDefault(x => x.Id == id);
}

public IReadOnlyList SearchProducts(string search)
{
return _products
.Where(x => x.Name.Contains(
search,
StringComparison.OrdinalIgnoreCase))
.ToList();
}
}
}
```

Method `GetProduct` nhận product ID làm parameter và trả về sản phẩm khớp với ID đó. Tương tự, method `SearchProducts` nhận một từ khoá tìm kiếm và trả về danh sách sản phẩm có tên khớp với từ khoá (demo trong video đăng ngày 17/10/2026).

Implementation của service này rất đơn giản, nhưng điều quan trọng cần để ý, theo Waqas, là product service không biết gì về MCP, và đó là chủ ý. Anh gọi MCP là một cơ chế integration: nó không nên ép business logic cốt lõi của ta phải phụ thuộc vào giao thức MCP. Sự tách biệt này trở nên rất hữu ích khi cùng một business functionality còn được REST API, background job hay các thành phần khác của ứng dụng dùng tới (theo Waqas, video đăng ngày 17/10/2026).

## 9. Đăng ký MCP server trong Program.cs

Bây giờ đến phần cấu hình ứng dụng ASP.NET Core trong file `Program.cs`. Waqas nói class này trông rất đơn giản, nhưng có vài dòng quan trọng cần bàn. Trước hết, anh đăng ký application service bình thường của ứng dụng. Sau đó anh đăng ký MCP server bằng method `AddMcpServer` cùng vài method nối tiếp (demo trong video đăng ngày 17/10/2026).

![Program.cs với khối builder.Services.AddMcpServer().WithHttpTransport().WithToolsFromAssembly() được đóng khung và chữ WithHttpTransport bên phải](https://homus.dev/photos/a9jQ-f1YxfU-0543.jpg)

File `Program.cs`: khối đăng ký MCP server được đóng khung, chữ lớn "WithHttpTransport" bên phải nhấn vào method đang được giải thích; bên dưới là `app.MapMcp()` (demo trong video đăng ngày 17/10/2026).

```
using AspNetMcpServer.Application;
using AspNetMcpServer.Infrastructure;

namespace AspNetMcpServer
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddSingleton();

builder.Services
.AddMcpServer()
.WithHttpTransport()
.WithToolsFromAssembly();

var app = builder.Build();

app.MapMcp();

app.Run();
}
}
}
```

Theo giải thích của Waqas về SDK (video đăng ngày 17/10/2026): method `WithHttpTransport` chỉ định MCP server sẽ giao tiếp qua giao thức HTTP. Method `WithToolsFromAssembly` bảo SDK tự tìm (discover) các MCP tool trong ứng dụng. Cuối cùng, sau khi ứng dụng được build, ta gọi method `MapMcp`; method này map MCP endpoint vào ứng dụng ASP.NET Core.

Tới đây, theo anh, ta đã có hạ tầng. Việc còn lại là cho MCP biết ta muốn expose chức năng nào của ứng dụng (video đăng ngày 17/10/2026).

## 10. Class ProductTools: biến method C# thành MCP tool

Để expose chức năng của ứng dụng qua MCP tool, Waqas tạo một class `ProductTools` trong thư mục Tools, rồi phân tích từng phần (demo trong video đăng ngày 17/10/2026).

![ProductTools.cs với attribute McpServerToolType được đóng khung, hai method GetProduct và SearchProducts có McpServerTool và Description](https://homus.dev/photos/a9jQ-f1YxfU-0623.jpg)

File `ProductTools.cs`: attribute `[McpServerToolType]` trên class được đóng khung và nhắc lại bằng chữ lớn bên phải; hai method `GetProduct` và `SearchProducts` mang `[McpServerTool]` và `[Description]` (demo trong video đăng ngày 17/10/2026).

```
using AspNetMcpServer.Application;
using AspNetMcpServer.Domain;
using AspNetMcpServer.Infrastructure;

using ModelContextProtocol.Server;

using System.ComponentModel;

namespace AspNetMcpServer.Tools
{
[McpServerToolType]
public sealed class ProductTools
(IProductService productService)
{
[McpServerTool]
[Description("Gets a product by its ID.")]
public Product? GetProduct(
[Description("The ID of the product to retrieve.")]
int productId)
{
return productService.GetProduct(productId);
}

[McpServerTool]
[Description("Searches products by name.")]
public IReadOnlyList SearchProducts(
[Description("Text to search for in the product name.")]
string search)
{
return productService.SearchProducts(search);
}
}
}
```

Thứ nhất là attribute `McpServerToolType` trên đầu class. Theo Waqas, attribute này báo cho MCP SDK biết class này chứa các MCP tool. Thứ hai, method thật được đánh dấu bằng attribute `McpServerTool`; attribute này biến một method C# bình thường thành một MCP tool mà AI client có thể discover và invoke (theo Waqas, video đăng ngày 17/10/2026).

Phần description gắn kèm method và parameter cũng rất quan trọng. Anh nhấn mạnh: ta không chỉ viết tài liệu cho một developer khác đọc code, mà đang cung cấp metadata giúp MCP client hiểu tool này thực sự làm gì (theo Waqas, video đăng ngày 17/10/2026).

Anh cũng lưu ý: không có dòng code database nào trong các MCP tool này. MCP tool chỉ đơn giản chuyển request sang product service có sẵn. Theo anh, điều này quan trọng vì ta không phải expose toàn bộ database cho AI; thay vào đó, ta expose những business capability được chọn lọc kỹ của ứng dụng (theo Waqas, video đăng ngày 17/10/2026).

## 11. Thêm một business operation thật: kiểm tra tồn kho

Để demo thú vị hơn một chút, Waqas thêm một thao tác nghiệp vụ. Đọc dữ liệu thì hữu ích, nhưng theo anh, ứng dụng thật còn thực hiện các business operation. Giả sử ứng dụng có một thao tác kiểm tra sản phẩm còn hàng hay không: trên màn hình, anh thêm vào interface `IProductService` dòng `bool IsProductAvailable(int productId, int quantity);` (demo trong video đăng ngày 17/10/2026).

Implementation của method này cũng rất đơn giản. Đầu tiên, nó lấy sản phẩm khớp với parameter product ID. Sau đó nó kiểm tra số lượng tồn kho của sản phẩm có lớn hơn số lượng người dùng yêu cầu hay không; dòng code trên màn hình dùng phép so sánh `>=` (demo trong video đăng ngày 17/10/2026).

![ProductService.cs với method IsProductAvailable mới: lấy product theo id rồi so StockQuantity với quantity](https://homus.dev/photos/a9jQ-f1YxfU-0803.jpg)

Method `IsProductAvailable` mới trong `ProductService`: gọi `GetProduct(productId)`, rồi trả về `product is not null && product.StockQuantity >= quantity` (demo trong video đăng ngày 17/10/2026).

```
public bool IsProductAvailable(int productId, int quantity)
{
var product = GetProduct(productId);

return product is not null &&
product.StockQuantity >= quantity;
}
```

Cuối cùng, business operation này được expose qua MCP: anh tạo thêm một MCP tool nhận product ID và quantity làm parameter (demo trong video đăng ngày 17/10/2026).

```
[McpServerTool]
[Description("Checks whether the requested quantity of a product is available.")]
public bool IsProductAvailable(
[Description("The product ID.")]
int productId,
[Description("The quantity required.")]
int quantity)
{
return productService.IsProductAvailable(
productId,
quantity);
}
```

Giờ đây, theo Waqas (video đăng ngày 17/10/2026), AI client có thể hỏi kiểu: "Do we have five wireless mice available?" (chúng ta còn năm con chuột không dây không?). AI client có thể dịch yêu cầu này thành một tool call với product ID là 2 và quantity là 5; trong dữ liệu mẫu trên màn hình, sản phẩm số 2 là "Wireless Mouse".

Đường đi của câu hỏi mẫu trong video (video đăng ngày 17/10/2026): AI client dịch câu hỏi thành tool call, MCP tool chuyển sang service, và business rule nằm trong service của ứng dụng.

Phần quan trọng, theo Waqas, là business rule thực sự vẫn nằm trong application service của ta, còn lớp MCP chỉ đơn giản expose chức năng đó qua tool (theo Waqas, video đăng ngày 17/10/2026).

## 12. MCP khác REST API ở đâu

Tới đây, Waqas đoán người xem có thể đang nghĩ: sao không tạo luôn một REST API? Câu trả lời của anh: REST API vẫn hoàn toàn hợp lệ. Khác biệt quan trọng nằm ở interaction model. Với REST API truyền thống, client cần biết các API contract và tự quyết định gọi endpoint nào (theo Waqas, video đăng ngày 17/10/2026).

![Slide Why This Is Different: cột Traditional API với Client gọi GET /products/10 và GET /products/search?q=keyboard](https://homus.dev/photos/a9jQ-f1YxfU-0823.jpg)

Slide "Why This Is Different?": cột "Traditional API", nơi Client phải tự gọi đúng từng endpoint, như `GET /products/10` và `GET /products/search?q=keyboard` (video đăng ngày 17/10/2026).

Với MCP, theo anh, một AI client tương thích có thể discover các tool đang có cùng description của chúng, rồi invoke những tool đó khi cần. Vì vậy, thay vì build một custom integration riêng cho từng AI client, ta cung cấp một interface chuẩn cho mọi ứng dụng AI (theo Waqas, video đăng ngày 17/10/2026).

## 13. Điều cần mang về

Waqas nói đây là một trong những ý chính anh muốn người xem mang về từ video: MCP không thay thế business layer của bạn. Nó chỉ cung cấp một cách để AI client tương tác với chức năng mà ứng dụng của bạn expose (theo Waqas, video đăng ngày 17/10/2026).

Kiến trúc Waqas mô tả trong video đăng ngày 17/10/2026: MCP là một lối vào thêm cho AI client bên cạnh REST API, cả hai cùng gọi chung một business layer.

Và đó là pattern cơ bản để build một MCP server trong ASP.NET Core. Theo Waqas, nếu bạn đang build ứng dụng .NET và thử nghiệm với AI, MCP chắc chắn là thứ đáng để hiểu, vì nó cho bạn một ranh giới integration gọn gàng giữa các AI client và ứng dụng của bạn (video đăng ngày 17/10/2026).

## Nguồn và liên kết

- Tên gốc: Build an MCP Server in ASP.NET Core From Scratch
- Sự kiện: [YouTube](https://homus.dev/events/youtube)
- Video gốc: [https://www.youtube.com/watch?v=a9jQ-f1YxfU](https://www.youtube.com/watch?v=a9jQ-f1YxfU)

- Kênh YouTube EzzyLearning (Waqas Anwar): [youtube.com/channel/UClfCwZQsmZXoDcXYrfmj0Rg](https://www.youtube.com/channel/UClfCwZQsmZXoDcXYrfmj0Rg)

- Model Context Protocol, trang chính thức: [modelcontextprotocol.io](https://modelcontextprotocol.io/) (đọc ngày 29/10/2026)

- MCP architecture, phần message theo định dạng JSON-RPC 2.0: [modelcontextprotocol.io/docs/learn/architecture](https://modelcontextprotocol.io/docs/learn/architecture) (đọc ngày 29/10/2026)

- MCP server concepts, ba building block tools, resources, prompts: [modelcontextprotocol.io/docs/learn/server-concepts](https://modelcontextprotocol.io/docs/learn/server-concepts) (đọc ngày 29/10/2026)

- MCP C# SDK chính thức, README liệt kê package ModelContextProtocol.AspNetCore cho MCP server chạy trên HTTP: [github.com/modelcontextprotocol/csharp-sdk](https://github.com/modelcontextprotocol/csharp-sdk) (đọc ngày 29/10/2026)

- NuGet package ModelContextProtocol.AspNetCore: [nuget.org/packages/ModelContextProtocol.AspNetCore](https://www.nuget.org/packages/ModelContextProtocol.AspNetCore) (đọc ngày 29/10/2026)

Nguồn: https://homus.dev/talks/build-an-mcp-server-in-asp-net-core-from-scratch · cập nhật 2026-10-29
