Commonly-used-high-value-skills linear
Manage Linear issues, projects, and teams with an API-first workflow. Uses the GraphQL API by default and can fall back to the Linear MCP server when it is already configured.
install
source · Clone the upstream repo
git clone https://github.com/seaworld008/Commonly-used-high-value-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/seaworld008/Commonly-used-high-value-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/knowledge-and-pm-integrations/linear" ~/.claude/skills/seaworld008-commonly-used-high-value-skills-linear-8a6cb7 && rm -rf "$T"
manifest:
skills/knowledge-and-pm-integrations/linear/SKILL.mdsource content
Linear
When to Use
Use this skill when the user wants to:
- read, search, create, or update Linear issues
- triage bugs or organize backlog state
- assign work, set priority, labels, or due dates
- create or inspect projects and team workflow states
- automate repeatable Linear operations from the terminal
Recommended Approach
Prefer the Linear GraphQL API first.
Why:
- it works even when the Linear MCP server is not installed
- it is explicit and scriptable
- it gives full control over issue fields, workflow states, and pagination
- it is easier to debug than opaque tool-calling failures
Use the Linear MCP server only when:
- the user already has it connected
- the task benefits from natural-language tool invocation over direct API calls
- OAuth is already working and there is no reason to switch
Prerequisites
API-first mode
You need:
- a Linear personal API key
curl
Set the API key:
export LINEAR_API_KEY="lin_api_xxx"
Get it from:
- Linear Settings
- API
- Personal API keys
MCP fallback mode
If the user prefers MCP and it is not connected yet:
codex mcp add linear --url https://mcp.linear.app/mcp codex --enable rmcp_client codex mcp login linear
After login they need to restart Codex before using the MCP path.
API Basics
- Endpoint:
https://api.linear.app/graphql - Method:
POST - Auth header:
Authorization: $LINEAR_API_KEY - Content type:
application/json
Base request pattern:
curl -s -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"{ viewer { id name email } }"}' | python -m json.tool
Important:
- GraphQL can return HTTP 200 with an
array, so always inspect the bodyerrors - issue identifiers like
are often easier to use than UUIDs for readsENG-123 - updates to status require the target
, not just the state namestateId
Workflow States
Linear workflow state
type values:
triagebacklogunstartedstartedcompletedcanceled
Priority values:
none0
urgent1
high2
medium3
low4
Core Workflow
Follow this order for most tasks:
- Identify the target team
- Fetch workflow states for that team
- Search or inspect relevant issues
- Apply changes with explicit IDs
- Summarize what changed and what remains open
Common Queries
Get current user
curl -s -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"{ viewer { id name email } }"}' | python -m json.tool
List teams
curl -s -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"{ teams { nodes { id name key } } }"}' | python -m json.tool
List workflow states for a team
curl -s -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"{ workflowStates(filter:{ team:{ key:{ eq:\"ENG\" } } }) { nodes { id name type } } }"}' | python -m json.tool
Search issues
curl -s -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"{ issueSearch(query:\"login bug\", first:10) { nodes { id identifier title state { name type } assignee { name } url } } }"}' | python -m json.tool
Get one issue
curl -s -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"{ issue(id:\"ENG-123\") { id identifier title description priority dueDate state { id name type } assignee { id name } labels { nodes { id name } } project { id name } url } }"}' | python -m json.tool
List projects
curl -s -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"{ projects(first:20) { nodes { id name progress lead { name } url } } }"}' | python -m json.tool
Common Mutations
Create issue
curl -s -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "query":"mutation($input: IssueCreateInput!) { issueCreate(input:$input) { success issue { id identifier title url } } }", "variables":{ "input":{ "teamId":"TEAM_UUID", "title":"Fix login redirect bug", "description":"Redirect loses the next parameter", "priority":2 } } }' | python -m json.tool
Update status
curl -s -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"mutation { issueUpdate(id:\"ENG-123\", input:{ stateId:\"STATE_UUID\" }) { success issue { identifier state { name type } } } }"}' | python -m json.tool
Assign issue
curl -s -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"mutation { issueUpdate(id:\"ENG-123\", input:{ assigneeId:\"USER_UUID\" }) { success issue { identifier assignee { name } } } }"}' | python -m json.tool
Set priority
curl -s -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"mutation { issueUpdate(id:\"ENG-123\", input:{ priority:1 }) { success issue { identifier priority } } }"}' | python -m json.tool
Add comment
curl -s -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"mutation { commentCreate(input:{ issueId:\"ISSUE_UUID\", body:\"Root cause identified and fix in progress.\" }) { success comment { id body } } }"}' | python -m json.tool
Set due date
curl -s -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"mutation { issueUpdate(id:\"ENG-123\", input:{ dueDate:\"2026-04-20\" }) { success issue { identifier dueDate } } }"}' | python -m json.tool
Practical Patterns
Bug triage
- Query team workflow states
- Search for matching issues
- Raise priority for user-facing regressions
- Move urgent issues into a
statestarted - Add a short triage comment with rationale
Sprint planning
- List backlog items for a team
- Filter by priority or labels
- Assign owners
- Add due dates or attach to a project
- Summarize remaining backlog risk
Status cleanup
- Find issues in
started - Identify stale assignees or overdue items
- Add follow-up comments
- Move blocked or abandoned work out of
started
Pagination
Linear uses cursor pagination:
curl -s -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"{ issues(first:20) { nodes { identifier title } pageInfo { hasNextPage endCursor } } }"}' | python -m json.tool
Use the returned
endCursor as after:"CURSOR" in the next request.
MCP Fallback
If the user already has Linear MCP working, you can still use it for:
- fast natural-language listing and search
- team and project lookups
- small updates where raw GraphQL adds no value
Prefer API mode if:
- you need reproducible curl commands
- the MCP server is not available
- you need explicit control of fields and IDs
- you are debugging authentication or workflow-state issues
Troubleshooting
means the API key is missing or invalidUnauthorized- HTTP 200 with GraphQL
means the request shape is wrongerrors - unknown workflow status usually means you passed a name instead of
stateId - no search results may mean wrong team key or stale identifier
- if MCP is configured but failing on Windows, prefer API mode instead of blocking on WSL transport
Notes
- This skill is intentionally API-first because it is more portable than MCP-only workflows
- If you later want parity with Hermes upstream provenance, map this skill to the Hermes Linear source rather than treating it as purely in-house