linear▌
odysseus0/symphony · updated Apr 8, 2026
All Linear operations go through the linear_graphql client tool exposed by
- ›Symphony's app server. It handles auth automatically.
Linear GraphQL
All Linear operations go through the linear_graphql client tool exposed by
Symphony's app server. It handles auth automatically.
{
"query": "query or mutation document",
"variables": { "optional": "graphql variables" }
}
One operation per tool call. A top-level errors array means the operation
failed even if the tool call completed.
Workpad
Maintain a local workpad.md in your workspace. Edit freely (zero API cost),
then sync to Linear at milestones — plan finalized, implementation done,
validation complete. Do not sync after every small change.
First sync — create the comment, save the ID:
mutation CreateComment($issueId: String!, $body: String!) {
commentCreate(input: { issueId: $issueId, body: $body }) {
success
comment { id }
}
}
Write the returned comment.id to .workpad-id so subsequent syncs can update.
Subsequent syncs — read .workpad-id, update in place:
mutation UpdateComment($id: String!, $body: String!) {
commentUpdate(id: $id, input: { body: $body }) { success }
}
Query an issue
The orchestrator injects issue context (identifier, title, description, state, labels, URL) into your prompt at startup. You usually do not need to re-read.
When you do, use the narrowest lookup for what you have:
# By ticket key (e.g. MT-686)
query($key: String!) {
issue(id: $key) {
id identifier title url description
state { id name type }
project { id name }
}
}
For comments and attachments:
query($id: String!) {
issue(id: $id) {
comments(first: 50) { nodes { id body user { name } createdAt } }
attachments(first: 20) { nodes { url title sourceType } }
}
}
State transitions
Fetch team states first, then move with the exact stateId:
query($id: String!) {
issue(id: $id) {
team { states { nodes { id name } } }
}
}
mutation($id: String!, $stateId: String!) {
issueUpdate(id: $id, input: { stateId: $stateId }) {
success
issue { state { name } }
}
}
Attach a PR or URL
# GitHub PR (preferred for PRs)
mutation($issueId: String!, $url: String!, $title: String) {
attachmentLinkGitHubPR(issueId: $issueId, url: $url, title: $title, linkKind: links) {
success
}
}
# Plain URL
mutation($issueId: String!, $url: String!, $title: String) {
attachmentLinkURL(issueId: $issueId, url: $url, title: $title) {
success
}
}
File upload
Three steps:
- Get upload URL:
mutation($filename: String!, $contentType: String!, $size: Int!) {
fileUpload(filename: $filename, contentType: $contentType, size: $size, makePublic: true) {
success
uploadFile { uploadUrl assetUrl headers { key value } }
}
}
- PUT file bytes to
uploadUrlwith the returned headers (usecurl). - Embed
assetUrlin comments/workpad as.
Issue creation
Resolve project slug to IDs first:
query($slug: String!) {
projects(filter: { slugId: { eq: $slug } }) {
nodes { id teams { nodes { id key states { nodes { id name } } } } }
}
}
Then create:
mutation($input: IssueCreateInput!) {
issueCreate(input: $input) {
success
issue { identifier url }
}
}
$input fields: title, teamId, projectId, and optionally description,
priority (0–4), stateId. For relations, follow up with:
mutation($input: IssueRelationCreateInput!) {
issueRelationCreate(input: $input) { success }
}
Input: issueId, relatedIssueId, type (blocks or related).
Rules
- No introspection. Never use
__typeor__schemaqueries. They return the entire Linear schema (~200K chars) and waste the context window. Every pattern you need is documented above. - Keep queries narrowly scoped — ask only for fields you need.
- Sync the workpad at milestones, not after every change.
- For state transitions, always fetch team states first — never hardcode state IDs.
- Prefer
attachmentLinkGitHubPRover generic URL attachment for GitHub PRs.
Discussion
Product Hunt–style comments (not star reviews)- No comments yet — start the thread.
Ratings
4.5★★★★★31 reviews- ★★★★★Neel Taylor· Dec 28, 2024
Keeps context tight: linear is the kind of skill you can hand to a new teammate without a long onboarding doc.
- ★★★★★Luis Brown· Dec 12, 2024
I recommend linear for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
- ★★★★★Luis Agarwal· Dec 8, 2024
linear has been reliable in day-to-day use. Documentation quality is above average for community skills.
- ★★★★★Dev Thompson· Nov 27, 2024
Solid pick for teams standardizing on skills: linear is focused, and the summary matches what you get after install.
- ★★★★★Nia Shah· Oct 18, 2024
linear is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
- ★★★★★Henry Lopez· Oct 14, 2024
Useful defaults in linear — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
- ★★★★★Benjamin Sharma· Sep 21, 2024
Registry listing for linear matched our evaluation — installs cleanly and behaves as described in the markdown.
- ★★★★★Piyush G· Sep 17, 2024
linear reduced setup friction for our internal harness; good balance of opinion and flexibility.
- ★★★★★Isabella Huang· Aug 12, 2024
Useful defaults in linear — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
- ★★★★★Shikha Mishra· Aug 8, 2024
We added linear from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
showing 1-10 of 31