如何把 Linear 接入 Claude Managed Agents:@mention 触发会话并把回复写回 issue 评论
【免费下载链接】claude-cookbooksA collection of notebooks/recipes showcasing some fun and effective ways of using Claude.项目地址: https://gitcode.com/GitHub_Trending/an/claude-cookbooks
如果你的 Linear workspace 里想让 Claude Managed Agent(CMA)像一个团队成员一样被 @mention、然后自动在 issue 下回复评论,可以参考 claude-cookbooks 仓库中managed_agents/linear目录下的桥接服务。这个项目实现了一个无状态 webhook 桥:Linear issue 里的 @mention 会触发 Linear 的AgentSessionEventwebhook,桥用它创建一个带路由metadata的 CMA 会话并发送user.message;Claude 在 Anthropic 侧跑完后,Anthropic 向桥推送session.status_idled事件,桥再根据会话里的 metadata 把回复通过createAgentActivity写回 Linear issue 评论。整体链路如下(来自 README):
Linear @mention ──▶ /linear-webhook ──▶ sessions.create (+ metadata) ──▶ 200 │ Claude runs to idle on Anthropic infra │ /cma-webhook ◀── session.status_idled ◀──────────┘ │ └──▶ sessions.retrieve → read metadata → createAgentActivityCMA 会话的metadata(linear_session_id、linear_org_id)就是全部路由状态,桥本身不存任何业务数据。适用前提:需要 Bun 运行时、一个公网可达的回调地址(本地开发用 ngrok 或 cloudflared)、Linear workspace 的 admin 权限(OAuth 应用只能由 workspace 管理员创建),以及一把 Anthropic API key。
准备条件与代码结构
进入模块目录并安装依赖:
cd managed_agents/linear bun installpackage.json 的依赖只有@anthropic-ai/sdk(^0.95.1,README 明确要求 ≥ 0.95.1)和@linear/sdk(^81.0.0)。README 的 Quickstart 还提到可以运行claude启动 Claude CLI,然后让它带着你完成配置——Claude 会读取 skill.md 按可工作的顺序走一遍。下面的手工路径和这条自动化路径做的事一致,这里以手工路径为主线。
各源码文件的分工(文件清单见 README 的 Files 表):
| 文件 | 职责 |
|---|---|
| setup/create-agent.ts | 一次性执行:agents.create+environments.create |
| src/main.ts | Bun 服务入口与全部路由 |
| src/oauth.ts | Linear OAuth(actor=app)与 token 存储 |
| src/agent.ts | sessions.create+ 带路由 metadata 的user.message |
| src/cma-webhook.ts | beta.webhooks.unwrap→ 按 metadata 过滤 → 发回复 |
先起一个隧道拿到公网 URL,后续所有回调地址都用它:
ngrok http 3000记下 ngrok 给出的https://...公网地址,下面记作<url>。
第一步:一次性创建 Claude agent 和 environment
bun run setup该命令执行 setup/create-agent.ts,调用 Anthropic SDK 创建一个名为linear-bridge-<时间戳>的 cloud environment(networking为unrestricted)和一个名为Linear Assistant的 agent,模型为claude-opus-4-7,启用agent_toolset_20260401工具集,system prompt 要求回复简短可执行、不要编造 issue ID、用户或项目名。执行成功后终端会打印:
Add to .env.local: CLAUDE_ENVIRONMENT_ID=<env.id> CLAUDE_AGENT_ID=<agent.id>把这两个 ID 拷下来,稍后写入.env.local。这一步只需要做一次。
第二步:创建 Linear OAuth 应用
OAuth 应用只能由 workspace 管理员创建:在linear.app/<your-workspace>/settings/api侧边栏进入Administration → API,然后找到OAuth Applications区域,点Create new(见 skill.md)。如果你不是公司 workspace 的 admin,skill.md 建议先建一个免费的个人 workspace 做测试。
创建时填写:
- Developer URL:必填但只是展示在授权页面上的链接,任意真实的
https://URL 即可; - Callback URL:
<url>/oauth/callback; - Webhook URL:
<url>/linear-webhook,订阅事件选择Agent session events; - 记下client ID / client secret和webhook signing secret。
这里有两个关键点,直接决定后续能否跑通:
- OAuth 授权时必须带
scope=app:assignable,app:mentionable和actor=app(src/oauth.ts 的handleOAuthAuthorize已包含)。actor=app会在 Linear workspace 里创建一个app user,这样 agent 才会出现在 @ 选择器里;个人LINEAR_API_KEY做不到这一点,回复必须以 app 身份经 OAuth token 发出。 - src/agent.ts 在收到
AgentSessionEvent后、创建 CMA 会话之前,会先createAgentActivity发一条{type: "thought", body: "Thinking..."}——因为 Linear 要求 10 秒内必须有第一条agentActivity,否则该 session 会被标记为失败。
第三步:在 Anthropic Console 注册 CMA webhook
在 Anthropic Console 的 Webhooks 页面注册端点:
- URL:
<url>/cma-webhook - 订阅事件:
session.status_idled+session.status_terminated(skill.md 建议只订阅需要的类型,不要选 "All events") - 记下
whsec_...开头的 signing key
端点必须注册在与你的ANTHROPIC_API_KEY相同的 workspace。Anthropic webhook 是 workspace 级的:如果 API key 属于 workspace A,而端点注册在 workspace B,会得到零投递且没有任何报错。检查 API key 所在 workspace 的方法是对照 API key 的 Workspace 列和 Console Webhooks 页的 workspace 选择器。
反过来也要知道:workspace webhook 会对该 workspace 里所有session 触发,不只是你创建的。src/cma-webhook.ts 因此会先sessions.retrieve(id),检查metadata里是否有linear_session_id/linear_org_id,不是自己的会话(包括你的 key 读不到的其他 key 创建的 session,会走 404/403 分支)一律返回 204 丢弃。
第四步:填写 .env.local 并启动桥
.env.local需要以下变量:LINEAR_WEBHOOK_SIGNING_SECRET、ANTHROPIC_WEBHOOK_SIGNING_KEY、CLAUDE_AGENT_ID、CLAUDE_ENVIRONMENT_ID是 src/main.ts 启动时强制检查的,缺失任意一个会打印FATAL: <name> is required并直接process.exit(1);LINEAR_CLIENT_ID、LINEAR_CLIENT_SECRET由 src/oauth.ts 的授权流程使用。BASE_URL未设置时默认http://localhost:<PORT>,PORT默认 3000。
cat > .env.local <<'EOF' LINEAR_CLIENT_ID=<第二步复制的 client ID> LINEAR_CLIENT_SECRET=<第二步复制的 client secret> LINEAR_WEBHOOK_SIGNING_SECRET=<第二步复制的 webhook secret> ANTHROPIC_WEBHOOK_SIGNING_KEY=<第三步复制的 whsec_...> CLAUDE_AGENT_ID=<第一步打印的 agent ID> CLAUDE_ENVIRONMENT_ID=<第一步打印的 environment ID> BASE_URL=<ngrok 公网 URL> EOF其中ANTHROPIC_API_KEY由 SDK 从环境读取,whsec_前缀的值填入ANTHROPIC_WEBHOOK_SIGNING_KEY。然后启动:
bun run dev启动后服务会打印路由信息,可用于自检:
Bridge running at <BASE_URL> Install agent: <BASE_URL>/oauth/authorize Linear webhook: <BASE_URL>/linear-webhook CMA webhook: <BASE_URL>/cma-webhook服务在GET /上返回{"status":"ok"},可以确认端口监听正常。
第五步:安装 agent 并触发 @mention
- 浏览器访问
<url>/oauth/authorize,该路由会把浏览器重定向到https://linear.app/oauth/authorize(带response_type=code、scope=read,write,app:assignable,app:mentionable、actor=app)。批准后回调<url>/oauth/callback完成 code 交换,页面显示Agent installed in <org name>,表示 token 已按 org 落盘到.linear-tokens.json(生产环境 skill.md 建议换成正式的 secret store)。 - 在 Linear 的任意 issue 中 @mention 这个 app user,发一条消息。
预期现象:issue 下先出现 "Thinking…"(这是 10 秒规则的第一条 thought 活动),Claude 会话在 Anthropic 侧跑到 idle 后,/cma-webhook收到session.status_idled,桥从事件历史中提取所有agent.message文本,以type: "response"的createAgentActivity写回评论。如果会话异常终止(session.status_terminated),桥会写回一条type: "error"、内容为 "Agent session terminated unexpectedly." 的评论。
排查与验证
skill.md 给出了一张针对"静默失败"的排查表,按现象定位:
| 现象 | 检查项 |
|---|---|
| "Thinking…" 从未出现 | Linear webhook 没到达桥。检查 Linear 应用的 webhook URL,以及 ngrok 是否还在运行 |
| 有 "Thinking…" 但无回复 | 查curl localhost:4040/api/requests/http(ngrok 请求日志)。没有 POST 到/cma-webhook:Anthropic 侧 workspace 不匹配,或端点没保存成功;POST 到了但返回 401:signing key 不一致 |
| 回复内容为空 | sessions.events.list可能分页,事件多时需要迭代完所有页 |
还有两个容易踩的坑:
- 重试与幂等:Anthropic 会用同一个顶层
event.id重试失败的投递,src/cma-webhook.ts 用内存seenEventIdsSet 去重;处理完(或决定忽略)必须返回 2xx,否则触发重试,约 20 次连续失败会自动禁用端点。多实例部署时需把 Set 换成 Redis 或数据库。 - 签名头:文档写的是
X-Webhook-Signature,实际线路上传的是Webhook-Signature/Webhook-Id/Webhook-Timestamp(Standard Webhooks 规范)。SDK 的webhooks.unwrap()已处理,只有手工验签时才需要注意。
限制与生产化说明
skill.md 的 Production notes 列出的改动范围(作为后续可选步骤,非本文任务的必做项):
- 用真实部署(Cloudflare Workers、Fly 等)替换 ngrok,其余不变;
- 内存
seenEventIds换成 Redis/数据库以支持多实例幂等; .linear-tokens.json文件换成正式 secret store;- 把 Anthropic 端点的事件订阅收窄到只处理的事件类型;如果 workspace 与他人共享,考虑使用专用 workspace 避免无关 session 涌入。
更多细节(mental model、调试表)可直接阅读 skill.md 与 README。
【免费下载链接】claude-cookbooksA collection of notebooks/recipes showcasing some fun and effective ways of using Claude.项目地址: https://gitcode.com/GitHub_Trending/an/claude-cookbooks
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考