> ## Documentation Index
> Fetch the complete documentation index at: https://docs.modulex.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Linear Integration for AI Agents & Workflows

> Modern project management and issue tracking tool for software teams. Streamline workflows, track bugs, and coordinate tasks with powerful search, filtering, and automation capabilities.

{/* Self-hosted logo — build-time vendored from modulex.json / Iconify (see scripts/lib/logo.js). */}

<img className="block dark:hidden" src="https://mintcdn.com/modulexaillc/df8MOr-hXotYLTh5/logos/linear-light.svg?fit=max&auto=format&n=df8MOr-hXotYLTh5&q=85&s=b34bc8a0890710096ddc37339a9fdf3c" alt="Linear logo" width="72" height="72" data-path="logos/linear-light.svg" />

<img className="hidden dark:block" src="https://mintcdn.com/modulexaillc/df8MOr-hXotYLTh5/logos/linear-dark.svg?fit=max&auto=format&n=df8MOr-hXotYLTh5&q=85&s=bc10bf292c7bde9ff73c181ccaa9aed6" alt="Linear logo" width="72" height="72" data-path="logos/linear-dark.svg" />

## Overview

Add **Linear** to any ModuleX agent or workflow. Project-management and issue-tracking integration for Linear via the **GraphQL API** at `api.linear.app/graphql`. Covers team discovery, issue CRUD + search, and project list/create.

<Info>
  **Categories**: Project & Task Management · Task Management · Collaboration · **Auth**: OAuth2, API Key · **Actions**: 7
</Info>

## Authentication

<Tabs>
  <Tab title="OAuth2">
    ### OAuth2 Authentication

    Connect using Linear OAuth (recommended for most use cases)

    #### Required Credentials

    | Field         | Description                            | Required | Format                                                             |
    | ------------- | -------------------------------------- | -------- | ------------------------------------------------------------------ |
    | Client ID     | Linear OAuth application Client ID     | Yes      | `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`                                 |
    | Client Secret | Linear OAuth application Client Secret | Yes      | `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` |

    #### OAuth Configuration

    * **Authorization URL**: `https://linear.app/oauth/authorize`
    * **Token URL**: `https://api.linear.app/oauth/token`
    * **Scopes**: `read`, `write`
  </Tab>

  <Tab title="API Key">
    ### API Key Authentication

    Authenticate using your Linear API key. Generate one from Linear Settings > API > Personal API keys.

    #### Required Credentials

    | Field          | Description                                     | Required | Format                                     |
    | -------------- | ----------------------------------------------- | -------- | ------------------------------------------ |
    | Linear API Key | Your Linear personal API key for authentication | Yes      | `lin_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` |
  </Tab>
</Tabs>

## Available Actions

