Add project-bound OAuth MCP queries and controlled analysis with scoped evidence, limits, timeouts and a nearby-model spatial query using EPSG:4326 inputs. Default nearby searches to 200 meters and five results. Integrate investigation messaging/presentation, health/readiness and typed history; remove duplicate web search and fix online simulation and compressed baseline writes. Include project migrations 023-025; keep local credentials and demo seeding excluded. Validation: 319 focused pytest checks; real PostGIS temporary-table regression; read-only Jinqian bridge radius comparison; cross-language MCP discovery/calls.
89 lines
5.8 KiB
Markdown
89 lines
5.8 KiB
Markdown
# MCP 接入的 Keycloak 管理员配置清单
|
||
|
||
这里创建的是 OAuth 认证配置。OpenCode 到 Agent、Agent 到 Server 的 MCP 协议客户端已实现,无需再开发或安装 MCP 客户端程序。
|
||
|
||
以下使用已创建的请求方客户端 `agent-mcp`,MCP 资源的 audience 使用 `tjwater-mcp`。它们位于现有业务登录使用的同一个 realm。
|
||
|
||
## 1. 请求方客户端 agent-mcp
|
||
|
||
在 Keycloak 的 Clients 中打开 `agent-mcp`:
|
||
|
||
| 设置 | 值 |
|
||
| --- | --- |
|
||
| Client type / Protocol | OpenID Connect |
|
||
| Client authentication | On;这是 confidential 客户端 |
|
||
| Service accounts roles | On;用于启动时读取 MCP 工具目录 |
|
||
| Standard token exchange | On;用于按当前用户或 worker 的身份换取 MCP 令牌 |
|
||
| Standard flow | Off;该客户端不负责浏览器登录 |
|
||
| Direct access grants | Off |
|
||
| Access token lifespan | 建议300秒,不超过900秒 |
|
||
| 签名算法 | RS256 |
|
||
|
||
保存后,在 Credentials 中取得 Client Secret。密钥只写入 Agent 的忽略文件 `.local.env`:
|
||
|
||
```dotenv
|
||
TJWATER_MCP_CLIENT_ID='agent-mcp'
|
||
TJWATER_MCP_CLIENT_SECRET='<Credentials 中的 Client Secret>'
|
||
```
|
||
|
||
不要把密钥放入聊天、前端配置、OpenCode 配置或 Git。Server 只配置 `TJWATER_MCP_HOST_CLIENT_ID='agent-mcp'`,不需要保存这个客户端的密钥。
|
||
|
||
## 2. 资源客户端及 scopes
|
||
|
||
创建或复用表示 MCP 服务的 OIDC 客户端 `tjwater-mcp`;关闭浏览器登录、直接密码登录和服务账户。这个 ID 是目标 audience,不是另一个需要部署的服务。
|
||
|
||
创建以下 OIDC Client scopes,并作为 Optional scopes 分配给 `agent-mcp`;启用 Include in token scope:
|
||
|
||
- `mcp.catalog.read`
|
||
- `mcp.query`
|
||
- `mcp.context.bind`
|
||
|
||
在这些 scopes 中添加 Audience mapper,使对应 token 的 `aud` 包含目标客户端 `tjwater-mcp`。应用按实际 grant 请求 scope:服务账户请求只有 `mcp.catalog.read`;用户/worker 的交换请求才包含查询和上下文 scope。不要给服务账户额外分配项目成员、管理或设备控制权限。
|
||
|
||
## 3. 允许当前业务身份交换
|
||
|
||
在原有前端登录客户端和 worker 客户端的专用 scope 中添加 Audience mapper,使源 token 的 `aud` 包含请求方 `agent-mcp`。保留原业务 API 所需的 audience;不要给源 token 添加 MCP 目标 `tjwater-mcp`。
|
||
|
||
交换后必须保持用户主体 `sub` 不变,`azp=agent-mcp`,目标 `aud` 包含 `tjwater-mcp`。Keycloak 的 `audience` 参数只筛选已有映射的 audience,不能代替 Audience mapper。
|
||
|
||
版本和界面名称以当前 Keycloak 为准。配置依据:[Keycloak Standard Token Exchange](https://www.keycloak.org/securing-apps/token-exchange)。仅在公开发现中看到 token exchange,并不能证明具体客户端已启用或映射正确。
|
||
|
||
## 4. 地址、数据库和启用顺序
|
||
|
||
正式环境提供该 realm 的 HTTPS issuer。本地开发可显式允许一个 RFC1918 IPv4 HTTP issuer:Agent 设置 `NODE_ENV=development`,Server 设置 `ENVIRONMENT=development`,两端 `TJWATER_MCP_DEV_HTTP_ISSUER_URI` 均填写与各自 `TJWATER_MCP_ISSUER_URI` 完全相同的地址(含 realm)。此例外不放行远程 HTTP MCP resource;Agent 只允许该 issuer 同源的远程 HTTP 发现及令牌端点,继续拒绝重定向。正式环境必须清空此项并使用 HTTPS 域名。配置值必须与发现文档和令牌 `iss` 一致,不能仅替换访问地址。
|
||
|
||
例如,同机开发时 Server `.env` 可配置为(内网地址按实际认证服务替换):
|
||
|
||
```dotenv
|
||
ENVIRONMENT=development
|
||
TJWATER_MCP_ENABLED=true
|
||
TJWATER_MCP_ISSUER_URI=http://192.168.1.114:8088/realms/tjwater
|
||
TJWATER_MCP_DEV_HTTP_ISSUER_URI=http://192.168.1.114:8088/realms/tjwater
|
||
TJWATER_MCP_RESOURCE_URI=http://127.0.0.1:8000/mcp
|
||
```
|
||
|
||
Agent `.local.env` 使用相同的三个 URI,并设置 `NODE_ENV=development`、
|
||
`TJWATER_MCP_ENABLED=true`。开发模式不跳过签名、issuer、audience、scope 或项目权限校验,
|
||
也不自动接受另一种 issuer。切换 Server 环境还会开启开发 API 文档页面。
|
||
修改环境文件后需重启相应进程;已有进程不一定自动重读 `.env`,系统环境变量也可能覆盖文件。
|
||
应先确认 Server 的 `/.well-known/oauth-protected-resource/mcp` 公布的新 issuer,
|
||
再启动 Agent 检查工具目录。切回生产时,两端恢复相同 HTTPS issuer 并删除 HTTP 白名单。
|
||
|
||
业务身份也必须使用同一 issuer:供水前端只在被 Git 忽略的
|
||
`.env.development.local` 中将 `TJWATER_KEYCLOAK_ISSUER` 设为该内网地址,
|
||
保留 `.env.local` 的 HTTPS 配置供正常 production 构建使用。
|
||
Server 本机 `.env` 可额外设置 `OPERATIONAL_WORKER_DEV_TOKEN_URL` 为同一内网 issuer
|
||
发现文档中的 `token_endpoint`;该值仅在 `ENVIRONMENT=development` 时生效,
|
||
不替换原来的 `OPERATIONAL_WORKER_TOKEN_URL`。重启开发前端和 worker,并在浏览器重新登录。
|
||
旧 HTTPS 令牌不能用于内网 issuer 的交换;工具目录读取成功不等于业务身份交换成功。
|
||
|
||
接入人员随后执行:
|
||
|
||
1. 安装 MCP SDK 2 对应的 Server 依赖。
|
||
2. 对选定项目业务库备份并应用 [025_mcp_query_contexts.sql](../resources/sql/025_mcp_query_contexts.sql)。
|
||
3. 在 Agent 和 Server 的私有环境中配置相同的 issuer、resource、audience;resource 必须指向实际 Server `/mcp`,请求方客户端 ID 均使用 `agent-mcp`。
|
||
4. 验证带标准 `resource` 的目录 grant 和用户/worker token exchange 都成功;若身份平台拒绝,先解决兼容性,不移除参数重试。
|
||
5. 在受控测试实例中开启两端 `TJWATER_MCP_ENABLED` 并重载;通过测试项目查询、任务证据和越权拒绝验收后,再按部署流程启用正式环境。
|
||
|
||
完整环境变量与验收要求见 [MCP 实施文档](mcp-query-implementation.md)。在以上步骤完成前保持 MCP 开关关闭。
|