Files
xiaoqu_mcp_service/xiaoqu-agent-service/README.md
T

5.1 KiB
Raw Blame History

xiaoqu-agent-service

面向 MCP 客户端(Kimi Code / Claude 等)的小趣业务数据服务:独立 Spring Boot 应用,只读查询现有三库(m0 权限库 / m1 商城库 / m2 业务库),以 MCP(Streamable HTTP)形式对外暴露工具。

设计方案见 ../xiaoqu-franchisee/doc/agent-mcp-service-design.md。当前为 P1 骨架:工程初始化、版本组合验证、三数据源连通、codegen 跑通、demo 工具经 MCP 调通。鉴权 / 权限引擎 / 管理后台为 P2+,未实现。

技术栈与已验证版本组合

组件 版本
JDK 17(Temurin 17.0.20.1)
Spring Boot 3.5.16
Spring AI(MCP server webmvc) 1.1.8
MyBatis-Plus 3.5.12(mybatis-plus-spring-boot3-starter)
MySQL 驱动 mysql-connector-j(Boot 管理)
Redis spring-boot-starter-data-redis(db5)

⚠️ 版本组合说明:Spring Boot 3.5.x + Spring AI 1.0.0 的 streamable 传输存在 NPE(spring-projects/spring-ai#6274),本工程选用已修复的 Spring AI 1.1.8,2026-09-03 实测 STREAMABLE 握手(initialize → tools/list → tools/call)通过。

工程结构

xiaoqu-agent-service/
├── mvnw / .mvn/wrapper/              # Maven Wrapper(本机无全局 mvn)
├── pom.xml
├── src/main/java/me/iiv/agent/
│   ├── AgentServiceApplication.java
│   ├── config/                       # M0/M1/M2DataSourceConfig(独立 SqlSessionFactory + MapperScan)、McpToolConfig
│   ├── mcp/tool/                     # @Tool 工具(SysTools: sys.ping;AgentTools: agent.count)
│   ├── security/  permission/  admin/  common/   # P2+ 占位包
│   ├── entity/m0、m2  mapper/m0、m1、m2           # codegen 生成物(提交进仓库)
├── src/main/resources/
│   ├── application.yml               # MCP server: protocol=STREAMABLE, 端点 /mcp;默认 dev profile
│   └── application-dev.yml           # 三数据源 + Redis,密码用环境变量占位符带默认值
└── src/test/java/me/iiv/agent/codegen/CodeGenerator.java   # run-once 代码生成器

数据源分包约定:entity/m0|m1|m2 与 mapper/m0|m1|m2 一一对应各自的 SqlSessionFactory(@MapperScan + sqlSessionFactoryRef)。

启动

./mvnw clean package -DskipTests
java -jar target/xiaoqu-agent-service.jar
# 或
./mvnw spring-boot:run
  • 默认 spring.profiles.active=dev,端口 8088,MCP 端点 http://localhost:8088/mcp。
  • 数据库/Redis 密码默认值仅供本地 dev,可用环境变量覆盖:M0_DB_PASSWORD / M1_DB_PASSWORD / M2_DB_PASSWORD / REDIS_PASSWORD。

MCP 工具

工具名 说明
sys.ping 服务自检:服务名、版本、当前时间、Redis PING
agent.count 查 m0 库 agent 表 soft_delete=0 总数(真实查库)

工具名使用点号分隔(MCP 规范允许 [a-zA-Z0-9._-],实测 Spring AI 1.1.8 与握手流程均正常)。若未来接入的客户端不接受点号,改为下划线即可。

curl 验证(Streamable HTTP 握手)

# 1) initialize(从响应头取 Mcp-Session-Id)
curl -i -X POST http://localhost:8088/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'

# 2) notifications/initialized(带 session id)
curl -X POST http://localhost:8088/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'Mcp-Session-Id: <上一步的session-id>' \
  -d '{"jsonrpc":"2.0","method":"notifications/initialized"}'

# 3) tools/list
curl -X POST http://localhost:8088/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'Mcp-Session-Id: <session-id>' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

# 4) tools/call
curl -X POST http://localhost:8088/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'Mcp-Session-Id: <session-id>' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"agent.count","arguments":{}}}'

响应为 SSE 帧(event: message / data: {...})。

codegen(run-once)

表白名单:m0 user, agent, authority, properyt, agent_manage_district_auth;m2 warehouse_agent_auth(注:物业表真实表名为老系统遗留拼写 properyt)。生成物落在 src/main/java 对应分包并提交进仓库。

# 生成(依赖已下载后执行;连 dev 库)
./mvnw -q dependency:build-classpath -Dmdep.includeScope=test -Dmdep.outputFile=target/cp.txt
javac -cp "$(cat target/cp.txt)" -d target/codegen-classes src/test/java/me/iiv/agent/codegen/CodeGenerator.java
java -cp "target/codegen-classes:$(cat target/cp.txt)" me.iiv.agent.codegen.CodeGenerator

重新生成前请先删除目标 entity/mapper 文件,避免覆盖人工改动。