将 无官方订阅的Claude Code 接入飞书:cc-connect 配置踩坑全记录
背景
Claude Code 是 Anthropic 推出的终端 AI 编程助手,能力很强,但只能通过本地终端使用(Remote Control和Channels都需要订阅)。cc-connect 是一个开源工具,能将 Claude Code(以及 Cursor、Gemini CLI 等)桥接到飞书、钉钉、Telegram 等即时通讯平台,实现手机远程调用 Claude Code。
本文记录了使用 cc-connect 将本地 Claude Code 接入飞书群聊的完整过程,包括第三方 API 代理的认证配置和实际踩坑经验。
环境:macOS + LMStudio 本地代理 + Claude Code + 飞书自建应用
前置条件
- 已安装 Claude Code(
npm install -g @anthropic-ai/claude-code) - 已有一个运行中的 Anthropic 兼容 API 代理(本文使用 LMStudio 本地代理,地址
http://127.0.0.1:3456) - 飞书开放平台已创建自建应用,且已启用机器人能力
第一步:安装 cc-connect
npm install -g cc-connect
验证安装:
cc-connect --version
# v1.3.2
第二步:绑定飞书应用
cc-connect feishu bind --app "<App ID>:<App Secret>"
其中 <App ID>:<App Secret> 从飞书开放平台 > 应用开发 > 凭证与基础信息中获取。
绑定成功后会输出 WebSocket 连接信息,说明飞书通道已打通。
第三步:首次启动验证
cc-connect start -f
启动后,在飞书中给机器人发一条消息。此时有两种情况:
- 官方账号用户:如果已通过
claude login登录了 Anthropic 官方账号,Claude Code 会正常回复,配置到此完成 - 第三方 API 代理用户:会收到
Not logged in. Please run /login的回复。这是因为 Claude Code 没有检测到有效的认证信息。继续下一步
第四步:配置第三方 API 代理(核心难点)
为什么需要这步?
Claude Code 启动时检查 ANTHROPIC_API_KEY 环境变量来决定使用哪个 API 端点。使用第三方代理时,需要通过环境变量指定代理地址和密钥。
cc-connect 内置的 Provider 机制不生效
cc-connect 提供了 provider add 命令和配置文件中的 [[projects.agent.providers]] 机制来管理 API 代理。理论上可以在配置文件中声明 provider 并通过 --env 注入环境变量:
# ~/.cc-connect/config.toml
[[projects]]
name = "claude-workroom"
[projects.agent]
type = "claudecode"
provider = "local-proxy" # 声明默认 provider
[[projects.agent.providers]]
name = "local-proxy"
api_key = "test"
base_url = "http://127.0.0.1:3456"
[projects.agent.providers.env]
ANTHROPIC_API_KEY = "sk-xxx"
ANTHROPIC_BASE_URL = "http://127.0.0.1:3456"
但在实际测试中(v1.3.2),这个机制完全不生效:
- debug 日志中
activeIdx=-1(始终未激活),providerEnv=[](始终为空) - 配置文件中声明
provider = "local-proxy"不会自动激活 provider add --env "KEY=VAL"注入的 env 也不会传递给 Claude Code 子进程- 只有在飞书中手动发送
/provider switch local-proxy后才生效,但该状态仅存在于内存中,重启 cc-connect 或新建 session(/new)后立即丢失
这是 cc-connect 的一个已知问题。如果未来版本修复了,provider 机制会是最优雅的方案。但在当前版本下,需要用下面的替代方案。
替代方案:启动脚本中设置环境变量
由于 cc-connect 的 provider env 不生效,但 Claude Code 会继承父进程的环境变量,因此在启动 cc-connect 的 shell 环境中直接设置 ANTHROPIC_API_KEY 和 ANTHROPIC_BASE_URL 即可:
export ANTHROPIC_API_KEY="你的API密钥"
export ANTHROPIC_BASE_URL="http://你的代理地址:端口"
cc-connect start -f
建议写成启动脚本,方便重复使用:
#!/bin/bash
# start-cc-connect.sh
export ANTHROPIC_API_KEY="你的API密钥"
export ANTHROPIC_BASE_URL="http://你的代理地址:端口"
export API_TIMEOUT_MS="600000"
export DISABLE_TELEMETRY="true"
export DISABLE_COST_WARNINGS="true"
export NO_PROXY="127.0.0.1"
# 防止继承父进程的 CLAUDECODE 环境变量(可能导致冲突)
unset CLAUDECODE
exec cc-connect start -f "$@"
使用方法:
chmod +x start-cc-connect.sh
./start-cc-connect.sh
环境变量说明
| 变量 | 必需 | 说明 |
|---|---|---|
ANTHROPIC_API_KEY |
是 | Claude Code 的 API 密钥,值为代理的密钥 |
ANTHROPIC_BASE_URL |
是 | API 代理地址,如 http://127.0.0.1:3456 |
API_TIMEOUT_MS |
否 | API 请求超时时间(毫秒),默认值可能过短,建议 600000(10 分钟) |
DISABLE_TELEMETRY |
否 | 禁用 Claude Code 的遥测数据上报 |
DISABLE_COST_WARNINGS |
否 | 禁用费用警告 |
NO_PROXY |
否 | 不走代理的地址,防止本地代理请求走系统代理。值为 127.0.0.1 |
注意:
unset CLAUDECODE很重要。如果父进程(如另一个终端或脚本)设置了CLAUDECODE环境变量,Claude Code 可能会尝试使用不兼容的通信协议,导致启动失败。
自动跳过权限确认(推荐)
Claude Code 默认在执行文件读写、Shell 命令等操作前会弹出权限确认。如果你通过手机飞书发消息,无法回到电脑上点击允许,需要配置自动跳过权限。
在 Claude Code 的全局配置目录创建 settings.json:
mkdir -p ~/.claude
cat > ~/.claude/settings.json << 'EOF'
{
"permissions": {
"dangerouslySkipPermissions": true
}
}
EOF
此配置对所有 Claude Code 实例生效,包括本地终端直接使用的场景。如果你只希望在 cc-connect 中跳过权限,可以将 settings.json 放在工作目录的
.claude/settings.json下(本文中为/Users/mac/cchome/workroom/.claude/settings.json)。cc-connect 配置文件中的
mode = "bypassPermissions"设置的是--permission-mode bypassPermissions,这和dangerouslySkipPermissions不同。前者仅跳过部分编辑权限,后者跳过所有权限检查。两者可以同时设置,settings.json 的优先级更高。
第五步:重启验证
pkill -9 -f cc-connect
./start-cc-connect.sh
在飞书中发送 /new 开启新会话,然后发一条消息。Claude Code 应正常回复(不再是 "Not logged in")。
第六步:开机自启动(推荐)
安装 daemon 服务
cc-connect daemon install --config ~/.cc-connect/config.toml
这会在 ~/Library/LaunchAgents/ 下创建 launchd plist 文件,实现开机自启动和崩溃自动重启。
配置环境变量
关键: cc-connect 以 daemon 方式运行时,不会加载 .zshrc 等 shell profile,因此环境变量必须在 plist 文件中显式配置。
编辑生成的 plist 文件(路径为 ~/Library/LaunchAgents/com.cc-connect.service.plist),在 EnvironmentVariables 中添加必要的环境变量:
<key>EnvironmentVariables</key>
<dict>
<key>CC_LOG_FILE</key>
<string>/Users/mac/.cc-connect/logs/cc-connect.log</string>
<key>CC_LOG_MAX_SIZE</key>
<string>10485760</string>
<key>PATH</key>
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
<!-- 以下为 Claude Code 所需的环境变量 -->
<key>ANTHROPIC_API_KEY</key>
<string>你的API密钥</string>
<key>ANTHROPIC_BASE_URL</key>
<string>http://你的代理地址:端口</string>
<key>API_TIMEOUT_MS</key>
<string>600000</string>
<key>DISABLE_TELEMETRY</key>
<string>true</string>
<key>DISABLE_COST_WARNINGS</key>
<string>true</string>
<key>NO_PROXY</key>
<string>127.0.0.1</string>
</dict>
macOS 的限制: launchd 启动的进程不继承用户 shell 的环境变量,包括
.zshrc、.bash_profile等。即使你在.zshrc中 export 了ANTHROPIC_API_KEY,daemon 进程也看不到。必须写在 plist 的EnvironmentVariables中。
重启 daemon 使配置生效
cc-connect daemon stop
cc-connect daemon start
daemon 管理命令
| 命令 | 作用 |
|---|---|
cc-connect daemon status |
查看运行状态 |
cc-connect daemon logs -f |
实时查看日志 |
cc-connect daemon restart |
重启 |
cc-connect daemon stop |
停止 |
cc-connect daemon start |
启动 |
后续如果需要修改环境变量(如更换 API Key),编辑 plist 文件后执行
cc-connect daemon restart即可。
踩坑记录
坑 1:cc-connect 的 Provider env 机制不生效
现象:配置了 [[projects.agent.providers]] 和 env,debug 日志中 providerCount=1 但 providerEnv=[]。
原因:cc-connect v1.3.2 的 claudecode agent 在启动 Claude Code 子进程时,不会读取 provider 中定义的 env 并注入。
解决:通过系统环境变量传递 ANTHROPIC_API_KEY 和 ANTHROPIC_BASE_URL。
坑 2:provider = "local-proxy" 配置不自动激活
现象:config.toml 中声明了 provider = "local-proxy",但 debug 日志中 activeIdx=-1。
原因:cc-connect 的 config 解析和 provider 激活逻辑存在脱节。config 中声明 provider 不会自动设置 activeIdx。
解决:同坑 1,通过环境变量绕过 provider 机制。或在飞书中每次手动 /provider switch(不推荐,状态不持久化)。
坑 3:provider add 会删除 config 中的 provider 字段
现象:执行 cc-connect provider add --project xxx --name xxx --env "KEY=VAL" 后,之前手动添加的 provider = "local-proxy" 字段从 config.toml 中消失了。
原因:provider add 命令会重写整个 [projects.agent] 配置段,导致手动添加的字段丢失。
解决:provider add 后需要手动补回 provider 字段。但如果 provider 机制本身不生效(坑 1),这一步意义不大。
坑 4:unset CLAUDECODE 是必须的
现象:Claude Code 启动后立即退出或行为异常。
原因:如果父进程设置了 CLAUDECODE 环境变量(例如在另一个 Claude Code session 中启动 cc-connect),Claude Code 会认为自己是被另一个 Claude Code 实例嵌套调用的,导致通信协议冲突。
解决:在启动脚本中 unset CLAUDECODE。
坑 5:NO_PROXY 防止代理死循环
现象:Claude Code 请求超时或连接被拒。
原因:如果系统配置了 HTTP 代理(如 http_proxy),对 127.0.0.1 的请求也会走代理,而代理可能不支持或配置不正确,导致连接失败。
解决:设置 NO_PROXY=127.0.0.1。
坑 6:bypassPermissions 不等于跳过所有权限
现象:cc-connect 配置了 mode = "bypassPermissions",但 Claude Code 执行工具(如 Bash、Edit)时仍然需要手动确认。
原因:cc-connect 的 mode = "bypassPermissions" 对应的是 Claude Code 的 --permission-mode bypassPermissions,这只跳过部分权限,不是完全跳过。
解决:在 ~/.claude/settings.json 中设置 "permissions": {"dangerouslySkipPermissions": true},这会跳过所有权限检查。
坑 7:daemon 模式下环境变量不生效
现象:交互式终端中启动脚本运行正常,但 daemon 模式下飞书回复 "Not logged in"。
原因:launchd 启动的进程不继承用户 shell 的环境变量。直接编辑 plist 文件中的 EnvironmentVariables 后,必须通过 cc-connect daemon stop && cc-connect daemon start 重启才能生效。仅修改 plist 文件而未重启,或者用 launchctl bootstrap 方式重新加载,可能因残留的 lock 文件导致启动失败。
解决:环境变量写在 plist 的 EnvironmentVariables 中,通过 cc-connect daemon stop/start 重启。如果启动失败,检查并清理 ~/.cc-connect/.config.toml.lock 锁文件。
完整配置参考
最终的 ~/.cc-connect/config.toml(不含 API 密钥,密钥通过环境变量注入):
data_dir = ""
attachment_send = ""
language = "zh"
[[projects]]
name = "claude-workroom"
[projects.agent]
type = "claudecode"
[projects.agent.options]
mode = "bypassPermissions"
work_dir = "/Users/mac/cchome/workroom"
[[projects.platforms]]
type = "feishu"
[projects.platforms.options]
app_id = "cli_xxxxxxxxxxxx"
app_secret = "xxxxxxxxxxxxxxxxxxxxxxxx"
[log]
level = "info"
[speech]
enabled = false
provider = ""
language = ""
[tts]
enabled = false
provider = ""
voice = ""
tts_mode = ""
max_text_len = 0
[cron]
session_mode = ""
[webhook]
port = 0
[bridge]
port = 0
[management]
port = 0
[management.auth]
token = ""
本文虽然看起来风格像我,但完全是由AI根据实际问题处理案例生成。我不知道中间有没有错误的内容,但是最终结果是配置成功了。

