# Linear SDK — TypeScript Client for Linear Agents > Linear SDK is the official TypeScript client. GraphQL-typed methods cover every Linear API surface. Drop into Inngest or Trigger.dev for issue automation. ## Install Save as a script file and run: ## Quick Use 1. `npm install @linear/sdk` 2. Generate a personal API key in Linear → Settings → API 3. `const linear = new LinearClient({ apiKey })`, then call typed methods like `linear.issues({ filter: ... })` --- ## Intro The Linear SDK is the official TypeScript client wrapping Linear's GraphQL API. Every method is fully typed (Issue, Project, Cycle, Team, User), with built-in pagination and rate-limit handling. Best for: agents and bots that automate Linear beyond what MCP covers — bulk imports, complex queries, scheduled triage. Works with: Node 18+, Bun, Deno. Setup time: 2 minutes. --- ### Hello, Linear ```typescript import { LinearClient } from "@linear/sdk"; const linear = new LinearClient({ apiKey: process.env.LINEAR_API_KEY }); // Get my issues const me = await linear.viewer; const issues = await me.assignedIssues({ first: 50 }); for (const issue of issues.nodes) { console.log(`${issue.identifier} — ${issue.title} (${(await issue.state).name})`); } ``` ### Create an issue with all the trimmings ```typescript const team = await linear.team("ENG"); const issue = await linear.createIssue({ teamId: team.id, title: "Auth flow drops state on redirect", description: "**Steps to reproduce:**\n1. Login\n2. Click external link\n3. Click back\n\nState lost.", priority: 1, // Urgent assigneeId: (await linear.viewer).id, labelIds: [ (await team.labels()).nodes.find(l => l.name === "bug")?.id!, ], projectId: "your-project-id", }); console.log(`Created ${issue.issue?.identifier}`); ``` ### Bulk triage with rate-limit awareness ```typescript import pLimit from "p-limit"; const limit = pLimit(5); // 5 concurrent calls; SDK auto-retries on 429 const stale = await linear.issues({ filter: { state: { type: { eq: "started" } }, updatedAt: { lt: new Date(Date.now() - 14 * 86400_000) }, }, }); await Promise.all( stale.nodes.map(issue => limit(() => issue.update({ labelIds: [...issue.labelIds, STALE_LABEL_ID], }), ), ), ); ``` ### Webhook payloads (in tandem with SDK) ```typescript // Express handler app.post("/webhooks/linear", async (req, res) => { if (req.body.action === "create" && req.body.type === "Issue") { const issue = await linear.issue(req.body.data.id); if ((await issue.priority) === 1) { await notifySlack(`🔥 Urgent issue: ${issue.title}`); } } res.sendStatus(200); }); ``` --- ### FAQ **Q: SDK vs MCP — when to use which?** A: MCP for interactive agents (Claude Code asks Linear questions during a session). SDK for scheduled or webhook-driven automation (Inngest jobs, GitHub Actions, server-side bots). Many teams use both. **Q: Is the SDK rate-limit-aware?** A: Yes — built-in retry with exponential backoff on 429s. For high-throughput jobs, combine with p-limit (concurrency cap) and persist progress so you can resume. **Q: Does it support Linear's GraphQL directly?** A: Yes — every typed SDK method is just a wrapper over GraphQL. For queries the SDK doesn't expose, use `linear.client.rawRequest(query, variables)` to send arbitrary GraphQL. --- ## Source & Thanks > Built by [Linear](https://github.com/linear). MIT-licensed. > > [linear/linear-sdk](https://github.com/linear/linear) — ⭐ Active --- ## 快速使用 1. `npm install @linear/sdk` 2. 在 Linear → Settings → API 生成 personal API key 3. `const linear = new LinearClient({ apiKey })`,调类型化方法如 `linear.issues({ filter: ... })` --- ## 简介 Linear SDK 是官方 TypeScript 客户端,包装 Linear GraphQL API。每个方法完全类型化(Issue / Project / Cycle / Team / User),自带分页和限速处理。适合超出 MCP 能力的 Linear 自动化 agent 和 bot —— 批量导入、复杂查询、定时分诊。需要 Node 18+ / Bun / Deno。装机时间 2 分钟。 --- ### Hello, Linear ```typescript import { LinearClient } from "@linear/sdk"; const linear = new LinearClient({ apiKey: process.env.LINEAR_API_KEY }); // 拿我的 issue const me = await linear.viewer; const issues = await me.assignedIssues({ first: 50 }); for (const issue of issues.nodes) { console.log(`${issue.identifier} — ${issue.title} (${(await issue.state).name})`); } ``` ### 创建带完整字段的 issue ```typescript const team = await linear.team("ENG"); const issue = await linear.createIssue({ teamId: team.id, title: "Auth flow drops state on redirect", description: "**Steps to reproduce:**\n1. Login\n2. Click external link\n3. Click back\n\nState lost.", priority: 1, // 紧急 assigneeId: (await linear.viewer).id, labelIds: [ (await team.labels()).nodes.find(l => l.name === "bug")?.id!, ], projectId: "your-project-id", }); console.log(`Created ${issue.issue?.identifier}`); ``` ### 批量分诊带限速感知 ```typescript import pLimit from "p-limit"; const limit = pLimit(5); // 5 并发,SDK 在 429 时自动重试 const stale = await linear.issues({ filter: { state: { type: { eq: "started" } }, updatedAt: { lt: new Date(Date.now() - 14 * 86400_000) }, }, }); await Promise.all( stale.nodes.map(issue => limit(() => issue.update({ labelIds: [...issue.labelIds, STALE_LABEL_ID], }), ), ), ); ``` ### Webhook payload 配 SDK ```typescript // Express handler app.post("/webhooks/linear", async (req, res) => { if (req.body.action === "create" && req.body.type === "Issue") { const issue = await linear.issue(req.body.data.id); if ((await issue.priority) === 1) { await notifySlack(`🔥 Urgent issue: ${issue.title}`); } } res.sendStatus(200); }); ``` --- ### FAQ **Q: SDK 和 MCP 怎么选?** A: 交互式 agent 用 MCP(Claude Code 在会话里问 Linear 问题)。定时或 webhook 驱动的自动化用 SDK(Inngest 任务、GitHub Action、服务端 bot)。很多团队两个都用。 **Q: SDK 限速感知吗?** A: 感知 —— 内置 429 上的指数退避重试。高吞吐任务配 p-limit(并发上限)+ 持久化进度便于恢复。 **Q: 能直接用 Linear GraphQL 吗?** A: 能 —— 类型化 SDK 方法只是 GraphQL 包装。SDK 没暴露的查询用 `linear.client.rawRequest(query, variables)` 发任意 GraphQL。 --- ## 来源与感谢 > Built by [Linear](https://github.com/linear). MIT-licensed. > > [linear/linear-sdk](https://github.com/linear/linear) — ⭐ Active --- Source: https://tokrepo.com/en/workflows/linear-sdk-typescript-client-for-linear-agents Author: Linear