MCP 开发实践
本教程将指导你在 Feat Cloud 中集成 MCP (Model Context Protocol),为 AI 系统提供工具和上下文信息。
- 使用默认 MCP 服务器快速上手
- 创建自定义 MCP 服务端点
- 配置 Tools、Prompts 和 Resources
- 理解 MCP 注解的使用方法
MCP 简介
Section titled “MCP 简介”Model Context Protocol (MCP) 是一种开放协议,允许 AI 系统与应用程序安全地交换信息和工具。Feat Cloud 提供完整的 MCP 支持:
- Tools: 允许 AI 助手调用应用程序中的功能
- Prompts: 提供预定义的提示词模板
- Resources: 共享文本或二进制资源
方式一:默认 MCP 服务器(推荐)
Section titled “方式一:默认 MCP 服务器(推荐)”当 Controller 类中出现 @Tool、@Prompt 或 @Resource 注解时,Feat Cloud 会在编译期自动生成默认 MCP 服务器实例,无需额外配置。
快速上手示例
Section titled “快速上手示例”@Controllerpublic class DefaultMcpUsageController {
@Autowired private McpServer mcpServer;
@PostConstruct public void init() { // 添加工具到默认 MCP 服务器 mcpServer.addTool(ServerTool.of("currentTime") .description("获取当前时间") .inputSchema(ServerTool.boolProperty("withMilliseconds", "是否包含毫秒")) .doAction(ctx -> { boolean withMs = ctx.getArguments().getBooleanValue("withMilliseconds"); long time = withMs ? System.currentTimeMillis() : System.currentTimeMillis() / 1000; return ToolResult.ofText(String.valueOf(time)); }));
// 添加提示词到默认 MCP 服务器 mcpServer.addPrompt(ServerPrompt.of("greeting") .description("问候语提示词") .arguments(tech.smartboot.feat.ai.mcp.model.Prompt.argument("name", "用户姓名")) .doAction(ctx -> { String name = ctx.getArguments().getString("name"); return PromptMessage.ofText(RoleEnum.Assistant, "你好," + name + "!有什么我可以帮助你的吗?"); })); }
@Tool(description = "简单的问候工具") public String greeting(@Param(required = true, description = "用户姓名") String name) { return "你好," + name + "!"; }}方式二:自定义 MCP 服务端点
Section titled “方式二:自定义 MCP 服务端点”对于更复杂的 MCP 服务需求,使用 @McpEndpoint 注解创建自定义 MCP 服务端点。
@Controller@McpEndpoint( name = "demo-mcp-service", title = "Demo MCP Service", sseEndpoint = "/mcp/sse", sseMessageEndpoint = "/mcp/sse/message", streamableEndpoint = "/mcp/stream")public class McpDemoController {
/** * 定义工具:获取用户信息 */ @Tool(name = "getUserInfo", description = "根据用户ID获取用户信息") public UserInfo getUserInfo( @Param(required = true, description = "用户ID") Long userId ) { UserInfo user = new UserInfo(); user.setId(userId); user.setName("User " + userId); user.setEmail(userId + "@example.com"); return user; }
/** * 定义文本提示词 */ @Prompt( name = "codeReviewPrompt", description = "代码审查提示词", type = PromptType.TEXT ) public String codeReviewPrompt( @Param(required = true, description = "代码片段") String codeSnippet ) { return "请审查以下代码并提供改进建议:" + codeSnippet; }
/** * 定义文本资源 */ @Resource( uri = "/resources/coding-standards.md", name = "编码规范", description = "团队编码规范文档", mimeType = "text/markdown", isText = true ) public String codingStandards() { return """ # 编码规范
## 命名规范 1. 类名使用大驼峰命名法 2. 方法名使用小驼峰命名法
## 代码格式 1. 缩进使用4个空格 2. 行宽不超过120个字符 """; }}public class UserInfo { private Long id; private String name; private String email;
// Getters and setters public Long getId() { return id; } public void setId(Long id) { this.id = id; }
public String getName() { return name; } public void setName(String name) { this.name = name; }
public String getEmail() { return email; } public void setEmail(String email) { this.email = email; }}@McpEndpoint
Section titled “@McpEndpoint”标记 Controller 类为 MCP 服务端点。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
name | String | "feat-mcp-server" | MCP 服务名称 |
title | String | "Feat MCP Server" | MCP 服务标题 |
version | String | Feat.VERSION | MCP 服务版本 |
sseEndpoint | String | 必填 | SSE 端点地址 |
sseMessageEndpoint | String | 必填 | SSE 消息端点地址 |
streamableEndpoint | String | 必填 | 流式传输端点地址 |
resourceEnable | boolean | true | 是否启用资源功能 |
toolEnable | boolean | true | 是否启用工具功能 |
promptsEnable | boolean | true | 是否启用提示词功能 |
loggingEnable | boolean | true | 是否启用日志功能 |
标记方法为 MCP 工具。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
name | String | 方法名 | 工具名称 |
description | String | "" | 工具描述 |
支持的返回类型:
- 基本类型:
String,int,long,float,double,boolean,byte - 复合类型:自定义对象(自动序列化为 JSON)
- 专用类型:
ToolResult.TextContent,ToolResult.ImageContent
// 返回文本@Tool(description = "获取文本信息")public ToolResult.TextContent getTextInfo() { return ToolResult.ofText("这是文本内容");}
// 返回图片@Tool(description = "获取图片信息")public ToolResult.ImageContent getImageInfo() { return ToolResult.ofImage("base64-encoded-image-data", "image/png");}@Param
Section titled “@Param”定义 MCP 工具的参数信息。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
required | boolean | 必填 | 参数是否必需 |
description | String | "" | 参数描述 |
@Prompt
Section titled “@Prompt”定义 MCP 提示词资源。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
name | String | 必填 | 提示词名称 |
description | String | "" | 提示词描述 |
type | PromptType | 必填 | 提示词类型 |
role | RoleEnum | RoleEnum.User | 提示词角色 |
mimeType | String | "" | MIME 类型 |
支持的提示词类型:
TEXT: 纯文本提示词IMAGE: 图片提示词AUDIO: 音频提示词EMBEDDED_RESOURCE: 嵌入式资源提示词
// 文本提示词@Prompt(name = "textPrompt", type = PromptType.TEXT)public String textPrompt() { return "这是一个文本提示词";}
// 图片提示词@Prompt(name = "imagePrompt", type = PromptType.IMAGE, mineType = "image/png")public String imagePrompt() { return "base64-encoded-image-data";}@Resource
Section titled “@Resource”定义 MCP 资源。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
uri | String | 必填 | 资源 URI |
name | String | 必填 | 资源名称 |
description | String | "" | 资源描述 |
isText | boolean | true | 是否为文本资源 |
mimeType | String | "" | MIME 类型 |
| 场景 | 推荐方案 |
|---|---|
| 快速集成、简单工具 | 默认 MCP 服务器 |
| 多服务管理、精细控制 | 自定义 MCP 服务端点 |
| 需要自定义端点路径 | 自定义 MCP 服务端点 |
通过 Feat Cloud 的 MCP 支持,你可以轻松为 AI 助手提供上下文信息和工具能力。