skills/linear/SKILL.md
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.
npx skillsauth add openhands/extensions linearInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
[ -n "$LINEAR_API_KEY" ] && echo "LINEAR_API_KEY is set" || echo "LINEAR_API_KEY is NOT set"
If LINEAR_API_KEY is missing, ask the user to provide it before proceeding. </IMPORTANT>
Linear uses two types of identifiers for issues:
ALL-1234): Displayed to users, used in search queries. This is the team key + number.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:
id (UUID) from the query resultAll 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"}'
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'
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'
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'
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'
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'
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'
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'
This example shows the complete flow to change an issue's state using its human-readable identifier:
# 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
# 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
# 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'
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 | 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 |
backlog - Not yet startedunstarted - Todostarted - In Progresscompleted - Donecanceled - Won't dotools
Create an automation that generates an async standup digest from Slack. Searches selected channels for messages since the previous workday, groups updates by project, highlights blockers and decisions, and posts a summary to a target channel.
tools
Create an automation that writes a recurring research brief. Uses Tavily MCP for web research and Notion MCP to publish the final brief with executive summary, implications, and source citations.
tools
Create an automation that triages new Linear issues. Inspects the issue title, description, team, customer, priority, and recent related issues via Linear MCP. Suggests labels, priority, likely owner, duplicates, and posts a clarifying comment.
tools
Create an automation that drafts incident retrospectives. Gathers incident-channel messages from Slack, collects linked tickets and follow-ups from Linear, and publishes a retrospective draft to Notion with a timeline, impact summary, root-cause hypotheses, and action items.