DESIGN.md 17 KB

FranklinWH MCP Server 设计文档

1. 概述

FranklinWH MCP Server (fwh-tools) 是基于 Model Context Protocol 实现的内部工具服务器,为 AI Agent(Kiro CLI)提供对 FranklinWH 内部工具平台数据和服务的结构化访问能力。

项目 说明
服务名 fwh-tools
版本 2.0.0
语言 Go
SDK github.com/mark3labs/mcp-go
传输协议 stdio (JSON-RPC 2.0 over stdin/stdout)
构建产物 单二进制 fwh-mcp-server
调用方 Kiro CLI(通过 ACP 协议启动子进程)

2. 架构设计

2.1 整体架构

┌─────────────────────────────────────────────────────┐
│                   Kiro CLI (AI Agent)                 │
│              通过 ACP 协议管理 MCP Server              │
└────────────────────────┬────────────────────────────┘
                         │ stdio (JSON-RPC 2.0)
                         ▼
┌─────────────────────────────────────────────────────┐
│              fwh-mcp-server (本进程)                  │
│                                                      │
│  ┌────────────────────────────────────────────────┐  │
│  │              MCP Protocol Layer                 │  │
│  │         (mcp-go SDK: 请求路由、序列化)          │  │
│  └─────────────────────┬──────────────────────────┘  │
│                        │                             │
│  ┌─────────┬───────────┼───────────┬─────────────┐  │
│  │service/ │  data/    │  storage/ │    util/     │  │
│  │业务逻辑 │ 数据直查   │ 对象存储  │   辅助工具   │  │
│  └────┬────┴─────┬─────┴─────┬─────┴──────┬──────┘  │
│       │          │           │            │          │
└───────┼──────────┼───────────┼────────────┼──────────┘
        │          │           │            │
        ▼          ▼           ▼            │ (纯函数)
┌──────────┐ ┌──────────┐ ┌──────────┐     │
│ services/│ │ MongoDB  │ │  MinIO   │     │
│层(复用后 │ │ Redis    │ │          │     │
│端业务代 │ │          │ │          │     │
│码)       │ │          │ │          │     │
└──────────┘ └──────────┘ └──────────┘

2.2 与现有后端的关系

MCP Server 是现有后端 Service 层的另一个入口,不是独立系统:

对比项 HTTP Server (main.go) MCP Server (cmd/mcp/main.go)
入口 Fiber HTTP 路由 stdio JSON-RPC
调用方 前端浏览器 Kiro CLI (AI Agent)
认证 Casdoor JWT 无需(本地 stdio 进程)
复用层 controllers → services → repositories 直接调用 services/repositories
输出格式 JSON HTTP Response MCP Tool Result (text/JSON)

2.3 代码目录结构

service/cmd/mcp/
├── main.go                      # 入口:初始化基础设施 + 创建 MCP Server + 注册工具
├── tools/
│   ├── register.go              # RegisterAll:唯一对外注册入口
│   ├── helper/
│   │   └── helper.go            # 统一响应工具函数
│   ├── service/                 # 业务逻辑层工具
│   │   ├── register.go          # RegisterServiceTools
│   │   ├── site.go              # 站点相关工具
│   │   ├── sim.go               # SIM 卡相关工具
│   │   ├── monitor.go           # 监控统计工具
│   │   └── feedback.go          # 反馈协作工具
│   ├── data/                    # 数据直查层工具
│   │   ├── register.go          # RegisterDataTools
│   │   ├── mongo.go             # MongoDB 直查
│   │   └── redis.go             # Redis 缓存读取
│   ├── storage/                 # 对象存储层工具
│   │   ├── register.go          # RegisterStorageTools
│   │   ├── file.go              # 用户上传文件读取
│   │   └── minio.go             # MinIO 对象浏览/读取
│   └── util/                    # 辅助工具层
│       ├── register.go          # RegisterUtilTools
│       └── format.go            # SN 解析等纯函数

3. 工具分层架构

采用四层分类设计,按访问层级递进:

