Skip to content
OpenSmartRoute
Skillv1.0.0

linear-install-auth

Install and configure Linear SDK/CLI authentication. Use when setting up a new Linear integration, configuring API keys, OAuth2 flows, or initializing LinearClient in your project. Trigger: "install l

by jeremylongshore(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from jeremylongshore/tons-of-skills-marketplace (plugins/saas-packs/linear-pack/skills/linear-install-auth/SKILL.md). Install upstream with npx skills add jeremylongshore/tons-of-skills-marketplace --skill linear-install-auth. Copyright stays with the author (MIT).

Linear Install & Auth

Overview

Install the @linear/sdk TypeScript SDK and configure authentication for the Linear GraphQL API at https://api.linear.app/graphql. Supports personal API keys for scripts and OAuth 2.0 (with PKCE) for user-facing apps.

Prerequisites

  • Node.js 18+ (SDK is TypeScript-first, works in any JS environment)
  • Package manager (npm, pnpm, or yarn)
  • Linear account with workspace access
  • For API key: Settings > Account > API > Personal API keys
  • For OAuth: Create app at Settings > Account > API > OAuth applications

Instructions

Step 1: Install the SDK

set -euo pipefail
npm install @linear/sdk
# or: pnpm add @linear/sdk
# or: yarn add @linear/sdk

The SDK exposes LinearClient, typed models for every entity (Issue, Project, Cycle, Team), and error classes (LinearError, InvalidInputLinearError).

Step 2: API Key Authentication (Scripts & Server-Side)

Generate a Personal API key at Linear Settings > Account > API > Personal API keys. Keys start with lin_api_ and are shown only once.

import { LinearClient } from "@linear/sdk";

// Environment variable (recommended)
const client = new LinearClient({
  apiKey: process.env.LINEAR_API_KEY,
});

// Verify connection
const me = await client.viewer;
console.log(`Authenticated as: ${me.name} (${me.email})`);

Environment setup:

# .env (never commit)
LINEAR_API_KEY=lin_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

# .gitignore
echo '.env' >> .gitignore

Step 3: OAuth 2.0 Authentication (User-Facing Apps)

Linear supports the standard Authorization Code flow with optional PKCE. As of October 2025, newly created OAuth apps issue refresh tokens by default.

import crypto from "crypto";

// 1. Build authorization URL
const SCOPES = ["read", "write", "issues:create"];
const state = crypto.randomBytes(16).toString("hex");

const authUrl = new URL("https://linear.app/oauth/authorize");
authUrl.searchParams.set("client_id", process.env.LINEAR_CLIENT_ID!);
authUrl.searchParams.set("redirect_uri", process.env.LINEAR_REDIRECT_URI!);
authUrl.searchParams.set("response_type", "code");
authUrl.searchParams.set("scope", SCOPES.join(","));
authUrl.searchParams.set("state", state);
// Optional PKCE:
// authUrl.searchParams.set("code_challenge", challenge);
// authUrl.searchParams.set("code_challenge_method", "S256");

// 2. Exchange authorization code for tokens
const tokenResponse = await fetch("https://api.linear.app/oauth/token", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: new URLSearchParams({
    grant_type: "authorization_code",
    code: authorizationCode,
    client_id: process.env.LINEAR_CLIENT_ID!,
    client_secret: process.env.LINEAR_CLIENT_SECRET!,
    redirect_uri: process.env.LINEAR_REDIRECT_URI!,
  }),
});

const { access_token, refresh_token, expires_in } = await tokenResponse.json();

// 3. Create client with OAuth token
const client = new LinearClient({ accessToken: access_token });

Available OAuth scopes: read, write, issues:create, admin, initiative:read, initiative:write, customer:read, customer:write.

Step 4: Token Refresh (OAuth)

async function refreshAccessToken(refreshToken: string): Promise<string> {
  const response = await fetch("https://api.linear.app/oauth/token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "refresh_token",
      refresh_token: refreshToken,
      client_id: process.env.LINEAR_CLIENT_ID!,
      client_secret: process.env.LINEAR_CLIENT_SECRET!,
    }),
  });

  if (!response.ok) {
    throw new Error(`Token refresh failed: ${response.status}`);
  }

  const tokens = await response.json();
  // Store new refresh_token — Linear rotates it on each refresh
  await saveTokens(tokens.access_token, tokens.refresh_token);
  return tokens.access_token;
}

Step 5: Validate Configuration on Startup

