Files
smartmate/infra/smartflow-mcp-server
LoveLosita 26c350f378 Version: 0.4.4.dev.260307
feat: 🚀 增强会话管理与缓存机制

* 会话 ID 空值兜底,若 `conversation_id` 为空时自动生成 UUID
* 在响应头写入 `X-Conversation-ID`,供前端使用,保持同一会话状态

perf:  会话状态缓存优化

* 当缓存未命中但 DB 已确认/创建会话后,调用 `SetConversationStatus` 回写 Redis
* 缓存写回失败时记录日志,不中断聊天主流程,确保业务流畅性

fix: 🐛 修复历史消息顺序问题与编译错误

* 修复历史消息顺序问题,保证返回的 N 条历史消息按时间正序喂给模型

  * 通过反转 `created_at desc` 查询结果的切片,确保模型输入顺序正确
* 修复 `fmt.Errorf` 参数不匹配问题,修正编译错误
* 整理 `agent-cache.go` 为标准 UTF-8 编码,避免 Go 编译报错 `invalid UTF-8 encoding`

feat: 🛠️ 独立构建 MCP 服务器

* 使用 `Codex` 构建独立于后端的 MCP 服务器,简化与 Codex 的协作
* 通过该服务器方便 Codex 直接测试和查看 Redis 与 MySQL 中的数据
2026-03-07 15:25:40 +08:00
..
2026-03-07 15:25:40 +08:00
2026-03-07 15:25:40 +08:00
2026-03-07 15:25:40 +08:00
2026-03-07 15:25:40 +08:00
2026-03-07 15:25:40 +08:00
2026-03-07 15:25:40 +08:00
2026-03-07 15:25:40 +08:00
2026-03-07 15:25:40 +08:00

smartflow-mcp-server (MVP)

用于让 Codex 通过 MCPstdio只读访问 MySQL 与 Redis面向接口联调与测试。

1. 功能范围(第一阶段)

只实现 3 个只读工具:

  1. mysql_query_readonly
  2. redis_get
  3. redis_scan

未实现任何写操作工具。

2. 目录结构

infra/smartflow-mcp-server
├─ cmd/server/main.go
├─ internal
│  ├─ audit
│  ├─ config
│  ├─ envutil
│  ├─ mcp
│  ├─ ratelimit
│  ├─ security
│  ├─ store
│  └─ tools
├─ .env.example
├─ go.mod
└─ README.md

3. 快速启动

go mod tidy
go test ./...
go run ./cmd/server

服务采用 stdio MCP 协议,不会启动 HTTP 端口。

4. 配置说明(全部来自环境变量)

复制并编辑:

cp .env.example .env

关键变量:

  • MYSQL_HOST / MYSQL_PORT / MYSQL_USER / MYSQL_PASSWORD / MYSQL_DATABASE
  • REDIS_ADDR / REDIS_PASSWORD / REDIS_DB
  • MYSQL_ALLOWED_DATABASES:逗号分隔
  • MYSQL_ALLOWED_TABLES:逗号分隔,支持 db.tabletable
  • MCP_ENFORCE_WHITELISTtrue 时无明确表引用会拒绝执行
  • MCP_TOOL_TIMEOUT_MS:单次工具调用超时
  • MCP_RATE_LIMIT_RPS + MCP_RATE_LIMIT_BURST:基础令牌桶限流
  • MCP_MAX_RESULT_ROWSMySQL 最大返回行数
  • MCP_REDIS_SCAN_MAX_KEYSredis_scan 最大返回 key 数
  • MCP_AUDIT_LOG_PATH:审计日志路径

5. 工具说明

5.1 mysql_query_readonly

输入:

{
  "sql": "SELECT id, name FROM users WHERE id = ?",
  "params": [1]
}