┌───────────────────────────────────────────────────┐
│  Layer 1: service_*  — 业务逻辑层(优先使用)        │
│  调用后端 Service 层函数,包含业务校验和数据聚合      │
├───────────────────────────────────────────────────┤
│  Layer 2: data_*     — 数据直查层(灵活查询)        │
│  直接读取 DB/Cache,跳过业务逻辑,仅限只读           │
├───────────────────────────────────────────────────┤
│  Layer 3: storage_*  — 对象存储层(文件操作)        │
│  file_* 支持读写,minio_* 仅只读浏览和读取           │
├───────────────────────────────────────────────────┤
│  Layer 4: util_*     — 辅助工具层(纯函数)          │
│  格式解析等不涉及数据持久化的工具                     │
└───────────────────────────────────────────────────┘

命名规范: {layer}_{domain}_{action}

示例:service_site_query_info、data_mongo_find、storage_minio_list_objects、util_parse_sn


4. 工具清单

4.1 Service 层(业务逻辑)

工具名 说明 参数
service_site_query_info 查询站点设备详情 sn (必填)
service_site_search 搜索站点列表 page, size, keyword
service_site_power_flow 查询功率流数据 sn (必填), date (必填, yyyy-MM-dd)
service_sim_query 查询 SIM 卡详情 giccid (必填)
service_sim_search 搜索 SIM 卡列表 page, size, search, status, platform
service_monitor_alarm_stats 查询告警统计 date
service_monitor_shutdown_stats 查询停机统计 date
service_feedback_create 创建 Plane Intake Issue title (必填), type (必填), priority, description, category
service_feedback_history 查询反馈历史 (无参数)

4.2 Data 层(数据直查)

工具名 说明 参数
data_mongo_find MongoDB 集合查询 collection (必填), filter, limit, skip, sort
data_mongo_count MongoDB 文档计数 collection (必填), filter
data_redis_get 读取 Redis key key (必填), type
data_redis_exists 检查 key 存在性及 TTL key (必填)

4.3 Storage 层(对象存储)

工具名 说明 参数 读写
storage_file_read 读取用户上传文件 path (必填) 读
storage_file_write 写入文件到存储 path (必填), content (必填) 写
storage_file_list 列出用户上传文件 (无参数) 读
storage_minio_list_objects 列出 MinIO 对象 bucket (必填), prefix, limit 读
storage_minio_read_object 读取 MinIO 文本文件 bucket (必填), key (必填) 读

4.4 Util 层(辅助工具)

工具名 说明 参数
util_parse_sn 解析设备 SN 序列号含义 sn (必填)

5. 安全设计

5.1 访问控制

机制 说明
传输层 stdio 本地进程通信,无网络暴露
认证 无需(由 ACP 管理器控制进程生命周期)
Collection 白名单 MongoDB 查询限制在指定集合内
Bucket 白名单 MinIO 访问限制在指定 bucket 内
只读限制 data* 和 storage* 层所有操作均为只读
文件大小限制 MinIO 读取限制 1MB,用户上传限制 2MB
查询结果限制 MongoDB 单次最多返回 100 条
Redis 安全 不支持通配符 key,防止 KEYS * 类操作

5.2 白名单配置

MongoDB Collections:

var mongoAllowedCollections = []string{
    "site_info",
    "sim_card_manage",
    "batch_download",
    "site_analysis",
    "shutdown_statistics",
    "alarm_statistics",
    "sites_monitor_config",
    "user_config",
}

MinIO Buckets:

var minioAllowedBuckets = []string{
    "fwh-toolbox-batch-download",
    "fwh-toolbox-ai-file",
}

5.3 写操作控制

层级 写操作 说明
service service_feedback_create 创建 Plane Intake Issue
data 无 全部只读
storage storage_file_write 写入文件到 MCP FileStore(MinIO),最大 2MB
storage storage_minio_* 仅只读(列出、读取),不支持写入
util 无 纯函数

6. 文件存储设计

