图木舒克市网站建设_网站建设公司_云服务器_seo优化
2026/1/16 3:28:03 网站建设 项目流程

Model Context Protocol (MCP) 是一个标准化协议,让 AI 客户端(如 Claude、ChatGPT 等)能够通过统一的接口调用你的 API。本文将详细介绍如何在 ASP.NET Core WebApi 项目中集成 MCP 支持,实现 AI 与你的服务无缝对接。

什么是 MCP?

MCP(Model Context Protocol)是一个开放协议,旨在标准化 AI 应用与外部工具、数据源之间的通信方式。通过 MCP,你的 API 可以:

被 AI 助手自动发现和调用

提供标准化的工具描述和参数定义

支持多种传输模式(HTTP、Stdio)

实现安全的认证和授权

核心特性

本项目实现了以下功能:

✅ 使用官方 ModelContextProtocol.AspNetCore SDK

✅ 通过 [McpServerTool] 特性快速定义工具

✅ 自动参数绑定和 JSON Schema 生成

✅ 支持 HTTP 和 Stdio 双传输模式

✅ 基于 Token 的认证和授权

✅ 与现有 WebApi 完美共存

快速开始

第一步:安装 NuGet 包

dotnet add package ModelContextProtocol.AspNetCore --version 0.4.0-preview.3

第二步:配置 MCP 服务

在 Program.cs 中添加 MCP 配置:

using ModelContextProtocol.Server;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

// 添加 MCP 服务器(支持 HTTP 和 Stdio 双模式)

builder.Services

.AddMcpServer(options =>

{

options.ServerInfo = new ModelContextProtocol.Protocol.Implementation

{

Name = "Weather API",

Version = "1.0.0"

};

})

.WithHttpTransport() // HTTP 模式:用于 Web 客户端

.WithStdioServerTransport() // Stdio 模式:用于 Kiro IDE 等本地工具

.WithToolsFromAssembly();

var app = builder.Build();

// 添加认证中间件(可选)

app.UseMiddleware<McpAuthenticationMiddleware>();

app.UseAuthorization();

app.MapControllers();

// 映射 MCP 端点

app.MapMcp("/mcp");

app.Run();

第三步:定义 MCP 工具

创建 Tools/WeatherTools.cs:

using System.ComponentModel;

using ModelContextProtocol.Server;

[McpServerToolType]

public static class WeatherTools

{

[McpServerTool]

[Description("Get weather forecast for the next 5 days")]

public static IEnumerable<WeatherForecast> GetWeatherForecast()

{

var rng = new Random();

return Enumerable.Range(1, 5).Select(index => new WeatherForecast

{

Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),

TemperatureC = rng.Next(-20, 55),

Summary = Summaries[rng.Next(Summaries.Length)]

}).ToArray();

}

[McpServerTool]

[Description("Get current weather for a specific city")]

public static WeatherForecast GetWeatherByCity(

[Description("The name of the city")] string city)

{

var rng = new Random();

return new WeatherForecast

{

Date = DateOnly.FromDateTime(DateTime.Now),

TemperatureC = rng.Next(-20, 55),

Summary = $"Weather in {city}: {Summaries[rng.Next(Summaries.Length)]}"

};

}

private static readonly string[] Summaries = new[]

{

"Freezing", "Bracing", "Chilly", "Cool", "Mild",

"Warm", "Balmy", "Hot", "Sweltering", "Scorching"

};

}

第四步:配置认证(可选)

在 appsettings.json 中配置:

{

"McpAuth": {

"Enabled": true,

"ValidTokens": ["your-secret-token-here"]

}

}

开发环境可以禁用认证(appsettings.Development.json):

{

"McpAuth": {

"Enabled": false

}

}

第五步:运行和测试

dotnet run

应用启动后,可以访问:

Swagger UI: http://localhost:5000/swagger

WebApi: http://localhost:5000/weatherforecast

MCP 端点: http://localhost:5000/mcp

传输模式详解

HTTP 模式

适用于 Web 应用、Claude Desktop、远程访问等场景。

测试示例:

# 列出所有工具

curl -X POST http://localhost:5000/mcp \

-H "Content-Type: application/json" \

-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

# 调用工具

curl -X POST http://localhost:5000/mcp \

-H "Authorization: Bearer your-secret-token-here" \

-H "Content-Type: application/json" \

-d '{

"jsonrpc":"2.0",

"id":2,

"method":"tools/call",

"params":{

"name":"GetWeatherForecast",

"arguments":{}

}

}'

Claude Desktop 配置:

编辑配置文件(Windows: %APPDATA%\Claude\claude_desktop_config.json):

{

"mcpServers": {

"weather-api": {

"url": "http://localhost:5000/mcp",

"headers": {

"Authorization": "Bearer your-secret-token-here"

}

}

}

}

Stdio 模式

适用于 Kiro IDE、本地命令行工具等场景,无需网络端口。

Kiro IDE 配置:

编辑 .kiro/settings/mcp.json:

{

"mcpServers": {

"weather-api": {

"command": "dotnet",

"args": ["run", "--project", "path/to/NetCoreApiMcpDemo.csproj"],

"env": {

"ASPNETCORE_ENVIRONMENT": "Development"

}

}

}

}

模式对比

特性 HTTP 模式 Stdio 模式

传输方式 HTTP POST 标准输入/输出

