> **Building with AI coding agents?** If you're using an AI coding agent, install the official Scalekit plugin. It gives your agent full awareness of the Scalekit API — reducing hallucinations and enabling faster, more accurate code generation.
>
> - **Claude Code**: `/plugin marketplace add scalekit-inc/claude-code-authstack` then `/plugin install <auth-type>@scalekit-auth-stack`
> - **GitHub Copilot CLI**: `copilot plugin marketplace add scalekit-inc/github-copilot-authstack` then `copilot plugin install <auth-type>@scalekit-auth-stack`
> - **Codex**: run the bash installer, restart, then open Plugin Directory and enable `<auth-type>`
> - **Skills CLI** (Windsurf, Cline, 40+ agents): `npx skills add scalekit-inc/skills --list` then `--skill <skill-name>`
>
> `<auth-type>` / `<skill-name>`: `agentkit`, `full-stack-auth`, `mcp-auth`, `modular-sso`, `modular-scim` — [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Linear

**Authentication:** OAuth 2.0
**Categories:** Developer Tools, Project Management
## What you can do

Connect this agent connector to let your agent:

- **Read issues** — fetch issues, projects, cycles, and team details
- **Create and update issues** — file new issues, update status, set priority, and assign teammates
- **Manage projects** — create and update project metadata and milestones
- **Search** — find issues by keyword, assignee, label, or state

## Authentication

This connector uses **OAuth 2.0**. Scalekit acts as the OAuth client: it redirects your user to Linear, obtains an access token, and automatically refreshes it before it expires. Your agent code never handles tokens directly — you only pass a `connectionName` and a user `identifier`.

You supply your Linear **Connected App** credentials (Client ID + Secret) once per environment in the Scalekit dashboard.

Before calling this connector from your code, create the Linear connection in **AgentKit** > **Connections** and copy the exact **Connection name** from that connection into your code. The value in code must match the dashboard exactly.

## Set up the connector

Register your Scalekit environment with the Linear connector so Scalekit handles the authentication flow and token lifecycle for you. The connection name you create will be used to identify and invoke the connection programmatically. Then complete the configuration in your application as follows:

1. ### Set up auth redirects

    - In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections** > **Create Connection**. Find **Linear** and click **Create**. Copy the redirect URI. It looks like `https:///sso/v1/oauth//callback`.

      > Image: Copy redirect URI from Scalekit dashboard

    - Log in to [Linear](https://linear.app) and go to **Settings** → **API** → **OAuth applications**.

    - Click **New application**, enter an application name and description, then paste the redirect URI from Scalekit into the **Callback URLs** field. Click **Create application**.

      > Image: Create OAuth application in Linear

2. ### Get client credentials

    - In your Linear OAuth application, copy the **Client ID** and **Client Secret**.

3. ### Add credentials in Scalekit

    - In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections** and open the connection you created.

    - Enter your credentials:
      - Client ID (from above)
      - Client Secret (from above)
      - Permissions (scopes — see [Linear OAuth scopes reference](https://developers.linear.app/docs/oauth/authentication#oauth-2.0-scopes))

      > Image: Add credentials in Scalekit dashboard
    - Click **Save**.

## Code examples

Connect a user's Linear account and make API calls on their behalf — Scalekit handles OAuth and token management automatically.

## Proxy API Calls

  ### Node.js

```typescript

const connectionName = 'linear'; // get your connection name from connection configurations
const identifier = 'user_123';   // your unique user identifier

// Get your credentials from app.scalekit.com → Developers → Settings → API Credentials
const scalekit = new ScalekitClient(
  process.env.SCALEKIT_ENV_URL,
  process.env.SCALEKIT_CLIENT_ID,
  process.env.SCALEKIT_CLIENT_SECRET
);
const actions = scalekit.actions;

// Authenticate the user
const { link } = await actions.getAuthorizationLink({
  connectionName,
  identifier,
});
console.log('🔗 Authorize Linear:', link);
process.stdout.write('Press Enter after authorizing...');
await new Promise(r => process.stdin.once('data', r));

// Make a GraphQL request via Scalekit proxy
const result = await actions.request({
  connectionName,
  identifier,
  path: '/graphql',
  method: 'POST',
  body: JSON.stringify({ query: '{ viewer { id name email } }' }),
});
console.log(result);
```

  ### Python

```python

from dotenv import load_dotenv
load_dotenv()

connection_name = "linear"   # get your connection name from connection configurations
identifier = "user_123"      # your unique user identifier

# Get your credentials from app.scalekit.com → Developers → Settings → API Credentials
scalekit_client = scalekit.client.ScalekitClient(
    client_id=os.getenv("SCALEKIT_CLIENT_ID"),
    client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
    env_url=os.getenv("SCALEKIT_ENV_URL"),
)
actions = scalekit_client.actions

# Authenticate the user
link_response = actions.get_authorization_link(
    connection_name=connection_name,
    identifier=identifier
)
# present this link to your user for authorization, or click it yourself for testing
print("🔗 Authorize Linear:", link_response.link)
input("Press Enter after authorizing...")

# Make a GraphQL request via Scalekit proxy
result = actions.request(
    connection_name=connection_name,
    identifier=identifier,
    path="/graphql",
    method="POST",
    body=json.dumps({"query": "{ viewer { id name email } }"})
)
print(result)
```

## Tool list

Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you're not sure which name to use, list the tools available for the current user first.

## Tool list

### `linear_graphql_query`

Execute a custom GraphQL query or mutation against the Linear API. Allows running any valid GraphQL operation with variables support for advanced use cases.

Parameters:

- `query` (`string`, required): The GraphQL query or mutation to execute
- `variables` (`object`, optional): Variables to pass to the GraphQL query

### `linear_issue_create`

Create a new issue in Linear using the issueCreate mutation. Requires a team ID and title at minimum.

Parameters:

- `teamId` (`string`, required): ID of the team to create the issue in
- `title` (`string`, required): Title of the issue
- `assigneeId` (`string`, optional): ID of the user to assign the issue to
- `description` (`string`, optional): Description of the issue
- `estimate` (`string`, optional): Story point estimate for the issue
- `labelIds` (`array`, optional): Array of label IDs to apply to the issue
- `priority` (`string`, optional): Priority level of the issue (1-4, where 1 is urgent)
- `projectId` (`string`, optional): ID of the project to associate the issue with
- `stateId` (`string`, optional): ID of the workflow state to set

### `linear_issue_update`

Update an existing issue in Linear. You can update title, description, priority, state, and assignee.

Parameters:

- `issueId` (`string`, required): ID of the issue to update
- `assigneeId` (`string`, optional): ID of the user to assign the issue to
- `description` (`string`, optional): New description for the issue
- `priority` (`string`, optional): Priority level of the issue (1-4, where 1 is urgent)
- `stateId` (`string`, optional): ID of the workflow state to set
- `title` (`string`, optional): New title for the issue

### `linear_issues_list`

List issues in Linear using the issues query with simple filtering and pagination support.

Parameters:

- `after` (`string`, optional): Cursor for pagination (returns issues after this cursor)
- `assignee` (`string`, optional): Filter by assignee email (e.g., 'user@example.com')
- `before` (`string`, optional): Cursor for pagination (returns issues before this cursor)
- `first` (`integer`, optional): Number of issues to return (pagination)
- `labels` (`array`, optional): Filter by label names (array of strings)
- `priority` (`string`, optional): Filter by priority level (1=Urgent, 2=High, 3=Medium, 4=Low)
- `project` (`string`, optional): Filter by project name (e.g., 'Q4 Goals')
- `state` (`string`, optional): Filter by state name (e.g., 'In Progress', 'Done')


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
