# mcp-server **Repository Path**: a1035244092/mcpser ## Basic Information - **Project Name**: mcp-server - **Description**: erver - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-19 - **Last Updated**: 2026-10-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 当前 Octop 用户名透传 Demo(2026-10-19) 当前链路:Octop 登录账号 → 调用时 `user_name` Header → MCP 请求上下文 → IMS 网关。没有业务 JWT,工具参数不包含用户名。 - 运行、内网部署及两仓库提交说明:见 [用户名透传接入说明](docs/用户名透传接入说明.md)。 - 完整链路启动:`work/gateway-demo-venv/bin/python demo/run_username_demo.py`。 - 演示使用真实 Octop 登录、WebSocket 聊天、队列和工具缓存;模型和 IMS 数据由本地模拟服务提供。 - `username-demo` Profile 只暴露两个 IMS 工具;不开启时保留原来的基础业务分组。 --- # 单个 Spring Boot 服务,多个业务 MCP 连接器 同一个 Java 进程监听 `127.0.0.1:8090`,按业务提供四个独立 MCP 地址。 在 Octop 中分别注册这些地址,就能在对话中按需选择订单、销售、运维、文本工具。 每个入口有独立的 MCP 工具集合和会话管理,不需要部署四个应用。 ## 启动与验证 依赖沿用原项目:Spring Boot 4.1.1、Spring AI 2.0.1、Java 21+。 pom.xml 没有新增依赖,构建可复用工程内 `.m2repo/`。 ```bash ./build.sh --offline ./run.sh # 另一个终端,运行 Java 治理检查和真实 HTTP MCP 回归 python3 tests/run_checks.py ``` | 业务 | Octop 显示名称 | MCP 地址 | 工具 | |---|---|---|---| | 订单 | 订单业务 Demo | http://127.0.0.1:8090/mcp/orders | get_order、list_recent_orders | | 销售 | 销售分析 Demo | http://127.0.0.1:8090/mcp/sales | sales_summary_by_region | | 运维 | 运行维护 Demo | http://127.0.0.1:8090/mcp/operations | ping、jvm_info | | 文本 | 文本处理 Demo | http://127.0.0.1:8090/mcp/text | text_stats | 保留 `/mcp` 总入口兼容原来的 Spring Boot 演示连接器,默认含全部 6 个工具。 受限业务应用只选择对应业务连接器;若同时选择总入口,仍能获得全部工具。 - 健康:`GET /actuator/health` - 总目录:`GET /tool-registry/tools`,`exposed=true` 的集合等于总入口 tools/list。 - 分组目录:`GET /tool-registry/groups`,各组 tools 等于该业务入口 tools/list。 ## 项目结构 ```text src/main/java/com/example/mcpdemo/ ├── McpDemoApplication.java ├── orders/ │ ├── GetOrderTool.java # 一个类一个工具 │ ├── ListRecentOrdersTool.java │ ├── Order.java │ └── OrderService.java # 内存演示数据,替换真实业务接口的位置 ├── sales/ │ ├── SalesSummaryTool.java │ └── SalesService.java # 独立的模拟区域销售汇总 ├── operations/ │ ├── PingTool.java │ └── JvmInfoTool.java ├── text/ │ └── TextStatsTool.java └── registry/ ├── ToolMetadata.java ├── ToolRegistry.java # 元数据、重复检测、全局策略与不可变快照 ├── ToolRegistryConfiguration.java ├── GroupedMcpEndpoints.java # 同一 JVM 的多个业务 MCP 入口 └── ToolCatalogController.java ``` 原 `DemoTools` 已按业务拆开,没有启用或引入 `ImsMcpTools`。 工具名称、参数、返回格式沿用原演示;订单演示服务补充 U200 数据, 按 userId 隔离查询,最近订单按时间倒序返回。 ## 演示数据和提问 全部订单、销售金额都是虚构数据,不连接生产系统。 - U100:A1001(已支付,1288 元)、A1002(待支付,399 元)、A1003(已退款,58 元)。 - U200:B2001(已支付,899 元)、B2002(待发货,269 元)。 - 未知用户返回空列表;不存在的订单返回“未找到”提示。 - 销售:华东 1288、华北 399、华南 58;这些是独立模拟汇总,不从订单明细计算。 - ping、jvm_info 返回本机运行状态;text_stats 对传入的文本执行真实统计。 选择订单连接器后,可提问:“查一下 A1001 的状态,再列出 U200 最近两笔订单。” 选择销售连接器后,可提问:“各区域销售额分别是多少?” 选择运维连接器后,可提问:“检查服务是否在线,并查看 JVM 内存。” 选择文本连接器后,可提问:“统计‘你好 Octop hello’的字符数和字节数。” ## 新增业务工具 在 Spring 扫描范围内新增一个 `@Component`,工具方法标注 `@McpTool`, 元数据标注业务组即可。无需修改集中注册清单,重启后自动生成对应业务地址。 新增 bean 应声明具体的工具类型,以便启动前按类型检查方法注解。 ```java @Component @ToolMetadata(domain = "customer", version = "1.0.0", groups = {"customer"}) public class CustomerInfoTool { @McpTool(name = "customer_info", description = "查询演示客户资料") public Map query( @McpToolParam(description = "客户编号,例如 C100") String customerId) { return Map.of("id", customerId, "name", "演示客户", "demo", true); } } ``` 这会产生 `/mcp/customer`。一个工具也可以属于多个组。 组 ID 必须是小写字母开头、后接小写字母/数字/连字符,长度不超过 64。 不使用分组元数据的工具只进入总入口。 ## Registry 和权限边界 启动时先按 Bean 类型发现全部 `@McpTool` 方法并初始化工具 Bean,避免依赖初始化 顺序导致目录不完整;再使用 Spring AI 原生 `SyncMcpToolProvider` 生成 schema 和调用处理器。 原生未筛选的 specification factory 被排除,防止工具绕过 Registry 重复注册。 - 元数据支持 domain、version、enabled、groups;方法注解整体覆盖类注解。 - 默认值为 general / 1.0.0 / enabled=true / 无分组。 - 重复名称(即使禁用)、未知工具/分组策略、空 domain/version 均拒绝启动。 - 全局策略:disabled 或 enabled=false 优先;group 和 allow 取交集。 - 各业务入口再次从全局允许集合中筛选,不能恢复被全局禁用的工具。 - 总入口与分组入口分别校验实际注册集合,分组会话不可跨地址复用。 - 元数据 version 用于目录治理,不是并行版本路由。 - 所有策略是启动快照;修改后重启,不支持运行时 addTool/removeTool。 ```bash # 所有入口都只能使用这两个工具 TOOL_REGISTRY_ALLOW=get_order,ping ./run.sh # 禁用工具对总入口和全部业务入口都生效 TOOL_REGISTRY_DISABLED=jvm_info ./run.sh ``` 本实现使用 SYNC + STREAMABLE,且只提供工具。扩展 resources/prompts/completions 或改 ASYNC 时需要补充对应的注册支持。 业务路径实现工具集合隔离,并不等于用户身份认证;任何能访问服务地址的客户端都可以选择 任意业务路径。当前只监听本机。远程部署应由可信网关提供 TLS、认证和路径授权, 目录接口也应限制访问。Spring AI starter 默认不提供身份认证。 ## Octop 1.0.1 注册 已核对本地离线包的 METADATA(Version 1.0.1)及源代码: `octop/infra/connectors/custom_mcp.py::normalize_server_spec` 支持 url、headers 等, 不保留自定义连接器的 allowed_tools;experts.py 支持 mcp_servers 按连接器选择。 因此由服务端业务入口提供可靠的工具集合,每个地址在 Octop 注册为一个连接器。 在“连接器 → 自定义连接器”中分别添加四个 HTTP Server,transport 均为 streamable_http。 若使用 JSON 模式,将以下配置合并到已有对象,保留原连接器: ```json { "demo-orders": {"display_name":"订单业务 Demo","url":"http://127.0.0.1:8090/mcp/orders","transport":"streamable_http"}, "demo-sales": {"display_name":"销售分析 Demo","url":"http://127.0.0.1:8090/mcp/sales","transport":"streamable_http"}, "demo-operations": {"display_name":"运行维护 Demo","url":"http://127.0.0.1:8090/mcp/operations","transport":"streamable_http"}, "demo-text": {"display_name":"文本处理 Demo","url":"http://127.0.0.1:8090/mcp/text","transport":"streamable_http"} } ``` ## 测试覆盖 `tests/run_checks.py` 使用本地依赖,无需下载新的测试库: - Java 检查:重复工具、未知策略、类级元数据、注解禁用、只读目录。 - HTTP 检查:真实 initialize、tools/list、tools/call;默认、分组、白名单/禁用、空集合策略。 - 四个业务入口逐一检查目录一致、允许调用成功、所有越组调用拒绝、跨入口会话拒绝。 - 验证原订单金额、U200 数据不混入 U100、销售结构化返回值。 - 使用临时本机端口;完成后停止测试进程,不占用 8090。