SSH 里 Codex MCP 提示未登录,可能不是 MCP 坏了

By wwd · 2026-08-01 07:53:52

技术排障#Codex#macOS#MCP#ssh

SSH 里 Codex MCP 提示未登录,可能不是 MCP 坏了

今天碰到一个容易误判的问题:同一台 Mac,本机打开终端运行 Codex CLI 没有任何 MCP 授权警告;但从另一台电脑远程登录到这台 Mac,再运行同一个 codex 命令,就提示某些 MCP server 没有登录。

第一反应很容易是:是不是 Codex 装了两份?是不是 MCP 配置坏了?是不是远程服务本身断了?后来查下来,真正的问题要普通得多:SSH 会话没有解锁 macOS 的 login keychain,Codex 读不到保存在里面的 OAuth 凭证。

一、先确认是不是同一个 Codex

先不要急着重新登录 MCP。第一步是确认本机终端和 SSH 终端跑的是不是同一个 Codex。

可以分别在两个终端里执行:

which -a codex
codex --version
echo "CODEX_HOME=$CODEX_HOME"
echo "$PATH"

这里主要看三件事:

  • which codex 指向哪里;
  • codex --version 是否一致;
  • CODEX_HOME 是否被设置成了不同目录。

如果这些不一样,先修 PATH 或配置目录。很多机器上可能同时残留 Homebrew、npm、独立安装器、桌面 App 内置版等多份 Codex。它们都叫 codex,但不一定读同一套状态。

二、再看 MCP 登录状态

接着看 MCP 列表:

codex mcp list

如果本机终端里显示 OAuth 正常,SSH 终端里同样的 server 却显示 Not logged in,而前面的 Codex 路径、版本、CODEX_HOME 又都一样,那就基本可以排除“装错版本”和“配置目录不同”。

这时更该怀疑的是 macOS Keychain。

三、为什么 SSH 会读不到 OAuth 凭证

很多 OAuth 类凭证不会直接明文放在配置文件里,而是存在系统安全存储里。在 macOS 上,这通常会牵涉 login keychain。

本机图形登录后,login keychain 往往已经解锁,所以本机终端能读到凭证。SSH 远程登录虽然也是同一个用户,但它是另一个会话,不一定能直接使用已经解锁的 keychain 状态。

所以就会出现一个看起来矛盾的现象:

  • 同一台机器;
  • 同一个用户;
  • 同一个 codex;
  • 同一个 ~/.codex;
  • 但本机没警告,SSH 有警告。

差别就在于 SSH 会话读不到 keychain 里的 OAuth token。

四、怎么验证和修复

在 SSH 会话里先看 keychain:

security default-keychain
security list-keychains

看到 login keychain 在列表里,只能说明路径存在,不代表它已经解锁。可以手动解锁:

security unlock-keychain ~/Library/Keychains/login.keychain-db

输入密码后,再看:

codex mcp list

如果原来的 Not logged in 变成了 OAuth,问题就确认了:不是 MCP server 坏了,也不是 Codex 配置坏了,而是 SSH 会话下 keychain 没解锁。

以后远程登录后,如果又遇到同样警告,可以先解锁 keychain,再启动 Codex:

security unlock-keychain ~/Library/Keychains/login.keychain-db
codex

不建议把 keychain 密码写进脚本。嫌麻烦的话,可以做一个只负责提示解锁的 alias:

alias codex-ssh='security unlock-keychain ~/Library/Keychains/login.keychain-db && codex'

五、排查顺序

遇到这种问题,可以按这个顺序查:

  1. 先确认本机和 SSH 里 which codex、codex --version、CODEX_HOME 是否一致。
  2. 再看 codex mcp list 里 OAuth server 的 Auth 状态。
  3. 如果只有 SSH 里显示 Not logged in,优先解锁 login keychain。
  4. 解锁后再复查 MCP 状态。
  5. 只有在解锁无效时,才考虑重新执行 codex mcp login <name>。

这个问题的坑在于,它看起来像远程 MCP 登录失败,其实是本地安全存储没有被当前会话打开。先把运行环境和 keychain 状态查清楚,能少走很多弯路。

Reactions

Comments

No comments yet.

Leave a comment