适用场景 Web 应用、远程访问 本地工具、IDE 集成

认证 HTTP Header 环境变量/配置

网络 需要网络端口 无需网络

性能 网络开销 进程间通信,更快

认证和授权

实现认证中间件

创建 Middleware/McpAuthenticationMiddleware.cs:

public class McpAuthenticationMiddleware

{

private readonly RequestDelegate _next;

private readonly IConfiguration _configuration;

private readonly ILogger<McpAuthenticationMiddleware> _logger;

public McpAuthenticationMiddleware(

RequestDelegate next,

IConfiguration configuration,

ILogger<McpAuthenticationMiddleware> logger)

{

_next = next;

_configuration = configuration;

_logger = logger;

}

public async Task InvokeAsync(HttpContext context)

{

// 只对 MCP 端点进行认证

if (!context.Request.Path.StartsWithSegments("/mcp"))

{

await _next(context);

return;

}

// 检查是否启用认证

var authEnabled = _configuration.GetValue<bool>("McpAuth:Enabled");

if (!authEnabled)

{

await _next(context);

return;

}

// 验证 Token

var authHeader = context.Request.Headers["Authorization"].FirstOrDefault();

if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith("Bearer "))

{

context.Response.StatusCode = 401;

await context.Response.WriteAsJsonAsync(new { error = "Unauthorized" });

return;

}

var token = authHeader.Substring("Bearer ".Length).Trim();

var validTokens = _configuration.GetSection("McpAuth:ValidTokens").Get<string[]>();

if (validTokens == null || !validTokens.Contains(token))

{

context.Response.StatusCode = 401;

await context.Response.WriteAsJsonAsync(new { error = "Invalid token" });

return;

}

await _next(context);

}

}

安全最佳实践

使用强 Token:至少 32 字符的随机字符串

定期轮换:定期更换 Token

使用 HTTPS:生产环境必须使用 HTTPS

环境隔离:开发和生产使用不同的 Token

日志安全:不要在日志中记录完整 Token

客户端集成示例

C# 客户端

using ModelContextProtocol;

using ModelContextProtocol.Client;

var transport = new HttpClientTransport(new HttpClientTransportOptions

{

BaseUrl = new Uri("http://localhost:5000/mcp"),

Headers = new Dictionary<string, string>

{

["Authorization"] = "Bearer your-secret-token-here"

}

});

var client = await McpClient.CreateAsync(transport);

await client.InitializeAsync(new InitializeParams

{

ProtocolVersion = "2025-06-18",

ClientInfo = new Implementation

{

Name = "MyApp",

Version = "1.0.0"

}

});

// 列出工具

var tools = await client.ListToolsAsync();

// 调用工具

var result = await client.CallToolAsync(

"GetWeatherForecast",

new Dictionary<string, object?>()

);

JavaScript/Vue 客户端

<script setup>

import { ref } from 'vue';

const weather = ref('');

const MCP_URL = 'http://localhost:5000/mcp';

const TOKEN = 'your-secret-token-here';

const callMcp = async (method, params = {}) => {

const response = await fetch(MCP_URL, {

method: 'POST',

headers: {

'Content-Type': 'application/json',

Authorization: `Bearer ${TOKEN}`,

},

body: JSON.stringify({

jsonrpc: '2.0',

id: Date.now(),

method,

params,

}),

});

return response.json();

};

const getWeather = async () => {

const data = await callMcp('tools/call', {

name: 'GetWeatherForecast',

arguments: {},

});

weather.value = data.result.content[0].text;

};

</script>

MCP Tools 最佳实践

让 AI 更准确地使用你的工具是成功的关键。以下是经过实践验证的最佳实践。

核心原则

AI 通过以下信息决定是否使用你的工具:

工具名称 - 清晰、描述性

Description - 详细的功能说明

参数描述 - 明确的参数用途

使用场景 - 何时应该使用这个工具

1. 使用清晰的命名

// ❌ 不好 - 名称模糊

[McpServerTool]

public static string Get() { }

// ✅ 好 - 动词开头,描述清晰

[McpServerTool]

public static string GetWeatherForecast() { }

// ✅ 更好 - 包含具体信息

[McpServerTool]

public static string GetWeatherForecastForNextDays() { }

命名建议:

使用动词开头:Get, Search, Calculate, Compare, Analyze

包含操作对象:Weather, Temperature, Forecast

避免缩写和简称

使用 PascalCase

2. 编写详细的 Description(最重要!)

这是最关键的部分!AI 主要通过 Description 判断是否使用工具。

// ❌ 不好 - 太简短

[Description("Get weather")]

// ⚠️ 一般 - 有基本信息但不够

[Description("Get weather forecast for the next 5 days")]

// ✅ 好 - 包含详细信息和使用场景

[Description(@"Get detailed weather forecast for the next several days including temperature, weather conditions, and trends.

Use this tool when users ask about:

- Future weather (tomorrow, next week, upcoming days)

- Weather predictions or forecasts

- Planning activities based on weather

- Temperature trends

Examples of user queries:

- 'What's the weather forecast for the next 5 days?'

- 'Will it rain this week?'

- 'What's the temperature trend?'")]

Description 应该包含:

功能说明 - 工具做什么

使用场景 - 何时使用("Use this tool when...")

示例查询 - 用户可能的提问方式

支持的功能 - 特殊能力或限制

3. 详细的参数描述

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询