6.1 FileStore 架构

MinIO Bucket: fwh-toolbox-ai-file
├── acp/                          ← ACP (AI Chat) 产生的文件
│   └── {userId}/{sessionId}/{uuid}_{fileName}
│
└── mcp/                          ← MCP (用户上传) 的文件
    └── {userId}/{sessionId}/{uuid}_{fileName}

6.2 文件生命周期

阶段 操作 说明
上传 POST /ai/files/upload 前端上传 → 后端存入 MinIO(prefix=acp)
读取 Agent readTextFile 或 storage_file_read AI 请求读取 → FileStore 从 MinIO 获取
过期 自动清理 文件设置 7 天过期

6.3 共享模块

通用 FileStore 位于 service/utils/filestore/filestore.go,ACP 和 MCP 通过不同 prefix 实例化:

// ACP 使用
acpFS := filestore.NewFileStore("acp")

// MCP 使用
mcpFS := filestore.NewFileStore("mcp")

7. 响应格式

7.1 统一响应工具 (helper/helper.go)

函数 用途 返回类型
JSONResult(data) 序列化为格式化 JSON CallToolResult (text)
TextResult(text) 直接返回文本 CallToolResult (text)
ParamError(name) 参数缺失错误 CallToolResult (error)
ParamInvalidError(name, detail) 参数格式错误 CallToolResult (error)
ServiceError(action, err) 业务调用失败 CallToolResult (error)
EmptyResult(msg) 空结果提示 CallToolResult (text)

7.2 错误响应格式

参数 {name} 必填
参数 {name} 格式错误: {detail}
{action}失败: {error}

8. 初始化流程

func main() {
    // 1. 加载配置(与 HTTP Server 共享)
    cfg := config.LoadConfig()

    // 2. 初始化基础设施
    logger.Init(cfg.App.AppEnv)
    database.Init(&cfg.App)          // MongoDB
    cache.Init(cfg.App.RedisAddr)    // Redis
    repositories.PlaneWebHttpInit()  // Plane API

    // 3. 初始化 MCP FileStore (prefix="mcp")
    mcpFS := filestore.NewFileStore("mcp")
    storage.InitFileStore(mcpFS)

    // 4. 创建 MCP Server
    s := server.NewMCPServer("fwh-tools", "2.0.0",
        server.WithToolCapabilities(false),
        server.WithRecovery(),
        server.WithInstructions(serverInstructions),
    )

    // 5. 注册所有 Tools(单一入口)
    tools.RegisterAll(s)

    // 6. 启动 stdio 通信
    server.ServeStdio(s)
}

9. 部署配置

9.1 构建

cd service
go build -o fwh-mcp-server ./cmd/mcp

9.2 Kiro MCP 配置

文件:service/.kiro/settings/mcp.json

{
  "mcpServers": {
    "fwh-tools": {
      "command": "./fwh-mcp-server",
      "args": [],
      "env": {
        "MONGO_DSN": "${MONGO_DSN}",
        "REDIS_ADDR": "${REDIS_ADDR}",
        "MINIO_ENDPOINT": "${MINIO_ENDPOINT}",
        "MINIO_ACCESS_KEY": "${MINIO_ACCESS_KEY}",
        "MINIO_SECRET_KEY": "${MINIO_SECRET_KEY}",
        "PLANE_WEB_HOST": "${PLANE_WEB_HOST}",
        "PLANE_WEB_EMAIL": "${PLANE_WEB_EMAIL}",
        "PLANE_WEB_PASSWORD": "${PLANE_WEB_PASSWORD}",
        "PLANE_WEB_WORKSPACE_SLUG": "${PLANE_WEB_WORKSPACE_SLUG}",
        "PLANE_WEB_PROJECT_ID": "${PLANE_WEB_PROJECT_ID}"
      }
    }
  }
}

9.3 部署目录

