Files
2026-09-06 17:57:58 +08:00

84 lines
6.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 空间只读 MCP v1 架构
## 决策摘要
首版 MCP 内嵌在现有 Go 服务中,使用标准库实现 HTTP/JSON-RPC 协议层,使用 `pgx/v5` 原生连接池访问 PostgreSQL/PostGIS。没有引入 MCP SDK、Web 框架或 ORM。
采用这一边界是因为当前只需要与不能配置协议版本的 SuperAgent 客户端协作:服务端实际提供 `2025-06-18` 版本标识、四个方法和同步 JSON 响应;版本字段和 Header 按已稳定接通的 SuperAgent 兼容档案处理,不作为拒绝门禁。业务复杂度位于固定空间查询、权限范围和安全语义,而不是协议框架。
## SuperAgent 兼容档案
同一 SuperAgent 中已稳定启用的 `th-hotel-simple-superagent` 服务不会读取 `initialize.params.protocolVersion`,也不会读取或校验 `MCP-Protocol-Version` Header;它固定返回 `2025-06-18`,并正常处理 `notifications/initialized`、`tools/list` 与 `tools/call`。本项目对齐这一已验证的接入方式,目标是让 SuperAgent 能调用消防 MCP,而不是追求最新 MCP 版本。
`initialize.params.protocolVersion` 的缺失、空值、非字符串或其他值,不单独触发版本拒绝;可解析的 JSON-RPC initialize 始终返回 `result.protocolVersion: "2025-06-18"`。`MCP-Protocol-Version` Header 同样不作为拒绝门禁,SuperAgent 配置中无需增加版本或 Header 项。服务端并不因此实现或声明支持客户端填写的任意版本,也不把 `2025-03-26`、`2025-11-25` 等版本列为实现目标;固定返回 `2025-06-18` 是兼容响应。
上述兼容仅针对版本元数据。HTTP 方法、JSON-RPC 结构、独立 Bearer、`Content-Type`、非空 `Origin`、工具 schema、只读查询、服务端数据范围和结果脱敏等安全及业务边界仍由 Handler、Service 和 Repository 强制执行。initialize 结果可按实际字段记录 `direct_success`(值为 `2025-06-18`)或 `compatibility_success`(缺失或其他值被兼容处理),不得记录原始版本值。
## 模块关系
```mermaid
flowchart TD
APP["internal/app\n依赖装配与 readiness"]
H["internal/handler\nBearer、JSON-RPC、握手协商、schema、分页边界"]
S["internal/service\n查询边界、超时、分页与结果语义"]
D["internal/domain\n稳定空间领域对象"]
R["internal/repository\npgxpool、固定参数化 PostGIS SQL、过滤后总量"]
DB["8 张既有 PostGIS 表"]
APP --> H
APP --> S
APP --> R
H --> S
S --> D
S --> R
R --> D
R --> DB
```
Handler 不知道物理表名,Repository 不组织自然语言回答,Domain 不依赖 MCP 或 pgx。可信数据范围在应用装配时由配置传入 Service,并由 Repository 在 SQL 中应用:默认 `town_allowlist` 使用参数化镇街数组过滤;显式 `all` 使用服务端布尔参数放开镇街过滤。范围选择不进入工具 schema,模型无法扩大权限。
七个工具共用无状态 `limit/offset` 分页。Handler 限制 `limit=1..20`、`offset=0..10000`;Service 应用各工具默认页大小并生成 `result_count`、`total_count`、`has_more` 和 `next_offset`;Repository 在授权范围、空间条件、有效几何和业务过滤完成后使用窗口统计总量,再以稳定排序执行参数化 `LIMIT/OFFSET`。请求超过末页且匹配总量大于零时,Repository 以同一只读查询条件探测第一页以恢复准确总量,响应保持 `status=ok` 和空 `data`,避免把“页码越界”误报为“没有记录”。
## 数据映射
| 领域结果 | 物理表 |
| --- | --- |
| 地名候选 | 以下 8 张表的名称、镇街、村庄和几何字段 |
| 网格上下文、责任中队 | `st_2_fanghuowangge` |
| 水源候选 | `st_2_mpslfh_t_slfh_syd`、`st_2_xianyouxushuichiguan` |
| 指挥部候选设施 | `st_2_fanghuojianchazhan`、`st_2_fanghuoliaowangshao` |
| 通道候选 | `st_2_xianyoufanghuotongdao` |
| 风险区域 | `st_2_mudifenqu_mian`、`st_2_linqugongkuangqiye` |
姓名、联系电话和值班人员字段不进入领域结果,也没有出现在查询 SELECT 列表中。
## 空间约束
- MCP 入参固定为 WGS84 经纬度。
- 地名搜索是坐标查询前的候选发现:记录点直接返回二维坐标;线使用首个组成线的起点,面使用 `ST_PointOnSurface` 产生代表点,并以 `location_kind` 明确区分。代表点不得自动升级为用户确认的演练点。
- 防火通道原始 `geom` 已确认混合二维与 Z 维度,导入层必须使用不限定 typmod 的 `geometry` 保存原始事实。距离/最近点等 MCP v1 运算按二维地表语义解释;若底层函数需要降维,只能在只读查询或派生层显式处理,不得回写或静默修改原始几何。
- 启用前要求实库所有非空几何 SRID 为 4326、类型符合表用途且坐标位于 WGS84 合法范围;这些属于硬门禁。
- 点到点、点到线、点到面距离使用 PostGIS `geography` 米制计算。
- 面覆盖使用 `ST_Covers`,边界上的点也视为位于网格/风险区内。
- SQL 同时检查 SRID、类型和有效性。无效或空几何不自动修复、不改写原始事实,而是从全部 MCP 查询中排除;readiness 和工具结果明确告警结果可能不完整。readiness 发现异常类型、非 4326 SRID 或越界坐标时仍拒绝启用。
- 2026-09-05 实库 audit 发现防火网格 4 条、林区工矿企业 4 条、墓地坟区 27 条无效面几何。用户选择首版排除这 35 条记录,后续如需修复必须在派生副本中审查,不覆盖原始 `geom`。
- 距离结果只是地理邻近,不包含地形、路网、火势、天气和实时通行信息。
## 依赖决策
`github.com/jackc/pgx/v5 v5.10.0` 是当前唯一新增的直接依赖。项目只面向 PostgreSQL,并需要明确的连接池、context 和 PostgreSQL 参数行为,因此使用原生 `pgxpool`;空间计算仍全部由参数化 SQL/PostGIS 完成。
## 后续演进边界
- 动态用户/组织授权到位后,用可信身份解析器替换当前每 Token 的静态数据库全范围/镇街白名单,工具 schema 不增加可伪造的授权字段。
- 路线规划必须新增专门的图网络/地形数据和高风险 Spec,不能扩写当前通道候选工具的描述来冒充路线能力。
- 联系人字段如确需开放,必须有字段级权限、脱敏、审计和单独工具,不直接扩展当前结果。
- 写入、派遣或状态变更工具需要人工确认、幂等、审计和独立安全评审。
## 协议与依赖依据
- [MCP 2025-06-18 Lifecycle](https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle)
- [MCP 2025-06-18 Streamable HTTP Transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports)
- [MCP 2025-06-18 Tools](https://modelcontextprotocol.io/specification/2025-06-18/server/tools)
- [pgx 官方仓库与版本策略](https://github.com/jackc/pgx)