安全限制:

  • 仅允许 SELECT / SHOW / DESCRIBE / EXPLAIN
  • 禁止分号 ;(多语句)
  • 禁止注释 -- / # / /* */
  • 禁止 DDL/DML 关键字(INSERT/UPDATE/DELETE/ALTER/DROP/TRUNCATE 等)
  • 支持库/表白名单校验

输出(结构化):

  • columns
  • rows
  • rowCount
  • truncated
  • durationMs

5.2 redis_get

输入:

{
  "key": "user:1001"
}

输出:

  • exists
  • key
  • type
  • value
  • truncated
  • durationMs

5.3 redis_scan

输入:

{
  "pattern": "user:*",
  "count": 50
}

输出:

  • pattern
  • keys
  • returned
  • nextCursor
  • truncated
  • durationMs

6. 审计日志

每次工具调用会记录JSON 行格式):

  • 时间
  • 工具名
  • 调用方caller
  • 是否成功
  • 耗时
  • 脱敏后的输入摘要
  • 错误信息(截断)

敏感字段处理:

  • SQL 字符串字面量与数字会脱敏
  • Redis key 仅保留前后少量字符

7. Codex MCP 配置示例stdio

可按客户端配置格式接入,示例:

{
  "mcpServers": {
    "smartflow-db-readonly": {
      "command": "go",
      "args": ["run", "./cmd/server"],
      "cwd": "E:/SmartFlow-Agent/infra/smartflow-mcp-server",
      "env": {
        "MYSQL_HOST": "127.0.0.1",
        "MYSQL_PORT": "3306",
        "MYSQL_USER": "readonly_user",
        "MYSQL_PASSWORD": "replace_me",
        "MYSQL_DATABASE": "smartflow",
        "MYSQL_ALLOWED_DATABASES": "smartflow",
        "MYSQL_ALLOWED_TABLES": "smartflow.users,smartflow.tasks",
        "REDIS_ADDR": "127.0.0.1:6379",
        "REDIS_DB": "0",
        "MCP_TOOL_TIMEOUT_MS": "5000",
        "MCP_RATE_LIMIT_RPS": "5",
        "MCP_RATE_LIMIT_BURST": "10",
        "MCP_MAX_RESULT_ROWS": "500",
        "MCP_REDIS_SCAN_MAX_KEYS": "200",
        "MCP_AUDIT_LOG_PATH": "logs/audit.log"
      }
    }
  }
}

8. 安全限制生效示例

  • SQL 多语句:SELECT 1; SELECT 2 -> 被拒绝semicolon is not allowed
  • SQL 注释绕过:SELECT * FROM users --x -> 被拒绝sql comments are not allowed
  • 写操作:DELETE FROM users -> 被拒绝dangerous sql keyword detected
  • 白名单外表:SELECT * FROM admin.secret -> 被拒绝table not in whitelist
  • Redis 大范围扫描:redis_scan 返回数量受 MCP_REDIS_SCAN_MAX_KEYS 限制

9. 风险说明MVP 已知边界)

  1. SQL 校验采用关键字与模式匹配,不是完整 SQL AST 解析,建议二阶段引入 AST 级校验。
  2. SHOW DATABASES 等无显式表引用语句在非严格模式下可执行;生产建议开启 MCP_ENFORCE_WHITELIST=true
  3. Redis 复杂类型返回做了截断保护,但仍建议在生产环境设置更小上限。

10. 常见问题FAQ

Q1: 启动时报 MYSQL_USER and MYSQL_DATABASE are required

检查环境变量是否正确加载,建议先确认 .env 存在于 infra/smartflow-mcp-server

Q2: 为什么调用工具报限流

默认启用了令牌桶限流,调大 MCP_RATE_LIMIT_RPSMCP_RATE_LIMIT_BURST 即可。

Q3: 为什么 redis_scan 返回不全

是预期行为,结果数被 MCP_REDIS_SCAN_MAX_KEYS 限制,避免全量扫描拖垮 Redis。

Q4: 审计日志在哪里

默认在 logs/audit.log,可用 MCP_AUDIT_LOG_PATH 自定义。