/var/www/fwh-toolbox/server/
├── fwh-toolbox-server         # HTTP Server
├── fwh-mcp-server             # MCP Server
├── .kiro/
│   ├── settings/mcp.json      # MCP 配置
│   ├── agents/                # Agent 配置
│   └── steering/              # Steering 文件
└── .env                       # 环境变量

10. Instructions 系统提示

MCP Server 通过 server.WithInstructions() 向 AI Agent 提供使用指南:

FranklinWH 工具箱 MCP Server — 内部工具平台的 AI 接口层。

使用原则:
1. 优先使用 service_* 工具,它们包含完整的业务逻辑
2. 仅当 service 层无法满足时才使用 data_* 直查
3. 所有 data_* 和 storage_* 工具仅支持只读操作
4. 查询 MongoDB 时注意 collection 白名单限制

11. 扩展指南

11.1 添加新的 Service 层工具

  1. 在 tools/service/ 下创建新文件(如 newdomain.go)
  2. 实现 registerXxxTools(s *server.MCPServer) 函数
  3. 在 tools/service/register.go 的 RegisterServiceTools 中调用
  4. 工具命名遵循 service_{domain}_{action} 格式

    // tools/service/newdomain.go
    package service
    
    func registerNewDomainTools(s *server.MCPServer) {
    s.AddTool(
        mcp.NewTool("service_newdomain_query",
            mcp.WithDescription("..."),
            mcp.WithString("id", mcp.Required(), mcp.Description("...")),
        ),
        handleNewDomainQuery,
    )
    }
    
    func handleNewDomainQuery(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
    id, err := req.RequireString("id")
    if err != nil {
        return helper.ParamError("id"), nil
    }
    data, err := services.GetSomething(id)
    if err != nil {
        return helper.ServiceError("查询", err), nil
    }
    return helper.JSONResult(data), nil
    }
    

11.2 添加新的 MongoDB Collection 访问

在 tools/data/mongo.go 的 mongoAllowedCollections 白名单中添加新集合名:

var mongoAllowedCollections = []string{
    // ... 现有集合
    "new_collection_name",  // ← 添加这一行
}

11.3 添加新的 MinIO Bucket 访问

在 tools/storage/minio.go 的 minioAllowedBuckets 白名单中添加:

var minioAllowedBuckets = []string{
    // ... 现有 bucket
    "new-bucket-name",  // ← 添加这一行
}

12. 测试

12.1 本地测试

# 构建
cd service && go build -o fwh-mcp-server ./cmd/mcp

# 测试 tools/list
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | ./fwh-mcp-server

# 测试单个工具调用
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"util_parse_sn","arguments":{"sn":"10060006A03X25310091"}}}' | ./fwh-mcp-server

12.2 通过 Kiro CLI 测试

# 在 service/ 目录下(含 .kiro/ 配置)
kiro-cli chat

# 对话中使用工具
> 帮我查一下 SN 为 10060006A03X25310091 的站点信息
> 统计一下 site_info 集合中有多少条记录
> 解析一下这个 SN: 10050004B02X24450023

13. 依赖关系

依赖 版本 用途
github.com/mark3labs/mcp-go latest MCP 协议 SDK
go.mongodb.org/mongo-driver - MongoDB 驱动
github.com/minio/minio-go/v7 - MinIO 客户端
github.com/google/uuid - UUID 生成
go.uber.org/zap - 日志

共享后端模块:

  • fwh-toolbox-server/services — 业务逻辑层
  • fwh-toolbox-server/database — 数据库连接
  • fwh-toolbox-server/cache — Redis 缓存
  • fwh-toolbox-server/repositories — 数据访问层
  • fwh-toolbox-server/utils/filestore — 文件存储
  • fwh-toolbox-server/utils/minio — MinIO 客户端
  • fwh-toolbox-server/config — 配置加载
  • fwh-toolbox-server/dto — 数据传输对象

14. 变更历史

版本 日期 变更内容
1.0.0 2026-08-03 初版:6 个 service 层工具(site/sim/alarm/shutdown/plane)
2.0.0 2026-08-06 重构为四层架构,新增 data/storage/util 层,命名规范化