所有人麦克
A.NET包装库,用于模型上下文协议(MCP)SDK,通过流畅的构建器模式简化MCP服务器配置。旨在降低在中构建MCP服务器时的复杂性。NET核心,在官方MCP SDK之上提供直观的API。
特性
- Fluent Builder API:易于使用的配置
AIKitMcpBuilder - 运输支持:Stdio和HTTP传输开箱即用
- 认证:OAuth 2.0、JWT承载、MCP特定和HTTP传输的自定义身份验证
- 每会话工具:根据会话上下文(例如路由参数)动态过滤和公开工具
- 自动发现:自动从程序集中发现工具、资源和提示
- 高级MCP功能:任务、进度通知、完成、采样和启发
- 日志记录:可配置的日志记录,带有stderr重定向,用于干净的stdio
建筑
AIKit。Mcp是一个 抽象层 建在 官方模型上下文协议C#SDK它简化了MCP服务器的开发,同时保持了与MCP规范的完全兼容性。
与官方MCP SDK的关系
- 什么AIKit。Mcp提供:流畅的配置API、自动发现、简化的身份验证和开发人员友好的模式
- 官方SDK提供了什么:低级MCP协议实现、核心类型和协议原语
- 何时使用官方SDK文档:了解MCP协议概念、高级定制或何时使用AIKit。Mcp抽象不能满足您的需求
核心组件
- AIKitMcpBuilder 的:Fluent API,用于配置MCP服务器(包装MCP SDK配置)
- 运输:使用MCP SDK传输处理通信(CLI客户端为Stdio,web客户端为HTTP)
- 认证:使用各种身份验证方法保护您的HTTP端点(扩展MCP SDK身份验证)
- 自动发现:自动查找并注册您的工具、资源和提示(简化MCP SDK注册)
- MCP服务器:处理MCP协议通信的运行时(由官方MCP SDK提供支持)
开发流程
- 配置:使用
AIKitMcpBuilder设置服务器(与手动MCP SDK设置相比) - 实施:创建具有简单属性的工具、资源和提示(与MCP SDK协议类型相比)
- 注册:呼叫
WithAutoDiscovery()自动注册您的组件(与手动注册相比) - 跑:使用启动服务器
app.RunAsync()(与MCP SDK相同)
关键抽象
该库处理MCP协议的复杂性,因此您可以专注于业务逻辑。您的代码会自动映射到MCP概念:
- 类与
[McpServerToolType]→ MCP工具(参见 MCP工具规格) - 类与
[McpServerResourceType]→ MCP资源(请参阅 MCP资源规范) - 通过以下方式注册的提示类
WithPrompts()→ MCP提示(见 MCP提示规范)
何时查阅官方文件
有关高级主题,请参阅 MCP C#SDK官方文档:
- MCP协议详细信息:了解完整的MCP规范和协议流程
- 自定义运输实施:构建超越stdio/HTTP的传输
- 高级身份验证:超出提供选项的自定义身份验证方案
- 协议扩展:实现自定义MCP消息类型或扩展
- 性能调优:MCP通信的低级优化
- 调试协议问题:MCP消息流的深度故障排除
安装
通过NuGet安装:
dotnet add package AIKit.Mcp快速开始
备注: ServerName 默认为“AIKit.Mcp”和 ServerVersion 默认为“1.0.0”。如果默认值适合您的需要,您可以省略这些属性。
基本标准服务器
为命令行MCP客户端创建一个通过stdio运行的简单MCP服务器:
using AIKit.Mcp;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddAIKitMcp(mcp =>
{
mcp.WithStdioTransport();
mcp.WithAutoDiscovery(); // Automatically finds tools, resources, and prompts
});
var app = builder.Build();
await app.RunAsync();具有JWT身份验证的HTTP服务器
使用JWT身份验证创建基于HTTP的MCP服务器:
using AIKit.Mcp;
using Microsoft.AspNetCore.Builder;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAIKitMcp(mcp =>
{
mcp.WithHttpTransport(opts =>
{
opts.HttpBasePath = "/mcp";
opts.WithJwtAuth(jwt =>
{
jwt.JwtIssuer = "https://your-issuer.com";
jwt.JwtAudience = "your-mcp-server";
jwt.SigningKey = "your-256-bit-secret-key-here"; // Use a secure key in production
});
});
mcp.WithAutoDiscovery();
});
var app = builder.Build();
app.UseAIKitMcp("/mcp");
await app.RunAsync();添加资源和提示
除了工具外,MCP服务器还可以提供资源(数据)和提示(可重用的提示模板)。
资源示例:
[McpServerResourceType]
public class DataResources
{
[McpServerResource(Name = "config",
Description = "Application configuration data",
MimeType = "application/json")]
public async Task GetConfig()
{
return JsonSerializer.Serialize(new { version = "1.0", environment = "prod" });
}
}提示示例:
[McpServerPromptType]
public class AnalysisPrompts
{
[McpServerPrompt(Name = "analyze_data",
Description = "Prompt for data analysis tasks")]
public string AnalyzeDataPrompt(string dataType)
{
return $"Please analyze the following {dataType} data and provide insights...";
}
}当您调用时,资源和提示都会自动发现 WithAutoDiscovery().
工具实施
通过装饰类和方法创建工具:
using ModelContextProtocol.Server;
[McpServerToolType]
public class MathTools
{
[McpServerTool(Name = "add")]
public double Add(double a, double b) => a + b;
[McpServerTool(Name = "multiply")]
public double Multiply(double a, double b) => a * b;
}配置选项
运输
WithStdioTransport():用于命令行MCP客户端WithHttpTransport(Action):用于基于HTTP的MCP通信
身份验证(仅限HTTP)
AIKit。Mcp支持HTTP传输的多种身份验证方法。根据您的安全要求和集成需求进行选择。
使用JwtAuth
直接JWT承载身份验证在没有OAuth 2.0流的情况下验证JWT令牌。当您已预先发行JWT令牌或希望与直接提供JWT令牌的系统集成时,这非常有用。
builder.Services.AddAIKitMcp(mcp =>
{
mcp.WithHttpTransport(opts =>
{
opts.WithJwtAuth(jwt =>
{
jwt.JwtIssuer = "your-issuer";
jwt.JwtAudience = "your-audience";
jwt.SigningKey = "your-symmetric-signing-key";
// Or use authority for asymmetric keys:
// jwt.Authority = "https://your-authority.com";
// Optional: Custom token validation
jwt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidAudience = "your-audience",
ValidIssuer = "your-issuer"
};
// Optional: JWT events for custom handling
jwt.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
// Custom validation logic
return Task.CompletedTask;
}
};
});
});
mcp.WithAutoDiscovery();
});JwtAuth的主要功能:
- 直接JWT验证:不需要OAuth流
- 对称/非对称密钥:支持HMAC和RSA/ECDSA签名
- 权威支持:OAuth授权机构的自动密钥解析
- 简单配置:基本JWT验证的最低设置
何时使用JwtAuth:
- 使用预先发行的JWT代币
- 直接发行代币的内部服务
- 没有OAuth复杂性的简单身份验证场景
- 与基于JWT的身份验证系统集成
使用CustomAuth
自定义身份验证允许您通过提供自己的身份验证处理程序来实现任何身份验证方案。这为专有或专门的身份验证要求提供了最大的灵活性。
builder.Services.AddAIKitMcp(mcp =>
{
mcp.WithHttpTransport(opts =>
{
opts.WithCustomAuth(custom =>
{
custom.SchemeName = "ApiKey";
custom.RegisterScheme = builder =>
{
builder.AddScheme("ApiKey", options => { });
};
});
});
mcp.WithAutoDiscovery();
});哪里 ApiKeyHandler 是您的自定义实现:
public class ApiKeyHandler : AuthenticationHandler
{
protected override async Task HandleAuthenticateAsync()
{
var apiKey = Request.Headers["X-API-Key"].FirstOrDefault();
if (string.IsNullOrEmpty(apiKey) || apiKey != "valid-key")
{
return AuthenticateResult.Fail("Invalid API key");
}
var identity = new ClaimsIdentity(Scheme.Name);
var principal = new ClaimsPrincipal(identity);
return AuthenticateResult.Success(new AuthenticationTicket(principal, Scheme.Name));
}
}
public class ApiKeyOptions : AuthenticationSchemeOptions { }CustomAuth的主要功能:
- 完全灵活:实现任何身份验证逻辑
- ASP。NET核心集成:使用标准身份验证处理程序模式
- 自定义方案:支持专有身份验证方法
- 处理器模式:利用ASP。NET Core的身份验证基础架构
何时使用CustomAuth:
- 专有身份验证方案
- API密钥验证
- 自定义令牌格式
- 与传统身份验证系统集成
- 专门的安全要求
使用McpAuth
McpAuth 提供符合MCP的身份验证,将JWT承载令牌验证与OAuth 2.0保护的资源元数据集成在一起。这使得MCP客户端和服务器之间能够按照以下步骤进行安全通信 OAuth 2.0受保护资源授权框架 规范。
builder.Services.AddAIKitMcp(mcp =>
{
mcp.WithHttpTransport(opts =>
{
opts.WithMcpAuth(mcpAuth =>
{
// JWT configuration - matches the official MCP SDK demo
mcpAuth.Authority = "https://your-oauth-server.com";
mcpAuth.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidAudience = "https://your-mcp-server.com/mcp",
ValidIssuer = "https://your-oauth-server.com",
NameClaimType = "name",
RoleClaimType = "roles"
};
// Note: If TokenValidationParameters is not set, defaults with ValidateIssuer=true,
// ValidateAudience=true, ValidateLifetime=true (already default), ValidateIssuerSigningKey=true are used
// OAuth 2.0 protected resource metadata
mcpAuth.ResourceMetadata = new ModelContextProtocol.Authentication.ProtectedResourceMetadata
{
ResourceDocumentation = "https://docs.example.com/api/mcp",
AuthorizationServers = { "https://your-oauth-server.com" },
ScopesSupported = ["mcp:tools", "mcp:resources"]
};
// Optional: JWT events for custom handling
mcpAuth.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
// Custom token validation logic
return Task.CompletedTask;
}
};
});
});
mcp.WithAutoDiscovery();
});McpAuth的主要功能:
- JWT Bearer集成:使用标准JwtBararOptions属性直接配置JWT令牌验证
- 资源元数据:为客户端发现提供OAuth 2.0保护的资源信息
- MCP合规性:遵循MCP身份验证规范,与官方SDK完全相同
- 直接配置:直接设置权限、TokenValidationParameters和事件以实现完全控制
何时使用McpAuth:
- 构建需要安全身份验证的生产MCP服务器
- 遵循与完全相同的身份验证模式 官方MCP SDK保护的McpServer
- 使用JWT承载令牌和OAuth 2.0资源元数据与OAuth 2.0身份提供者集成
- 通过标准化身份验证支持多个MCP客户端
有关完整的工作示例,请参阅 官方MCP C#SDK ProtectedMcpServer示例.
发现
WithAutoDiscovery():自动从程序集中发现工具、资源和提示
特性
EnableCompletion:自动完成EnableDevelopmentFeatures:调试日志记录
任务管理
AIKit。Mcp支持内存和基于文件的任务存储,用于长时间运行的操作:
- 内存存储 (默认):任务仅在服务器运行时存在
- 基于文件的存储:具有可配置TTL和会话隔离的持久任务存储
builder.Services.AddAIKitMcp(mcp =>
{
// Enable file-based task store with custom options
mcp.WithFileBasedTaskStore(opts =>
{
opts.StoragePath = Path.Combine(AppContext.BaseDirectory, "tasks");
opts.DefaultTtl = TimeSpan.FromHours(24);
opts.EnableSessionIsolation = true;
opts.FileExtension = ".task";
});
});任务存储选项:
StoragePath:任务文件目录(默认:./tasks)DefaultTtl:任务的默认生存时间(默认值:1小时)EnableSessionIsolation:按会话ID隔离任务(默认值:true)FileExtension:任务文件的文件扩展名(默认:.json)
高级用法
任务管理
使用任务助手进行后台操作和轮询:
using AIKit.Mcp;
public class TaskTools
{
private readonly IMcpTaskStore _taskStore;
public TaskTools(IMcpTaskStore taskStore)
{
_taskStore = taskStore;
}
[McpServerTool(Name = "submit_job")]
public async Task SubmitJob(string jobType)
{
// Create a background task
var task = await McpTaskHelpers.CreateTaskAsync(
_taskStore,
new McpTaskMetadata { TimeToLive = TimeSpan.FromHours(1) },
new RequestId(Guid.NewGuid().ToString()),
new JsonRpcRequest { Method = "background_job" },
"session-id",
async (progressToken, cancellationToken) =>
{
// Simulate long-running work
for (int i = 0; i PollTask(string taskId)
{
var task = await _taskStore.GetTaskAsync(taskId, "session-id");
if (task == null) return "Task not found";
return task.Status switch
{
McpTaskStatus.Working => $"Task is running (progress: {task.Progress?.Percentage ?? 0}%)",
McpTaskStatus.Completed => $"Task completed: {await _taskStore.GetTaskResultAsync(taskId, "session-id")}",
McpTaskStatus.Cancelled => "Task was cancelled",
_ => "Task status unknown"
};
}
}进度报告
using AIKit.Mcp;
public class LongRunningTool
{
[McpServerTool(Name = "long_task")]
public async Task LongTask(McpServer server, ProgressToken token)
{
for (int i = 0; i
{
mcp.MessageFilter = () => next => async (context, ct) =>
{
Console.WriteLine($"Incoming: {context.JsonRpcMessage.Method}");
await next(context, ct);
Console.WriteLine("Message processed");
};
});每会话工具
每会话工具允许您根据会话上下文(如HTTP路由参数、标头或其他特定于请求的数据)动态筛选和公开不同的工具集。这对于多租户应用程序、基于角色的访问控制或上下文感知工具可用性非常有用。
基本设置
首先,创建具有类别的工具类:
[McpServerToolType]
public class ClockTool
{
[McpServerTool(Name = "get_current_time", Description = "Get the current time")]
public string GetCurrentTime() => DateTime.Now.ToString("HH:mm:ss");
}
[McpServerToolType]
public class CalculatorTool
{
[McpServerTool(Name = "add_numbers", Description = "Add two numbers")]
public double Add(double a, double b) => a + b;
}
[McpServerToolType]
public class UserInfoTool
{
[McpServerTool(Name = "get_user_info", Description = "Get user information")]
public string GetUserInfo() => "User: admin, Role: administrator";
}配置
按类别注册工具并启用基于会话的筛选:
builder.Services.AddAIKitMcp(mcp =>
{
mcp.WithHttpTransport(opts =>
{
opts.HttpBasePath = "/mcp";
// Optional: Configure session options
opts.WithSessionOptions(sessionOpts =>
{
sessionOpts.RouteParameterName = "category"; // Default is "category"
});
});
// Register tools with categories
mcp.WithTools("time");
mcp.WithTools("math");
mcp.WithTools("admin");
// Enable auto-discovery for non-categorized tools if needed
mcp.WithAutoDiscovery();
});基于会话的筛选
工具根据会话上下文进行筛选。对于HTTP传输,这通常使用路由参数:
// Route: /mcp/time/* - Only time-related tools available
app.MapGet("/mcp/time/{sessionId}", ...);
// Route: /mcp/math/* - Only math-related tools available
app.MapGet("/mcp/math/{sessionId}", ...);
// Route: /mcp/admin/* - Only admin-related tools available
app.MapGet("/mcp/admin/{sessionId}", ...);自定义会话上下文
对于更高级的场景,您可以自定义如何确定会话上下文:
builder.Services.AddAIKitMcp(mcp =>
{
mcp.WithHttpTransport(opts =>
{
opts.WithSessionOptions(sessionOpts =>
{
// Custom logic to extract session context from HTTP context
sessionOpts.GetSessionContext = httpContext =>
{
// Example: Use user role from claims
var userRole = httpContext.User.FindFirst("role")?.Value ?? "guest";
return userRole switch
{
"admin" => "admin",
"user" => "basic",
_ => "guest"
};
};
});
});
// Register tools for different roles
mcp.WithTools("admin");
mcp.WithTools("basic");
mcp.WithTools("guest");
});主要特点
- 动态过滤:工具在运行时根据会话上下文进行筛选
- 基于类别的注册:使用字符串类别注册工具类型
- HTTP路由集成:基于路线参数的自动过滤
- 自定义上下文逻辑:实现自定义会话上下文提取
- 向后兼容:未分类的工具仍然适用于自动发现
用例
- 多租户应用程序:针对不同租户的不同工具
- 基于角色的访问:管理工具vs.用户工具vs.访客工具
- 功能标志:根据配置启用/禁用工具集
- 上下文感知服务:根据用户偏好或会话状态而变化的工具
建造和测试
# Build all projects
dotnet build src/AIKit.Mcp.slnx
# Run tests
dotnet test src/AIKit.Mcp.Tests/AIKit.Mcp.Tests.csproj故障排除
常见问题
“未找到工具”错误
- 确保你的工具类装饰有
[McpServerToolType] - 检查工具方法是否
[McpServerTool(Name = "...")]属性 - 验证
WithAutoDiscovery()在您的配置中调用
身份验证失败
- 对于JWT:验证发行者、受众和签名密钥是否与您的令牌匹配
- 对于OAuth:检查客户端ID、作用域和令牌验证参数
- 确保令牌已发送
Authorization: Bearer头球
HTTP传输不工作
- 验证
app.UseAIKitMcp("/mcp")在中间件管道中调用 - 检查基础路径是否与您的匹配
HttpBasePath配置 - 确保为HTTP传输正确配置了身份验证
标准运输问题
- Stdio服务器应由MCP客户端直接运行
- 检查日志输出是否存在连接错误
- 验证服务器是否正常启动
调试日志记录
启用详细日志记录以排除问题:
builder.Services.AddAIKitMcp(mcp =>
{
mcp.EnableDevelopmentFeatures = true;
// This enables debug logging and additional error details
});测试您的服务器
使用MCP检查器测试您的服务器:
# Install MCP CLI if not already installed
npm install -g @modelcontextprotocol/cli
# Test stdio server
mcp dev --stdio "dotnet run --project YourProject.csproj"
# Test HTTP server
mcp dev --http "http://localhost:5000/mcp"依赖项
- 模型上下文协议(>=0.80-review.1)
- 微软。扩展。日志记录(>=10.0.2)
- 微软。AspNetCore。身份验证。JwtBearer(>=10.0.2)\[用于HTTP身份验证\]
贡献
欢迎投稿!请查看当前任务的问题。
最佳实践
工具设计
- 描述性名称:为工具和参数使用清晰、描述性的名称
- 输入验证:始终验证输入并提供有意义的错误消息
- 异步操作:对I/O操作和长时间运行的任务使用异步方法
- 进度报告:对于>5秒的操作,实施进度报告
[McpServerToolType]
public class DataProcessingTools
{
[McpServerTool(Name = "process_large_dataset",
Description = "Process a large dataset with progress reporting")]
public async Task ProcessLargeDataset(string datasetId, McpServer server, ProgressToken token)
{
// Validate input
if (string.IsNullOrEmpty(datasetId))
throw new ArgumentException("Dataset ID is required");
// Report progress
for (int i = 0; i
{
// Validate required configuration
var jwtKey = Environment.GetEnvironmentVariable("JWT_SIGNING_KEY");
if (string.IsNullOrEmpty(jwtKey))
throw new InvalidOperationException("JWT_SIGNING_KEY environment variable is required");
mcp.WithHttpTransport(opts =>
{
opts.WithJwtAuth(jwt =>
{
jwt.JwtIssuer = Environment.GetEnvironmentVariable("JWT_ISSUER");
jwt.JwtAudience = Environment.GetEnvironmentVariable("JWT_AUDIENCE");
jwt.SigningKey = jwtKey;
});
});
});许可证
MIT许可证-有关详细信息,请参阅许可证文件。
路线图
- \[\]NuGet包发布
- \[\]其他身份验证提供程序
- \[\]WebSocket传输支持
- \[\]性能优化