function validateLinearConfig(): void {
  const key = process.env.LINEAR_API_KEY;
  if (!key) throw new Error("LINEAR_API_KEY environment variable is required");
  if (!key.startsWith("lin_api_")) throw new Error("LINEAR_API_KEY must start with lin_api_");
  if (key.length < 30) throw new Error("LINEAR_API_KEY appears truncated");
}

// Call before creating client
validateLinearConfig();

Error Handling

Error Cause Solution
Authentication required Invalid, expired, or missing API key Regenerate at Settings > Account > API
Invalid API key format Key doesn't start with lin_api_ Copy full key from Linear (shown once)
Forbidden Token lacks required OAuth scope Re-authorize with correct scopes
invalid_grant on token exchange Code expired or PKCE verifier mismatch Restart OAuth flow; codes expire quickly
Module not found: @linear/sdk SDK not installed Run npm install @linear/sdk
ENOTFOUND api.linear.app DNS/firewall issue Ensure outbound HTTPS to api.linear.app

Examples

Raw GraphQL Without SDK

const response = await fetch("https://api.linear.app/graphql", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": process.env.LINEAR_API_KEY!,
  },
  body: JSON.stringify({
    query: `{ viewer { id name email } }`,
  }),
});

const { data, errors } = await response.json();
if (errors) console.error("GraphQL errors:", errors);
else console.log("Viewer:", data.viewer);

Server-to-Server (Client Credentials)

// For apps without user interaction — uses client_credentials grant
const response = await fetch("https://api.linear.app/oauth/token", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: new URLSearchParams({
    grant_type: "client_credentials",
    client_id: process.env.LINEAR_CLIENT_ID!,
    client_secret: process.env.LINEAR_CLIENT_SECRET!,
    scope: "read,write",
  }),
});

const { access_token } = await response.json();
const client = new LinearClient({ accessToken: access_token });

Resources

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/jeremylongshore-tons-of-skills-marketplace-linear-install-auth/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

jeremylongshore-tons-of-skills-marketplace-linear-install-auth.ocm.jsonjson
{
  "ocm": "1",
  "id": "jeremylongshore-tons-of-skills-marketplace-linear-install-auth",
  "kind": "skill",
  "name": "linear-install-auth",
  "description": "Install and configure Linear SDK/CLI authentication. Use when setting up a new Linear integration, configuring API keys, OAuth2 flows, or initializing LinearClient in your project. Trigger: \"install linear\", \"setup linear\", \"linear auth\", \"configure linear API key\", \"linear SDK setup\", \"linear OAuth\".",
  "publisher": "jeremylongshore",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "coding"
    ],
    "tags": [
      "skill-md",
      "saas",
      "linear",
      "api",
      "authentication",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Install and configure Linear SDK/CLI authentication. Use when setting up a new Linear integration, configuring API keys, OAuth2 flows, or initializing LinearClient in your project. Trigger: \"install linear\", \"setup linear\", \"linear auth\", \"configure linear API key\", \"linear SDK setup\", \"linear OAuth\"."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/jeremylongshore/tons-of-skills-marketplace",
      "path": "plugins/saas-packs/linear-pack/skills/linear-install-auth/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/jeremylongshore/tons-of-skills-marketplace/blob/HEAD/plugins/saas-packs/linear-pack/skills/linear-install-auth/SKILL.md",
      "key": "jeremylongshore/tons-of-skills-marketplace/plugins/saas-packs/linear-pack/skills/linear-install-auth/SKILL.md"
    },
    "compatibility": "Designed for Claude Code",
    "allowed_tools": [
      "Read,",
      "Write,",
      "Edit,",
      "Bash(npm:*),",
      "Bash(pnpm:*),",
      "Bash(yarn:*),",
      "Grep"
    ],
    "license": "MIT"
  },
  "instructions": "# Linear Install & Auth\n\n## Overview\n\nInstall the `@linear/sdk` TypeScript SDK and configure authentication for the Linear GraphQL API at `https://api.linear.app/graphql`. Supports personal API keys for scripts and OAuth 2.0 (with PKCE) for user-facing apps.\n\n## Prerequisites\n\n- Node.js 18+ (SDK is TypeScript-first, works in any JS environment)\n- Package manager (npm, pnpm, or yarn)\n- Linear account with workspace access\n- For API key: Settings > Account > API > Personal API keys\n- For OAuth: Create app at Settings > Account > API > OAuth applications\n\n## Instructions\n\n### Step 1: Install the ",
  "cost": {
    "context_tokens": 1640
  }
}

Fetch it by URL: GET /api/v1/registry/jeremylongshore-tons-of-skills-marketplace-linear-install-auth/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.