Skill Store 33

Linear

Interact with Linear project management - query issues, update status, create tickets, and manage…

by openhands · MIT

The skill

Interact with Linear project management - query issues, update status, create tickets, and manage workflows using the Linear GraphQL API. Use when working with Linear tickets, sprints, or project tracking.

Linear

Connection selection

Use authenticated Linear MCP tools first when they are available in the agent's environment. Detect this by tool availability, without depending on a particular MCP server name. Use the API key and direct GraphQL instructions below only when Linear MCP tools are unavailable or when raw API or curl access is explicitly needed.

Windows PowerShell equivalents for the repeated Linear GraphQL curl and environment-variable snippets are in references/windows.md.

<IMPORTANT> Before using the direct API fallback, check if the required environment variable is set:

[ -n "$LINEAR_API_KEY" ] && echo "LINEAR_API_KEY is set" || echo "LINEAR_API_KEY is NOT set"

If LINEAR_API_KEY is missing and authenticated Linear MCP tools are unavailable, ask the user to provide it before proceeding. </IMPORTANT>

Understanding Linear Identifiers

Linear uses two types of identifiers for issues:

  • Human-readable identifier (e.g., ALL-1234): Displayed to users, used in search queries. This is the team key + number.
  • UUID (e.g., a1b2c3d4-e5f6-7890-abcd-ef1234567890): Required for all mutations (update, comment, etc.). Returned as id in query results.

Important workflow: When working with issues, you must:

  1. Search or query using the human-readable identifier
  2. Extract the id (UUID) from the query result
  3. Use the UUID in any mutation operations

Authentication

All Linear API requests use GraphQL with the API key in the Authorization header:

curl -s -X POST https://api.linear.app/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: $LINEAR_API_KEY" \
  -d '{"query": "YOUR_GRAPHQL_QUERY"}'

Common Queries

Get Assigned Issues (Open)

curl -s -X POST https://api.linear.app/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: $LINEAR_API_KEY" \
  -d '{
    "query": "query { viewer { assignedIssues(first: 50, filter: { state: { type: { nin: [\"completed\", \"canceled\"] } } }) { nodes { id identifier title priority priorityLabel state { name type } description createdAt updatedAt } } } }"
  }' | jq '.data.viewer.assignedIssues.nodes'

Get Issues by Priority

Priority values: 0 = No priority, 1 = Urgent, 2 = High, 3 = Medium, 4 = Low

curl -s -X POST https://api.linear.app/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: $LINEAR_API_KEY" \
  -d '{
    "query": "query { viewer { assignedIssues(first: 50, filter: { priority: { lte: 2 }, state: { type: { nin: [\"completed\", \"canceled\"] } } }) { nodes { id identifier title priority priorityLabel state { name } } } } }"
  }' | jq '.data.viewer.assignedIssues.nodes'

Get Issue Details

curl -s -X POST https://api.linear.app/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: $LINEAR_API_KEY" \
  -d '{
    "query": "query { issue(id: \"ISSUE_UUID\") { id identifier title description state { name } priority assignee { name email } labels { nodes { name } } comments { nodes { body createdAt user { name } } } } }"
  }' | jq '.data.issue'

Search Issues by Identifier

curl -s -X POST https://api.linear.app/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: $LINEAR_API_KEY" \
  -d '{
    "query": "query { issueSearch(query: \"ALL-1234\", first: 5) { nodes { id identifier title state { name } } } }"
  }' | jq '.data.issueSearch.nodes'

Common Mutations

Update Issue State

First, get available workflow states:

curl -s -X POST https://api.linear.app/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: $LINEAR_API_KEY" \
  -d '{
    "query": "query { workflowStates { nodes { id name type } } }"
  }' | jq '.data.workflowStates.nodes'

Then update the issue:

curl -s -X POST https://api.linear.app/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: $LINEAR_API_KEY" \
  -d '{
    "query": "mutation { issueUpdate(id: \"ISSUE_UUID\", input: { stateId: \"STATE_UUID\" }) { success issue { identifier state { name } } } }"
  }' | jq '.data.issueUpdate'

Add Comment to Issue

curl -s -X POST https://api.linear.app/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: $LINEAR_API_KEY" \
  -d '{
    "query": "mutation { commentCreate(input: { issueId: \"ISSUE_UUID\", body: \"Your comment here\" }) { success comment { id body } } }"
  }' | jq '.data.commentCreate'

Create New Issue

curl -s -X POST https://api.linear.app/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: $LINEAR_API_KEY" \
  -d '{
    "query": "mutation { issueCreate(input: { teamId: \"TEAM_UUID\", title: \"Issue Title\", description: \"Issue description\", priority: 2 }) { success issue { identifier title url } } }"
  }' | jq '.data.issueCreate'

End-to-End Workflow: Move Issue to "In Progress"

This example shows the complete flow to change an issue's state using its human-readable identifier:

Step 1: Search for the issue to get its UUID

# Search for issue ALL-1234 and extract its UUID
curl -s -X POST https://api.linear.app/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: $LINEAR_API_KEY" \
  -d '{
    "query": "query { issueSearch(query: \"ALL-1234\", first: 1) { nodes { id identifier title state { name } } } }"
  }' | jq '.data.issueSearch.nodes[0]'
# Save the "id" value (UUID) from the response

Step 2: Get available workflow states

# List all workflow states to find the "In Progress" state UUID
curl -s -X POST https://api.linear.app/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: $LINEAR_API_KEY" \
  -d '{
    "query": "query { workflowStates { nodes { id name type } } }"
  }' | jq '.data.workflowStates.nodes[] | select(.name == "In Progress")'
# Save the "id" value of the desired state

Step 3: Update the issue state

# Use the issue UUID and state UUID from previous steps
curl -s -X POST https://api.linear.app/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: $LINEAR_API_KEY" \
  -d '{
    "query": "mutation { issueUpdate(id: \"ISSUE_UUID_FROM_STEP_1\", input: { stateId: \"STATE_UUID_FROM_STEP_2\" }) { success issue { identifier state { name } } } }"
  }' | jq '.data.issueUpdate'

Get Team Information

curl -s -X POST https://api.linear.app/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: $LINEAR_API_KEY" \
  -d '{
    "query": "query { teams { nodes { id name key } } }"
  }' | jq '.data.teams.nodes'

Priority Levels

Priority Label Recommended Action
1 Urgent Work on immediately
2 High Work on first
3 Medium Normal priority
4 Low When time permits
0 None Backlog

State Types

  • backlog - Not yet started
  • unstarted - Todo
  • started - In Progress
  • completed - Done
  • canceled - Won't do

Documentation

Use this skill

Connect your agent to the Skill Store MCP server and ask for it by ref: openhands/linear-48109861107.

Download SKILL.md · Markdown version

Details

Publisher
openhands
Category
Business › Product & project management
License
MIT
Updated
2026-10-19

References

More from openhands