# @kody/linear ## Intent Provide reusable, account-agnostic Linear helpers so Kody agents can read and update issues, projects, teams, comments, and workflow states through a saved `linear` / `linear-*` OAuth integration or a personal API key — without hand-rolling GraphQL. Mutations are previewable with `dryRun: true` and only run live after `confirm: true`. This listing is meant to be forked. After you fork, connect **your** Linear workspace. Do not treat the live `@kody/linear` package storage as yours. This official OAuth/API-key package is the **preferred** invoke path. Setup is harder: bring your own Linear OAuth app or personal API key. For a faster first win, connect Linear MCP in Get started and use [`@kody/linear-mcp`](https://kody.codes/@kody/linear-mcp). ## What it does - List or inspect teams, projects, issues, comments, and workflow states - Create or update issues, comments, and projects after explicit confirmation - Call an unwrapped Linear GraphQL operation through `./request` - Connect more than one Linear workspace via `integrationName` / `account` ## Prerequisites / setup Linear has **no built-in Kody OAuth app**. Choose one lane: | Lane | When to use | Credential | | --- | --- | --- | | **OAuth** (recommended) | Multi-account, refresh tokens, shared helpers | Saved integration `linear` or `linear-` | | **Personal API key** | Fastest for a single workspace / personal scripts | User secret `linearApiKey` (or `linearApiKey-`) | OAuth access tokens use `Authorization: Bearer …`. Personal API keys must be sent as `Authorization: ` **without** the Bearer prefix — this package handles that. Required API host: **`api.linear.app`**. Approve it in the account secrets UI. ### Lane A — BYO OAuth 1. Create an OAuth application at https://linear.app/settings/api/applications/new 2. Set the redirect URI **exactly** to `https://kody.codes/connect/oauth` 3. Request scopes `read,write` (comma-separated; `read` is always present). Narrower mutation-only scopes: `issues:create`, `comments:create`. 4. Connect while signed in to Kody: https://kody.codes/connect/oauth?provider=linear&authorizeUrl=https%3A%2F%2Flinear.app%2Foauth%2Fauthorize&tokenUrl=https%3A%2F%2Fapi.linear.app%2Foauth%2Ftoken&apiBaseUrl=https%3A%2F%2Fapi.linear.app&scopes=read%2Cwrite&scopeSeparator=%2C&flow=confidential&allowedHosts=api.linear.app&dashboardUrl=https%3A%2F%2Flinear.app%2Fsettings%2Fapi%2Fapplications%2Fnew 5. Paste the Linear client id and client secret into the Kody wizard (never into chat). Approve host `api.linear.app`. 6. Reconnect later with https://kody.codes/connect/oauth?provider=linear OAuth token URL: `https://api.linear.app/oauth/token`. Authorize URL: `https://linear.app/oauth/authorize`. Flow: confidential (client secret). Linear scopes are **comma-separated** (`scopeSeparator=,`). To connect a second workspace, change `provider` (for example `provider=linear-work`) and pass `integrationName: 'linear-work'` on every call. Add `prompt=consent` on Linear's authorize screen if you need to pick a different workspace for the same app. ### Lane B — Personal API key 1. Create a key at https://linear.app/settings/account/security 2. Grant **Read** plus the write permissions you need (`Write`, or `Create issues` / `Create comments`). 3. Save it (do not paste the value in chat): https://kody.codes/account/secrets/new?name=linearApiKey&description=Linear%20personal%20API%20key&allowedHosts=api.linear.app&scope=user For a second workspace/key, use a distinct secret name such as `linearApiKey-work` and pass `secretName: 'linearApiKey-work'` (or `account: 'work'`, which resolves to `linear-work` / `linearApiKey-work`). ### Scopes | Scope | Needed for | | --- | --- | | `read` | All queries (viewer, teams, projects, issues, comments, workflow states) | | `issues:create` | `./create-issue` | | `comments:create` | `./create-comment` | | `write` | `./update-issue`, `./create-project`, other mutations | | `admin` | Do not request unless a workflow truly needs admin endpoints | Agents: see [`AGENTS.md`](./AGENTS.md) for import paths, smoke checks, and mutation guards. ## Done when - OAuth `linear` is connected or `linearApiKey` is saved; host `api.linear.app` is approved - Smoke test returns `ok: true` (live viewer id when credentials exist; no email) - Mutating helpers refuse unless `confirm: true`; `dryRun: true` never calls Linear ## Branding The community icon is Linear's official logomark as served by Linear (`https://static.linear.app/client/assets/favicon-D8hcELd9.svg`), scaled to a square. Paths are unmodified. Linear® is a trademark of Linear Orbit, Inc. This package is not affiliated with or endorsed by Linear Orbit, Inc. ## Docs - [Linear GraphQL API](https://linear.app/developers/graphql) - [OAuth 2.0](https://linear.app/developers/oauth-2-0-authentication) - [Personal API keys](https://linear.app/settings/account/security)