Linear CLI
A CLI to manage Linear issues from the command line, with git and jj integration.
Prerequisites
The linear command must be available on PATH. To check:
linear --version
If not installed globally, you can run it without installing via npx:
npx @schpet/linear-cli --version
All subsequent commands can be prefixed with npx @schpet/linear-cli in place of linear. Otherwise, follow the install instructions at:
https://github.com/schpet/linear-cli?tab=readme-ov-file#install
Common Tasks
Copy-pasteable recipes for the most frequent flows. Prefer these dedicated commands over linear api — reach for the GraphQL fallback only when no dedicated command or flag covers the operation.
Query issues with filters
issue query searches across all assignees and supports structured filters that can be combined:
linear issue query --team ENG --state started --json
linear issue query --project "Mobile App" --state backlog --state triage --unassigned
linear issue query --assignee sam --label bug --updated-after 2026-01-01
Note: linear issue list is an alias of issue mine and only shows your issues — use issue query for anything scoped to other people or a whole team/project.
List my issues
linear issue mine --state started --sort priority
Create an issue
linear issue create --team ENG --title "Fix login redirect" \
--description-file ./description.md --no-interactive
Write multi-line markdown to a file and pass --description-file (see the markdown section below); --no-interactive avoids prompts in scripted use.
Update an issue's state, assignee, or labels
linear issue update ENG-123 --state "In Review" --assignee sam
linear issue update ENG-123 --unassign
linear issue update ENG-123 --add-label security # add, keep existing labels
linear issue update ENG-123 --remove-label sprint-42 # detach; does not delete the label
linear issue update ENG-123 --remove-label sprint-42 --add-label sprint-43 # atomic swap
linear issue update ENG-123 --label infra --label security # replaces the label set
Add a comment
linear issue comment add ENG-123 --body-file ./comment.md
Attach an image or screenshot so it is visible inline
linear issue comment add ENG-123 --attach ./screenshot.png
This uploads the image and embeds it in a comment, where Linear renders it inline. Do not use linear issue attach when the image must be visible: that command creates a sidebar link attachment and does not render images inline.
View an issue / get its URL
linear issue view ENG-123 # details incl. comments
linear issue view ENG-123 --json # structured output
linear issue url ENG-123 # print just the URL
Best Practices for Markdown Content
When working with issue descriptions or comment bodies that contain markdown, always prefer using file-based flags instead of passing content as command-line arguments:
- Use
--description-fileforissue createandissue updatecommands - Use
--body-fileforcomment addandcomment updatecommands
Why use file-based flags:
- Ensures proper formatting in the Linear web UI
- Avoids shell escaping issues with newlines and special characters
- Prevents literal
\nsequences from appearing in markdown - Makes it easier to work with multi-line content
Example workflow:
# Write markdown to a temporary file
cat > /tmp/description.md <<'EOF'
## Summary
- First item
- Second item
## Details
This is a detailed description with proper formatting.
EOF
# Create issue using the file
linear issue create --title "My Issue" --description-file /tmp/description.md
# Or for comments
linear issue comment add ENG-123 --body-file /tmp/comment.md
Only use inline flags (--description, --body) for simple, single-line content.
Linear Markdown Features
Mention people and resources with plain URLs
Linear turns a resource's plain Linear URL in Markdown into a linked mention. A literal @name, @[Name](id), or a Markdown link such as [Name](url) does not create the same mention. Put the plain URL directly in the comment or description:
https://linear.app/yourworkspace/profiles/someuser could you review this? https://linear.app/yourworkspace/issue/ENG-123 is related.
Resolve people within the relevant team first. The team can usually be inferred from the issue identifier or current directory:
linear team members ENG --json
Use the selected member's url field verbatim in the Markdown. If the intended person is not a member of that team, stop and confirm before searching the whole workspace with linear user list --json; mentioning someone outside the team is likely accidental. For issues, use linear issue url ENG-123 and include that plain URL.
Add collapsible sections
Open a collapsible section with +++ [title] and close it with +++:
+++ [Server log]
Markdown content that is initially hidden.
+++
The square brackets around the title and the closing +++ are required.
Available Commands
Compact command list, generated from linear --help:
linear api
linear auth
linear auth default
linear auth list
linear auth login
linear auth logout
linear auth migrate
linear auth token
linear auth whoami
linear config
linear cycle
linear cycle list
linear cycle view
linear document
linear document comment
linear document comment add
linear document comment list
linear document create
linear document delete
linear document list
linear document update
linear document view
linear initiative
linear initiative add-project
linear initiative archive
linear initiative comment
linear initiative comment add
linear initiative comment list
linear initiative create
linear initiative delete
linear initiative list
linear initiative remove-project
linear initiative unarchive
linear initiative update
linear initiative view
linear initiative-update
linear initiative-update create
linear initiative-update list
linear issue
linear issue agent-session
linear issue agent-session list
linear issue agent-session view
linear issue attach
linear issue comment
linear issue comment add
linear issue comment delete
linear issue comment list
linear issue comment update
linear issue commits
linear issue create
linear issue delete
linear issue describe
linear issue id
linear issue link
linear issue mine
linear issue pull-request
linear issue query
linear issue relation
linear issue relation add
linear issue relation delete
linear issue relation list
linear issue start
linear issue title
linear issue update
linear issue url
linear issue view
linear label
linear label create
linear label delete
linear label list
linear markdown
linear milestone
linear milestone create
linear milestone delete
linear milestone list
linear milestone update
linear milestone view
linear project
linear project comment
linear project comment add
linear project comment list
linear project create
linear project delete
linear project list
linear project update
linear project view
linear project-update
linear project-update create
linear project-update list
linear schema
linear team
linear team autolinks
linear team create
linear team delete
linear team id
linear team list
linear team members
linear team states
linear user
linear user list
Reference Documentation
- api - Make a raw GraphQL API request
- auth - Manage Linear authentication
- config - Interactively generate .linear.toml configuration
- cycle - Manage Linear team cycles
- document - Manage Linear documents
- initiative - Manage Linear initiatives
- initiative-update - Manage initiative status updates (timeline posts)
- issue - Manage Linear issues
- label - Manage Linear issue labels
- markdown - Linear-flavored Markdown: mentions and collapsible sections
- milestone - Manage Linear project milestones
- project - Manage Linear projects
- project-update - Manage project status updates
- schema - Print the GraphQL schema to stdout
- team - Manage Linear teams
- user - Manage Linear users
For curated examples of organization features (initiatives, labels, projects, bulk operations), see organization-features.
Discovering Options
To see available subcommands and flags, run --help on any command:
linear --help
linear issue --help
linear issue list --help
linear issue create --help
Each command has detailed help output describing all available flags and options.
Some commands have required flags that aren't obvious. Notable examples:
issue listsorts by priority by default — override via--sort(valid values:manual,priority), theissue_sortconfig option, or theLINEAR_ISSUE_SORTenv var. Requires--team <key>unless the team can be inferred from the directory — if unknown, runlinear team listfirst (linear team list --jsonmaps team names to theirkeyandid).--no-pageris only supported onissue list— passing it to other commands likeproject listwill error.
Using the Linear GraphQL API Directly
Prefer the CLI for all supported operations. The api command should only be used as a fallback for queries not covered by the CLI.
Check the schema for available types and fields
Write the schema to a tempfile, then search it:
linear schema -o "${TMPDIR:-/tmp}/linear-schema.graphql"
grep -i "cycle" "${TMPDIR:-/tmp}/linear-schema.graphql"
grep -A 30 "^type Issue " "${TMPDIR:-/tmp}/linear-schema.graphql"
Make a GraphQL request
Important: GraphQL queries containing non-null type markers (e.g. String followed by an exclamation mark) must be passed via heredoc stdin to avoid escaping issues. Simple queries without those markers can be passed inline.
# Simple query (no type markers, so inline is fine)
linear api '{ viewer { id name email } }'
# Query with variables — use heredoc to avoid escaping issues
linear api --variable teamId=abc123 <<'GRAPHQL'
query($teamId: String!) { team(id: $teamId) { name } }
GRAPHQL
# Search issues by text
linear api --variable term=onboarding <<'GRAPHQL'
query($term: String!) { searchIssues(term: $term, first: 20) { nodes { identifier title state { name } } } }
GRAPHQL
# Numeric and boolean variables
linear api --variable first=5 <<'GRAPHQL'
query($first: Int!) { issues(first: $first) { nodes { title } } }
GRAPHQL
# Complex variables via JSON
linear api --variables-json '{"filter": {"state": {"name": {"eq": "In Progress"}}}}' <<'GRAPHQL'
query($filter: IssueFilter!) { issues(filter: $filter) { nodes { title } } }
GRAPHQL
# Pipe to jq for filtering
linear api '{ issues(first: 5) { nodes { identifier title } } }' | jq '.data.issues.nodes[].title'
Advanced: Using curl directly
For cases where you need full HTTP control, use linear auth token:
curl -s -X POST https://api.linear.app/graphql \
-H "Content-Type: application/json" \
-H "Authorization: $(linear auth token)" \
-d '{"query": "{ viewer { id } }"}'