A New Collection of Thoughtful Learning Apps — Now Available on iOS & Android

Image
I’m excited to share a set of mobile apps I’ve recently completed and published on both the Google Play Store and the Apple App Store. These apps are designed with a simple goal in mind: to make meaningful, structured content more accessible, whether you’re studying theology or improving your English vocabulary. 📱 Now Available on Both Platforms All apps are live and available for download: Google Play Developer Page: https://play.google.com/store/apps/dev?id=5835943159853189043 Apple App Store Developer Page: https://apps.apple.com/ca/developer/q-z-l-corp/id1888794100 📖 Theology & Confession Study Apps For those interested in Reformed theology and classical Christian teachings, I’ve developed a series of apps that present foundational texts in a clean, focused reading format: The Belgic Confession Canons of Dort Heidelberg Catechism Westminster Shorter Catechism Each app is designed to provide a distraction-free experience, making it easier to read, reflect, and revisit these im...

我如何修复了 macOS 上的 GitHub Copilot CLI 连接问题

我如何修复了 macOS 上的 GitHub Copilot CLI 连接问题



问题描述

我遇到了一个令人沮丧的问题。GitHub Copilot 在 VS Code 的聊天窗口中运行良好,但是 gh copilot CLI 命令会无限期地挂起,没有任何输出。所有命令,如 gh copilot -p "what is 2+2" 都会冻结,使 CLI 无法使用。

初始症状

  • ✅ GitHub Copilot 在 VS Code 中聊天功能工作正常
  • ✅ GitHub CLI (gh) 已安装并已通过身份验证
  • ✅ 令牌具有正确的 copilot 作用域
  • ❌ 任何 gh copilot 命令都会挂起并超时
  • ❌ 命令似乎连接但从不返回结果

诊断过程

步骤1:验证身份验证

首先,我检查了 GitHub CLI 是否已正确通过身份验证:

gh auth status

输出显示我已使用 copilot 作用域登录:

github.com
  ✓ 已登录账户 qzl-dev (keyring)
  - 令牌作用域:'admin:public_key', 'copilot', 'gist', 'read:org', 'repo'

身份验证不是问题。

步骤2:检查 Copilot CLI 安装

gh copilot --version

CLI 已安装(版本 0.0.422),所以这也不是问题。

步骤3:查看日志

这是我发现问题的地方。我检查了 Copilot CLI 日志:

cat ~/.copilot/logs/*.log | tail -50

日志显示了真正的问题:

[ERROR] 发出 GitHub API 请求时出错:Error: unable to get issuer certificate; 
if the root CA is installed locally, try running Node.js with --use-system-ca

[ERROR] 无法启动远程服务器 github-mcp-server 的 MCP 客户端: 
TypeError: fetch failed

[ERROR] github-mcp-server 的 MCP 传输已关闭

根本原因

GitHub Copilot CLI 在内部使用 Node.js,需要连接到位于 https://api.individual.githubcopilot.com/mcp/readonly 的 MCP(模型上下文协议)服务器。问题是 SSL 证书验证失败,因为 Node.js 没有配置使用系统证书颁发机构(CA)存储。

这解释了为什么 VS Code 工作正常——VS Code 使用自己的证书处理,而 CLI 使用 Node.js 的内置 TLS/SSL 验证。

解决方案

通过设置环境变量来配置 Node.js 使用系统的 OpenSSL CA 证书:

export NODE_OPTIONS="--use-openssl-ca"

为了使其永久生效,我将其添加到 shell 配置文件:

echo 'export NODE_OPTIONS="--use-openssl-ca"' >> ~/.zshrc
source ~/.zshrc

测试修复

设置环境变量后,我测试了 CLI:

gh copilot -p "what is 2+2"

成功了!CLI 成功连接到 MCP 服务器并返回响应。

为什么会发生这种情况

这个问题通常发生在以下情况:

  1. 公司网络具有拦截 HTTPS 流量的自定义 SSL 证书
  2. 安全软件注入其自己的 CA 证书
  3. 代理配置需要自定义证书验证
  4. macOS 系统更新更改证书存储位置

Node.js 默认使用自己的捆绑 CA 证书,而不是系统的证书存储。--use-openssl-ca 标志告诉 Node.js 使用操作系统级别的证书存储,该存储包括系统上安装的任何自定义证书。

替代方案

如果上述解决方案不起作用,您可以尝试:

更新 OpenSSL 证书:

brew update
brew upgrade openssl

仅用于开发/测试(不建议用于生产):

export NODE_TLS_REJECT_UNAUTHORIZED=0

⚠️ 警告:这会完全禁用证书验证,仅应用于临时调试。

关键要点

  1. 首先检查日志:Copilot CLI 在 ~/.copilot/logs/ 中存储详细日志,这对调试很有价值
  2. SSL 问题很常见:当 CLI 工具在 API 调用上挂起时,SSL 证书验证通常是罪魁祸首
  3. 环境变量很重要:Node.js 行为可以通过 NODE_OPTIONS 进行显著改变
  4. VS Code 隔离:仅因为 Copilot 在 VS Code 中工作并不意味着 CLI 也会工作——它们使用不同的网络栈

配置文件

供参考,这是我在 ~/.copilot/mcp-config.json 中的 MCP 配置:

{
  "mcpServers": {
    "github-mcp-server": {
      "type": "http",
      "url": "https://api.individual.githubcopilot.com/mcp/readonly"
    }
  }
}

该配置由 VS Code 和 CLI 都使用,但 CLI 需要额外的 Node.js 环境变量来正确处理 SSL。

结论

SSL 证书问题可能令人沮丧,因为它们通常表现为无声挂起而不是清晰的错误消息。解决这个问题的关键是深入研究日志并了解 Copilot CLI 在内部使用 Node.js。通过使用 --use-openssl-ca 配置 Node.js 使用系统证书存储,CLI 可以成功验证 SSL 证书并连接到 MCP 服务器。

如果您遇到类似的 GitHub Copilot CLI 或任何 Node.js 命令行工具在 HTTPS 连接上挂起的问题,请检查日志并尝试此解决方案!


修复于:2026 年 3 月 5 日
环境:macOS, GitHub CLI with Copilot extension 0.0.422

❤️ Support This Blog


If this post helped you, you can support my writing with a small donation. Thank you for reading.


Comments

Popular Posts

Fix “A problem occurred starting process 'command node'” in Android Studio for React Native

Fix up watchman issue with Ghost

Using Mutual TLS (mTLS) in Next.js (Server-Side Only)