1. MCP/ChatGPT应用开发概述
MCP(Model Context Protocol)是一种由Anthropic推出的开放标准协议,旨在为大型语言模型(LLM)与外部数据、应用和服务之间的通信提供标准化接口。通过MCP协议,开发者可以构建能够与ChatGPT等AI系统深度集成的应用程序,实现动态信息检索和自动化操作。
1.1 MCP协议的核心特性
MCP协议设计主要考虑以下几个关键特性:
- 会话上下文维护:支持多轮对话状态保持
- 工具调用能力:允许AI系统调用外部功能
- 流式响应:支持长时间任务的渐进式响应
- 服务端通知:服务端可主动推送消息
- 能力协商:客户端与服务端初始化的功能协商
1.2 MCP应用开发模式选择
MCP支持两种主要的开发模式:
有状态模式(Stateful)
- 服务端维护会话状态
- 适合复杂多步骤交互
- 需要额外的会话存储
- 部署复杂度较高
无状态模式(Stateless)
- 每次请求自包含完整信息
- 架构简单,易于部署
- 适合Serverless环境
- 客户端负担较重
对于大多数简单应用场景,推荐使用无状态模式,因其部署简单且易于扩展。
2. C# MCP服务端开发
2.1 基础环境搭建
首先创建ASP.NET Core Web API项目,并添加必要的NuGet包:
xml复制<ItemGroup>
<PackageReference Include="ModelContextProtocol.AspNetCore" Version="1.1.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.3" />
<PackageReference Include="Microsoft.OpenApi" Version="2.7.0" />
</ItemGroup>
2.2 服务端配置
在Program.cs中进行基础配置:
csharp复制var builder = WebApplication.CreateBuilder(args);
var services = builder.Services;
services.AddControllers();
// 开发环境添加Swagger支持
if (builder.Environment.IsDevelopment())
{
services.AddOpenApi();
services.AddEndpointsApiExplorer();
services.AddSwaggerGen();
}
// 添加MCP服务配置
services.AddMcpServer().WithHttpTransport(options =>
{
options.Stateless = true; // 使用无状态模式
})
.WithResources<WidgetResource>()
.WithTools<WidgetTool>();
var app = builder.Build();
// 开发环境启用Swagger UI
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseCors(c => c.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());
app.MapControllers();
app.UseMiddleware<AppAuthorizationMiddleware>(); // 添加授权中间件
app.MapMcp("mcp"); // 映射MCP端点
app.Run();
2.3 资源定义
定义MCP资源类,用于提供UI界面:
csharp复制[McpServerResourceType]
public class WidgetResource
{
private readonly IWebHostEnvironment environment;
private readonly IFileInfo file;
public WidgetResource(IWebHostEnvironment environment)
{
this.environment = environment;
this.file = new PhysicalFileProvider(
Path.Combine(environment.ContentRootPath, "wwwroot"))
.GetFileInfo("/index.html");
}
[McpServerResource(
MimeType = "text/html;profile=mcp-app",
Name = "widget-app",
Title = "Widget Application",
UriTemplate = "ui://widget/app.html")]
[McpMeta("openai/widgetPrefersBorder", false)]
[McpMeta("openai/widgetDomain", "example.com")]
public async ValueTask<string> Dashboard()
{
using var stream = file.CreateReadStream();
using var reader = new StreamReader(stream);
return await reader.ReadToEndAsync();
}
}
2.4 工具定义
定义MCP工具类,提供具体功能:
csharp复制[McpServerToolType]
public class WidgetTool
{
[McpServerTool(Name = "get-time"), Description("获取服务器当前时间")]
[McpMeta("openai/outputTemplate", "ui://widget/app.html")]
public static string GetServerTime()
{
return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
}
3. 前端界面开发
3.1 前端项目结构
创建前端项目,使用Vue 3和Tailwind CSS:
code复制/ui
├── package.json
├── vite.config.ts
├── index.html
└── src
├── mcp-app.ts
└── app.vue
3.2 前端配置
package.json配置:
json复制{
"name": "ui",
"version": "1.0.0",
"scripts": {
"dev": "vite",
"build": "vite build"
},
"dependencies": {
"@modelcontextprotocol/ext-apps": "^1.2.2",
"@modelcontextprotocol/sdk": "^1.27.1",
"vue": "^3.5.30"
},
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.5",
"vite": "^8.0.0",
"tailwindcss": "^4.2.1"
}
}
vite.config.ts配置:
typescript复制import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [vue(), tailwindcss()],
build: {
outDir: "../MCPServer/wwwroot",
emptyOutDir: true
}
});
3.3 Vue组件开发
app.vue组件实现:
vue复制<script setup lang="ts">
import { ref, onMounted } from "vue";
import { App } from "@modelcontextprotocol/ext-apps";
const app = ref<App | null>(null);
const serverTime = ref("Loading...");
onMounted(async () => {
const instance = new App({ name: "Time App", version: "1.0.0" });
instance.ontoolresult = (result) => {
serverTime.value = result.content?.find(c => c.type === "text")?.text || "Error";
};
await instance.connect();
app.value = instance;
});
async function handleGetTime() {
if (!app.value) return;
const result = await app.value.callServerTool({
name: "get-time",
arguments: {}
});
serverTime.value = result.content?.find(c => c.type === "text")?.text || "Error";
}
</script>
<template>
<div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md">
<h1 class="text-xl font-semibold mb-4">Time App</h1>
<p class="mb-2">Server Time: {{ serverTime }}</p>
<button
@click="handleGetTime"
class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
>
Refresh Time
</button>
</div>
</template>
4. 授权与安全实现
4.1 OAuth 2.1配置
实现OAuth 2.1端点:
csharp复制[Route("/.well-known")]
[ApiController]
public class WellKnownController : ControllerBase
{
[HttpGet("oauth-authorization-server")]
public object GetOAuthServer()
{
return new
{
issuer = "https://example.com",
authorization_endpoint = "https://example.com/oauth/authorize",
token_endpoint = "https://example.com/oauth/token",
response_types_supported = new[] { "code" },
grant_types_supported = new[] { "authorization_code" },
scopes_supported = new[] { "mcp" }
};
}
}
4.2 授权中间件
实现授权验证中间件:
csharp复制public class AppAuthorizationMiddleware : IMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
if (context.Request.Path.StartsWithSegments("/mcp") &&
!context.Request.Path.StartsWithSegments("/mcp/.well-known"))
{
var authHeader = context.Request.Headers.Authorization.ToString();
if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith("Bearer "))
{
context.Response.Headers.WWWAuthenticate =
"Bearer resource_metadata=http://localhost:5048/mcp/.well-known/oauth-protected-resource";
context.Response.StatusCode = 401;
await context.Response.WriteAsJsonAsync(new {
error = "invalid_token",
error_description = "Authorization required"
});
return;
}
}
await next(context);
}
}
5. 调试与测试
5.1 使用MCP Inspector调试
MCP Inspector是官方提供的调试工具,可以:
- 模拟ChatGPT客户端请求
- 查看请求/响应详情
- 测试工具调用流程
- 验证授权机制
5.2 常见问题排查
-
跨域问题:
- 确保CORS配置正确
- 开发环境可以暂时允许所有来源
-
授权失败:
- 检查WWW-Authenticate头是否正确返回
- 验证Bearer token格式
-
工具调用失败:
- 检查工具名称是否匹配
- 验证参数格式是否符合预期
-
前端连接问题:
- 检查MCP端点URL是否正确
- 验证前端SDK版本兼容性
6. 部署与优化建议
6.1 生产环境部署
- 使用HTTPS保护所有通信
- 实现真正的OAuth 2.1授权服务器
- 添加速率限制防止滥用
- 配置适当的日志记录和监控
6.2 性能优化
- 对于无状态模式,考虑使用缓存
- 优化工具调用响应时间
- 压缩前端资源
- 使用CDN分发静态资源
6.3 扩展功能
- 添加更多工具类型
- 实现流式响应支持
- 集成数据库持久化
- 添加用户个性化功能
通过以上步骤,开发者可以使用C#构建功能完善的MCP/ChatGPT应用程序,实现与AI系统的深度集成。这种架构既保持了灵活性,又能满足企业级应用的安全和性能要求。
