with one click
linear-graphql
// Use Symphony's `linear_graphql` client tool for raw Linear GraphQL operations such as comment editing and upload flows.
// Use Symphony's `linear_graphql` client tool for raw Linear GraphQL operations such as comment editing and upload flows.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | linear-graphql |
| description | Use Symphony's `linear_graphql` client tool for raw Linear GraphQL operations such as private upload flows, rich `bodyData`, targeted introspection, and rare unsupported Linear API operations. |
Use this skill for raw Linear GraphQL work during Symphony app-server sessions.
Use Linear MCP tools for routine issue-management work: issue lookup, comment
listing, workpad discovery, plain comment/workpad create or update, issue state
transitions, labels/statuses/projects, and normal link attachment when MCP can
express the operation. Reserve linear_graphql for operations the MCP tools
cannot perform, such as private upload flows, rich bodyData writes or
verification, targeted introspection, or narrowly scoped unsupported Linear API
operations.
Do not use this skill to hand-build screenshot or screencast uploads for UI evidence. UI evidence publication is the repository's intentional GraphQL-only exception and must go through the script-backed publisher:
node .codex/skills/linear-ui-evidence/scripts/publish-linear-ui-evidence.js \
--issue ABC-123 \
--image output/playwright/screenshot.png::"Changed UI state"
That publisher owns private fileUpload(makePublic:false), signed upload PUTs,
rich bodyData image/video comments, and verification by re-reading
comment.bodyData.
Use the linear_graphql client tool exposed by Symphony's app-server session.
It reuses Symphony's configured Linear auth for the session.
Tool input:
{
"query": "query or mutation document",
"variables": {
"optional": "graphql variables object"
}
}
Tool behavior:
errors array as a failed GraphQL operation even if the
tool call itself completed.When you need an unfamiliar mutation, input type, or object field, use targeted
introspection through linear_graphql.
List mutation names:
query ListMutations {
__type(name: "Mutation") {
fields {
name
}
}
}
Inspect a specific input object:
query CommentCreateInputShape {
__type(name: "CommentCreateInput") {
inputFields {
name
type {
kind
name
ofType {
kind
name
}
}
}
}
}
Use Linear MCP get_issue or list_issues for this routine read path when they
are available. Only use the raw GraphQL queries below when MCP access is
unavailable or the workflow needs fields that the MCP tools do not expose.
Use these progressively:
issue(id: $key) when you have a ticket key such as MT-686.issues(filter: ...) when you need identifier search semantics.issue(id: $id) for narrower reads.Lookup by issue key:
query IssueByKey($key: String!) {
issue(id: $key) {
id
identifier
title
state {
id
name
type
}
project {
id
name
}
branchName
url
description
updatedAt
links {
nodes {
id
url
title
}
}
}
}
Lookup by identifier filter:
query IssueByIdentifier($identifier: String!) {
issues(filter: { identifier: { eq: $identifier } }, first: 1) {
nodes {
id
identifier
title
state {
id
name
type
}
project {
id
name
}
branchName
url
description
updatedAt
}
}
}
Resolve a key to an internal id:
query IssueByIdOrKey($id: String!) {
issue(id: $id) {
id
identifier
title
}
}
Read the issue once the internal id is known:
query IssueDetails($id: String!) {
issue(id: $id) {
id
identifier
title
url
description
state {
id
name
type
}
project {
id
name
}
attachments {
nodes {
id
title
url
sourceType
}
}
}
}
Use this before changing issue state when you need the exact stateId:
query IssueTeamStates($id: String!) {
issue(id: $id) {
id
team {
id
key
name
states {
nodes {
id
name
type
}
}
}
}
}
Use Linear MCP save_comment for this routine write path. save_comment can
create a new comment with issueId and update an existing comment by comment
id. Do not use raw GraphQL for ordinary workpad progress, handoff notes, or
plain Markdown comment edits when save_comment is available.
Only use commentCreate or commentUpdate through linear_graphql when the
operation requires GraphQL-only fields such as rich bodyData.
Use Linear MCP save_issue for routine state transitions. Only use
issueUpdate with the destination stateId when MCP cannot express the
required operation:
mutation MoveIssueToState($id: String!, $stateId: String!) {
issueUpdate(id: $id, input: { stateId: $stateId }) {
success
issue {
id
identifier
state {
id
name
}
}
}
}
Use Linear MCP save_issue links for ordinary PR URL attachment when a plain
Linear attachment is sufficient. Use the GitHub-specific attachment mutation
only when richer GitHub-specific Linear attachment metadata is required and MCP
cannot express it:
mutation AttachGitHubPR($issueId: String!, $url: String!, $title: String) {
attachmentLinkGitHubPR(
issueId: $issueId
url: $url
title: $title
linkKind: links
) {
success
attachment {
id
title
url
}
}
}
If you only need a plain URL attachment and do not care about GitHub-specific link metadata, use:
mutation AttachURL($issueId: String!, $url: String!, $title: String) {
attachmentLinkURL(issueId: $issueId, url: $url, title: $title) {
success
attachment {
id
title
url
}
}
}
Use these when the exact field or mutation shape is unclear:
query QueryFields {
__type(name: "Query") {
fields {
name
}
}
}
query IssueFieldArgs {
__type(name: "Query") {
fields {
name
args {
name
type {
kind
name
ofType {
kind
name
ofType {
kind
name
}
}
}
}
}
}
}
linear_graphql only for private upload flows, rich bodyData writes or
verification, targeted introspection, and rare unsupported Linear API
operations.linear-ui-evidence
publisher instead of writing upload/comment GraphQL in the conversation.stateId instead of hardcoding names inside mutations.attachmentLinkGitHubPR over a
generic URL attachment only when the richer GitHub-specific metadata is
required.fileUpload; those URLs already carry the needed authorization.