Looking for the chatbot template? It's now here.
GitHub

@chat-adapter/linear

Linear adapter for Chat SDK. Respond to @mentions in issue comment threads.

The Linear adapter treats issue comments as messages and issues as threads.

Installation

bash
pnpm add @chat-adapter/linear

Usage

The adapter auto-detects credentials from LINEAR_API_KEY (or LINEAR_CLIENT_ID/LINEAR_CLIENT_SECRET), LINEAR_WEBHOOK_SECRET, and LINEAR_BOT_USERNAME environment variables:

typescript
import { Chat } from "chat";import { createLinearAdapter } from "@chat-adapter/linear";const bot = new Chat({  userName: "my-bot",  adapters: {    linear: createLinearAdapter(),  },});bot.onNewMention(async (thread, message) => {  await thread.post("Hello from Linear!");});

Authentication

Option A: Personal API key

Best for personal projects, testing, or single-workspace bots. Actions are attributed to you as an individual.

  1. Go to Settings > Security & Access
  2. Under Personal API keys, click Create key
  3. Select Only select permissions and enable Create issues, Create comments
  4. Choose team access
  5. Click Create and set LINEAR_API_KEY
typescript
createLinearAdapter({  apiKey: process.env.LINEAR_API_KEY!,});

Option B: OAuth application (recommended)

The bot gets its own identity in Linear. The adapter handles token management internally.

  1. Go to Settings > API > Applications
  2. Create an OAuth2 application with your bot's name and icon
  3. Enable client credentials tokens in the app settings
  4. Note the Client ID and Client Secret
typescript
createLinearAdapter({  clientId: process.env.LINEAR_CLIENT_ID!,  clientSecret: process.env.LINEAR_CLIENT_SECRET!,});

The adapter uses the client credentials grant to obtain tokens automatically. Tokens are valid for 30 days and auto-refresh when expired.

Making the bot @-mentionable (optional)

To make the bot appear in Linear's @ mention dropdown as an Agent:

  1. In your OAuth app settings, enable Agent session events under webhooks
  2. Have a workspace admin install the app with actor=app and the app:mentionable scope:
https://linear.app/oauth/authorize?  client_id=your_client_id&  redirect_uri=https://your-domain.com/callback&  response_type=code&  scope=read,write,comments:create,app:mentionable&  actor=app

See the Linear Agents docs for full details.

Webhook setup

Note: Webhook management requires workspace admin access. If you don't see the API settings page, ask a workspace admin to create the webhook for you.

  1. Go to Settings > API and click Create webhook
  2. Fill in:
    • Label: A descriptive name (e.g., "Chat Bot")
    • URL: https://your-domain.com/api/webhooks/linear
  3. Copy the Signing secret as LINEAR_WEBHOOK_SECRET
  4. Under Data change events, select:
    • Comments (required)
    • Issues (recommended)
    • Emoji reactions (optional)
  5. Under Team selection, choose All public teams or a specific team
  6. Click Create webhook

Thread model

Linear has two levels of comment threading:

TypeDescriptionThread ID format
Issue-levelTop-level comments on an issuelinear:{issueId}
Comment threadReplies nested under a specific commentlinear:{issueId}:c:{commentId}

When a user writes a comment, the bot replies within the same comment thread.

Reactions

SDK emojiLinear emoji
thumbs_upthumbs_up
thumbs_downthumbs_down
heartheart
firefire
rocketrocket
eyeseyes
sparklessparkles
wavewave

Configuration

All options are auto-detected from environment variables when not provided.

OptionRequiredDescription
apiKeyNo*Personal API key. Auto-detected from LINEAR_API_KEY
clientIdNo*OAuth app client ID. Auto-detected from LINEAR_CLIENT_ID
clientSecretNo*OAuth app client secret. Auto-detected from LINEAR_CLIENT_SECRET
accessTokenNo*Pre-obtained OAuth access token. Auto-detected from LINEAR_ACCESS_TOKEN
webhookSecretNo**Webhook signing secret. Auto-detected from LINEAR_WEBHOOK_SECRET
userNameNoBot display name. Auto-detected from LINEAR_BOT_USERNAME (default: "linear-bot")
loggerNoLogger instance (defaults to ConsoleLogger("info"))

*One of apiKey, clientId/clientSecret, or accessToken is required (via config or env vars).

**webhookSecret is required — either via config or LINEAR_WEBHOOK_SECRET env var.

Environment variables

bash
# API Key authLINEAR_API_KEY=lin_api_xxxxxxxxxxxx# OR OAuth app authLINEAR_CLIENT_ID=your-client-idLINEAR_CLIENT_SECRET=your-client-secret# RequiredLINEAR_WEBHOOK_SECRET=your-webhook-secret

Features

Messaging

FeatureSupported
Post messageYes
Edit messageYes
Delete messageYes
File uploadsNo
StreamingNo

Rich content

FeatureSupported
Card formatMarkdown
ButtonsNo
Link buttonsNo
Select menusNo
TablesGFM
FieldsYes
Images in cardsNo
ModalsNo

Conversations

FeatureSupported
Slash commandsNo
MentionsYes
Add reactionsYes
Remove reactionsPartial
Typing indicatorNo
DMsNo
Ephemeral messagesNo

Message history

FeatureSupported
Fetch messagesYes
Fetch single messageNo
Fetch thread infoYes
Fetch channel messagesNo
List threadsNo
Fetch channel infoNo
Post channel messageNo

Limitations

  • No typing indicators — Linear doesn't support typing indicators
  • No streaming — Messages posted in full (editing supported for updates)
  • No DMs — Linear doesn't have direct messages
  • No modals — Linear doesn't support interactive modals
  • Action buttons — Rendered as text; use link buttons for clickable actions
  • Remove reaction — Requires reaction ID lookup (not directly supported)

Troubleshooting

"Invalid signature" error

  • Verify LINEAR_WEBHOOK_SECRET matches the secret from your webhook configuration
  • The webhook secret is shown only once at creation — regenerate if lost

Bot not responding to mentions

  • Verify webhook events are configured with Comments resource type
  • Check that the webhook URL is correct and accessible
  • Ensure the userName config matches how users mention the bot
  • Linear may auto-disable webhooks after repeated failures

"Webhook expired" error

  • Webhook timestamp is too old (> 5 minutes)
  • Usually indicates a delivery delay or clock skew
  • Check that your server time is synchronized

License

MIT