外接 MCP OAuth 验收
本指南用于检查源码或安装入口,并在真实操作系统、浏览器和外接服务上验证 OAuth。 命令与支持范围以 CLI 使用说明 为准;模拟服务测试、 运行入口检查和真实账号验收分别记录,未实际执行的项目保持“待验收”。
源码入口与凭据库
激活仓库虚拟环境,使用 python mind.py 运行。先执行 python -m pip check 确认依赖
完整,再执行 python mind.py --version 和 python mind.py mcp login --help 确认入口。
以下真实服务步骤中的 mind,源码运行时统一替换为 Python 和 mind.py 的绝对路径;
无需先编译或安装 npm 包。
源码运行需要 keyring 及当前平台的系统 adapter。Windows 使用 pywin32-ctypes,
macOS 使用 Keychain API,Linux 源码运行使用 SecretStorage 和 jeepney;依赖由
固定版本的 keyring 按平台声明。升级这些依赖后重新验证实际读写,不能只检查 import。
仓库提供隔离检查:它从非源码目录启动指定入口,检查 help、参数错误、服务注册、真实 系统凭据库的大记录恢复、绝对过期时间和幂等 logout。所有凭据均为本次创建的合成数据, 执行后删除;不登录真实账户,不修改默认配置。报告只包含时间、平台、版本、状态和结果。
python -m tests.manual.mcp_oauth_entry --report "<STATE_ROOT>/reports/mcp-oauth-source.json" --command "<ABSOLUTE_PYTHON>" "<REPO_ROOT>/mind.py"
每次报告使用新文件名,不覆盖旧证据。报告显式记录 entry_kind=source,SDK 和 keyring
版本来自运行脚本的虚拟环境。未来验证安装产物时,可选 --entry-kind installed 并将
--command 改为实际可执行文件或 npm launcher;脚本环境需与构建依赖一致。源码通过
不表示安装产物通过,当前 npm 平台包覆盖 Windows、macOS,Linux 不在 npm 发行范围内。
真实服务准备
为验收终端设置独立的 MIND_HOME 和 MIND_STATE_HOME,并在所有参与进程中保持一致。
运行状态根下的 reports/ 是证据目录;未设置状态根时使用配置根。不要覆盖日常配置或
复用已有注册名。连接模型所需的设置仍通过正常配置方式准备,不将密钥放入验收记录。
Windows PowerShell 示例:
$env:MIND_HOME = "<ACCEPTANCE_ROOT>/config"
$env:MIND_STATE_HOME = "<ACCEPTANCE_ROOT>/state"
New-Item -ItemType Directory -Force "$env:MIND_STATE_HOME/reports"
mind --version
mind mcp add sentry-oauth-acceptance --url "<SENTRY_MCP_URL>"
macOS/Linux 终端可用 export MIND_HOME="<ACCEPTANCE_ROOT>/config" 和
export MIND_STATE_HOME="<ACCEPTANCE_ROOT>/state" 设置同样的隔离目录。
记录版本或提交、平台、源码/安装入口和 SDK 版本;URL、组织与项目仅使用脱敏别名。
按服务端支持的方式配置公共客户端;预注册方式必须匹配固定 loopback 回调端口。
首次登录、调用与新进程恢复
- 执行
mind mcp login sentry-oauth-acceptance,在真实浏览器中选择测试账户并同意授权。 确认回调完成且命令返回 0;不要将授权地址、回调 URL 或授权码复制到报告。 - 执行
mind mcp get sentry-oauth-acceptance和mind mcp list,确认本地状态且无机密输出。 - 启动
mind,用/mcp status和/tools确认服务已连接并发现工具。从实际目录选择 一个只读调用,经现有审批路径执行并核对真实结果。只有服务实际暴露find_releases时才使用它;参数须限定在测试账户可访问的组织/项目。 - 完全退出进程并重新启动,再次调用同一只读工具,确认无需浏览器登录。确认验收配置 未设置 Bearer/Header,也未借用其他客户端的凭据。
刷新、竞争和失败恢复
| 场景 | 操作与通过标准 |
|---|---|
| 实际过期刷新 | 等待真实令牌到期,或使用服务正式支持的短有效期设置;下一次调用成功,新进程仍可调用。用脱敏的本地 expires_at 前后变化或服务端刷新事件确认刷新及持久化,不能仅以调用成功证明。 |
| 多进程 | 两个进程共享验收目录,在到期边界执行只读调用,无重复登录、轮换冲突或凭据覆盖。 |
| 授权拒绝 | 在真实授权页面拒绝一次登录,确认明确失败后可以重新登录。 |
| 取消与回调 | 登录等待时 Ctrl+C,确认退出码 130、回调端口释放,下一次登录成功。 |
| 手动打开 | 在不能自动启动浏览器的终端中,手动打开该次授权地址并完成登录。 |
| 手动回调 | 从交互终端执行 login --manual,在另一台机器的浏览器授权后,将完整回调 URL 粘贴回隐藏输入;确认无回显、正常保存。另验证浏览器回调先到时能自动结束输入。 |
| 网络失败 | 暂时断网后收到明确错误,恢复网络后可重新登录或重启服务;无无限刷新。 |
| 服务端撤销 | 在测试账户中撤销授权,下一请求失败且工具目录撤下,提示重新登录;原工具调用不自动重放。 |
| 退出竞争 | 一个进程调用,另一个执行 logout;活动进程在下一请求边界不得继续使用旧凭据,旧刷新结果不得恢复已删除登录。 |
| 清理和重入 | logout 两次均安全;新进程显示未登录,重新登录可恢复。最后先 logout,再 remove,仅清理本次创建的注册和资源。 |
若服务不发放 refresh token 或无法在验收窗口内验证过期,该项保留“待验收”,并另选实际 支持刷新的 MCP 服务补验。Linux/macOS 的浏览器、系统凭据库和取消行为须在对应平台 实际执行,不能用 Windows 通过结果代替。
隐藏输入与终端恢复
在仓库根目录运行真实 PTY 驱动,使用源码 CLI、本机 HTTP OAuth 故障服务和系统凭据库, 不需要真实账号。验收目录必须尚不存在;结束时清理本轮合成凭据。
python -m tests.manual.mcp_callback_acceptance --directory "<NEW_ACCEPTANCE_ROOT>"
它检查普通粘贴、括号粘贴、浏览器回调、错误 state/issuer、拒绝、超限、未结束粘贴、 取消、EOF、等待超时、令牌交换取消/超时及跨进程退出竞争。每项都检查原始终端模式恢复、 后续普通输入可用、输入无回显、回调端口关闭和凭据提交结果;报告只记录这些事实。 本机故障服务的粘贴成功不能代替真实 Sentry 或跨机器远程终端验收;实际使用的入口和 平台须分别记录。Linux/macOS 需在对应操作系统运行后才可记为通过。
Sentry 刷新和退出边界脚本
已有隔离注册和真实浏览器登录后,可用以下源码脚本重复检查生产连接适配器。它固定调用
execute_sentry_tool 中的 find_releases,需要目标服务提供该工具且账号可读取版本。
脚本不启动模型、不修改配置或令牌时间,也不主动退出登录;TUI 审批仍按前述步骤单独验收。
python -m tests.manual.mcp_oauth_sentry --config-root "<CONFIG_ROOT>" --state-root "<STATE_ROOT>" --mode call --report "<STATE_ROOT>/reports/call.json"
python -m tests.manual.mcp_oauth_sentry --config-root "<CONFIG_ROOT>" --state-root "<STATE_ROOT>" --mode wait-expiry --report "<STATE_ROOT>/reports/refresh-a.json"
默认注册名为 sentry-oauth-acceptance;可通过 --server 指定专用注册。wait-expiry 等待
当前凭据实际到期,默认最多等待 3600 秒,可通过 --timeout 调整。在到期前从两个终端
同时启动该模式,第二份报告使用 refresh-b.json,两进程须共用同一配置根和状态根。
完成后再从新进程执行 call,报告使用新文件名,确认刷新后的凭据可以恢复。
刷新报告显式核对调用前确已过期、消费标记和提交引起的两次版本递增、令牌轮换及新的
有效期;报告只保存判断结果、版本和绝对时间。两份报告还应核对最终版本一致。
entry_kind=source-runtime-adapter 表示适配器证据;CLI 和交互 TUI 的验收分别记录。
验证活动连接观察退出登录时,在第一个终端运行:
python -m tests.manual.mcp_oauth_sentry --config-root "<CONFIG_ROOT>" --state-root "<STATE_ROOT>" --mode observe-logout --timeout 180 --report "<STATE_ROOT>/reports/logout-observer.json"
看到 READY 后,在配置了相同 MIND_HOME、MIND_STATE_HOME 的另一个终端运行源码
mcp logout sentry-oauth-acceptance。观察进程会在凭据删除后发起下一次调用,检查
login_required、目录撤下和连接关闭,再读取最终凭据状态。该检查证明请求边界生效;
刷新正在交换时的退出竞争仍需单独记录。
退出后以新进程运行 --mode logged-out,使用新的报告文件,验证生产连接明确报告
login_required 且没有暴露工具。该模式会真正启动连接检查,不能用本地凭据为空替代。
每次报告必须位于状态根的 reports/ 下且使用新文件名;失败同样保存脱敏状态并返回
非零退出码。报告不包含工具结果正文、OAuth URL 或原始异常信息。终端取消时,应检查
源码子进程的返回码;Windows 外层 Shell 的中断状态可能与子进程返回码不同。
完成只读调用及恢复检查后,可以对本次新建的隔离授权执行 --mode revoke。
该模式会真实撤销测试授权:先从已经登录的 issuer 读取正式撤销端点,要求与 issuer 同源,
再发送本轮令牌并确认后续调用被拒绝、工具目录撤下。撤销响应为成功本身不算通过;
必须观察实际认证失败,报告才记录 server_revocation_observed=true。
不要对日常配置运行此模式;服务没有提供可用撤销端点时保留待验收。
python -m tests.manual.mcp_oauth_sentry --config-root "<CONFIG_ROOT>" --state-root "<STATE_ROOT>" --server sentry --mode revoke --report "<STATE_ROOT>/reports/revocation.json"
传输故障的本机综合验收入口为
python -m tests.manual.mcp_transport_acceptance --directory "<NEW_ACCEPTANCE_ROOT>"。
它通过真实 stdio、Streamable HTTP、SSE 连接检查协议上限、初始化重试、截止时间、
调用失败不重放、工具发现和关闭;每次使用新目录,不修改日常配置。
截止时间用例检查有界耗时和实际重试次数,不要求受系统调度影响的次数恒定。
记录模板
将下表复制为 <STATE_ROOT>/reports/mcp-oauth-acceptance-<date>-<platform>.md。
只保留时间、平台、版本、脱敏服务身份、状态和结果;不附原始终端转储、完整 URL、Token、
secret、授权码或凭据库内容。失败后填写原因和复验结果,不覆盖原失败记录。
| 字段 | 内容 |
|---|---|
| 时间 / 平台 | 待填写 |
| 版本 / 提交 / SDK | 待填写 |
| 源码或安装入口 / 检查结果 | 待填写 |
| 脱敏服务身份 / 客户端注册方式 | 待填写 |
| 首次浏览器登录 / 返回码 | 待验收 |
| 工具发现 / 审批 / 只读结果 | 待验收 |
| 新进程恢复 | 待验收 |
| 实际刷新 / 持久化证据 | 待验收 |
| 多进程 / 退出竞争 | 待验收 |
| 拒绝 / Ctrl+C / 端口释放 / 手动打开 | 待验收 |
| 断网 / 撤销 / 重新登录 | 待验收 |
| logout / 重复 logout / 清理 | 待验收 |
| Windows / Linux / macOS | 分别填写;未执行保持待验收 |
| 最终结果 / 待验收项 | 待填写 |