<AccordionGroup>
  <Accordion title="get_teams — Retrieve all teams in your Linear workspace. Use this to discover available teams before creating issues or projects.">
    ### Parameters

    <ResponseField name="limit" type="integer">
      Maximum number of teams to return (Default: `50`)
    </ResponseField>

    <ResponseField name="after" type="string">
      Cursor for pagination
    </ResponseField>

    ### Response

    ```json theme={null}
    {
      "additionalProperties": false,
      "properties": {
        "success": {
          "title": "Success",
          "type": "boolean"
        },
        "error": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Error"
        },
        "count": {
          "default": 0,
          "title": "Count",
          "type": "integer"
        },
        "page_info": {
          "anyOf": [
            {
              "additionalProperties": true,
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Page Info"
        },
        "teams": {
          "items": {
            "additionalProperties": true,
            "type": "object"
          },
          "title": "Teams",
          "type": "array"
        }
      },
      "required": [
        "success"
      ],
      "title": "GetTeamsOutput",
      "type": "object"
    }
    ```
  </Accordion>

  <Accordion title="get_issue — Retrieve a Linear issue by its ID. Returns title, description, state, assignee, team, project, labels, and timestamps.">
    ### Parameters

    <ResponseField name="issue_id" type="string" required>
      The ID of the issue to retrieve
    </ResponseField>

    ### Response

    ```json theme={null}
    {
      "additionalProperties": false,
      "properties": {
        "success": {
          "title": "Success",
          "type": "boolean"
        },
        "error": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Error"
        },
        "issue": {
          "anyOf": [
            {
              "additionalProperties": true,
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Issue"
        }
      },
      "required": [
        "success"
      ],
      "title": "GetIssueOutput",
      "type": "object"
    }
    ```
  </Accordion>

  <Accordion title="search_issues — Search Linear issues by team, project, assignee, labels, state, or text query.">
    ### Parameters

    <ResponseField name="team_id" type="string">
      Filter by team ID
    </ResponseField>

    <ResponseField name="project_id" type="string">
      Filter by project ID
    </ResponseField>

    <ResponseField name="assignee_id" type="string">
      Filter by assignee user ID
    </ResponseField>

    <ResponseField name="state_id" type="string">
      Filter by workflow state ID
    </ResponseField>

    <ResponseField name="query" type="string">
      Substring to match in issue titles
    </ResponseField>

    <ResponseField name="label_names" type="array">
      Filter by label names
    </ResponseField>

    <ResponseField name="include_archived" type="boolean">
      Include archived issues (Default: `false`)
    </ResponseField>

    <ResponseField name="order_by" type="string">
      Field to order by ('createdAt' or 'updatedAt') (Default: `updatedAt`)
    </ResponseField>

    <ResponseField name="limit" type="integer">
      Maximum number of issues to return (Default: `50`)
    </ResponseField>

    ### Response

    ```json theme={null}
    {
      "additionalProperties": false,
      "properties": {
        "success": {
          "title": "Success",
          "type": "boolean"
        },
        "error": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Error"
        },
        "count": {
          "default": 0,
          "title": "Count",
          "type": "integer"
        },
        "page_info": {
          "anyOf": [
            {
              "additionalProperties": true,
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Page Info"
        },
        "issues": {
          "items": {
            "additionalProperties": true,
            "type": "object"
          },
          "title": "Issues",
          "type": "array"
        }
      },
      "required": [
        "success"
      ],
      "title": "SearchIssuesOutput",
      "type": "object"
    }
    ```
  </Accordion>

  <Accordion title="create_issue — Create a new issue in Linear.">
    ### Parameters

    <ResponseField name="team_id" type="string" required>
      The team's UUID (the 'id' field returned by get\_teams) — NOT the short team key like 'ENG'. Call get\_teams first to resolve it.
    </ResponseField>

    <ResponseField name="title" type="string" required>
      The title of the issue
    </ResponseField>

    <ResponseField name="description" type="string">
      Markdown description
    </ResponseField>

    <ResponseField name="assignee_id" type="string">
      UUID of the user to assign the issue to
    </ResponseField>

    <ResponseField name="project_id" type="string">
      UUID of the project to add the issue to
    </ResponseField>

    <ResponseField name="state_id" type="string">
      UUID of the workflow state
    </ResponseField>

    <ResponseField name="label_ids" type="array">
      Label UUIDs to attach
    </ResponseField>

    <ResponseField name="priority" type="integer">
      Priority level: 0=No priority, 1=Urgent, 2=High, 3=Normal, 4=Low
    </ResponseField>

    ### Response

    ```json theme={null}
    {
      "additionalProperties": false,
      "properties": {
        "success": {
          "title": "Success",
          "type": "boolean"
        },
        "error": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Error"
        },
        "issue": {
          "anyOf": [
            {
              "additionalProperties": true,
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Issue"
        }
      },
      "required": [
        "success"
      ],
      "title": "CreateIssueOutput",
      "type": "object"
    }
    ```
  </Accordion>

  <Accordion title="update_issue — Update an existing Linear issue.">
    ### Parameters

    <ResponseField name="issue_id" type="string" required>
      The ID of the issue to update
    </ResponseField>

    <ResponseField name="title" type="string">
      New title
    </ResponseField>

    <ResponseField name="description" type="string">
      New markdown description
    </ResponseField>

    <ResponseField name="assignee_id" type="string">
      New assignee user ID
    </ResponseField>

    <ResponseField name="team_id" type="string">
      Move to a different team
    </ResponseField>

    <ResponseField name="project_id" type="string">
      Move to a different project
    </ResponseField>

    <ResponseField name="state_id" type="string">
      Change workflow state
    </ResponseField>

    <ResponseField name="label_ids" type="array">
      Replace labels with these IDs
    </ResponseField>

    <ResponseField name="priority" type="integer">
      New priority level (0-4)
    </ResponseField>

    ### Response

    ```json theme={null}
    {
      "additionalProperties": false,
      "properties": {
        "success": {
          "title": "Success",
          "type": "boolean"
        },
        "error": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Error"
        },
        "issue": {
          "anyOf": [
            {
              "additionalProperties": true,
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Issue"
        }
      },
      "required": [
        "success"
      ],
      "title": "UpdateIssueOutput",
      "type": "object"
    }
    ```
  </Accordion>

  <Accordion title="list_projects — List projects in Linear with optional team filtering and pagination.">
    ### Parameters

    <ResponseField name="team_id" type="string">
      Filter by team ID
    </ResponseField>

    <ResponseField name="order_by" type="string">
      Field to order by ('createdAt' or 'updatedAt') (Default: `updatedAt`)
    </ResponseField>

    <ResponseField name="limit" type="integer">
      Maximum number of projects to return (Default: `50`)
    </ResponseField>

    <ResponseField name="after" type="string">
      Cursor for pagination
    </ResponseField>

    ### Response

    ```json theme={null}
    {
      "additionalProperties": false,
      "properties": {
        "success": {
          "title": "Success",
          "type": "boolean"
        },
        "error": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Error"
        },
        "count": {
          "default": 0,
          "title": "Count",
          "type": "integer"
        },
        "page_info": {
          "anyOf": [
            {
              "additionalProperties": true,
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Page Info"
        },
        "projects": {
          "items": {
            "additionalProperties": true,
            "type": "object"
          },
          "title": "Projects",
          "type": "array"
        }
      },
      "required": [
        "success"
      ],
      "title": "ListProjectsOutput",
      "type": "object"
    }
    ```
  </Accordion>

  <Accordion title="create_project — Create a new project in Linear.">
    ### Parameters

    <ResponseField name="team_id" type="string" required>
      The team's UUID (the 'id' field returned by get\_teams) — NOT the short team key like 'ENG'. Call get\_teams first to resolve it.
    </ResponseField>

    <ResponseField name="name" type="string" required>
      The name of the project
    </ResponseField>

    <ResponseField name="description" type="string">
      The description of the project
    </ResponseField>

    <ResponseField name="status_id" type="string">
      The project-status ID
    </ResponseField>

    <ResponseField name="priority" type="integer">
      Priority level (0-4)
    </ResponseField>

    <ResponseField name="member_ids" type="array">
      IDs of users to add as members
    </ResponseField>

    <ResponseField name="start_date" type="string">
      Start date (YYYY-MM-DD)
    </ResponseField>

    <ResponseField name="target_date" type="string">
      Target date (YYYY-MM-DD)
    </ResponseField>

    <ResponseField name="label_ids" type="array">
      Label IDs to attach
    </ResponseField>

    ### Response

    ```json theme={null}
    {
      "additionalProperties": false,
      "properties": {
        "success": {
          "title": "Success",
          "type": "boolean"
        },
        "error": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Error"
        },
        "project": {
          "anyOf": [
            {
              "additionalProperties": true,
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Project"
        }
      },
      "required": [
        "success"
      ],
      "title": "CreateProjectOutput",
      "type": "object"
    }
    ```
  </Accordion>
</AccordionGroup>

## Limits & Quotas

* All tools share a single GraphQL endpoint; failures (HTTP non-200,
  GraphQL `errors`, exceptions) surface as `success=False` + `error`.
* The `search_issues` and `list_projects` actions interpolate filter
  values into the GraphQL string verbatim (matching legacy). Inputs
  are scoped to internal IDs / label names — not user prose — and
  treated as opaque tokens.
* Output objects keep their nested GraphQL shape unchanged (state,
  team, assignee, creator, labels.nodes for issues; lead, status for
  projects).

## Related integrations

<CardGroup cols={3}>
  <Card title="Airtable" href="/integrations/tools/airtable" />

  <Card title="ClickUp" href="/integrations/tools/clickup" />

  <Card title="Jira" href="/integrations/tools/jira" />
</CardGroup>

## Links

* [Linear](https://linear.app)
