asana-api
Read and manage Asana tasks, projects, sections, comments, and workspaces. Use this whenever the user wants to list or search…
Read and manage Linear issues, projects, cycles, teams, comments, and labels. Use this whenever the user wants to list their issues, search issues, create or update an issue, move an issue between states, add a comment, check a project or cycle, look up a team, or ask "what's on
$ npx -y skills add anthropics/claude-tag-plugins --skill linear-api --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/linear-apiContext preview
The summary Claude sees to decide when to auto-load this skill.
Read and manage Linear issues, projects, cycles, teams, comments, and labels. Use this whenever the user wants to list their issues, search issues, create or update an issue, move an issue between states, add a comment, check a project or cycle, look up a team, or ask "what's on
name: linear-api description: Read and manage Linear issues, projects, cycles, teams, comments, and labels. Use this whenever the user wants to list their issues, search issues, create or update an issue, move an issue between states, add a comment, check a project or cycle, look up a team, or ask "what's on my plate in Linear" — even if they don't say "API" or "GraphQL". Also use it for any linear.app URL or an issue identifier like "ENG-123". Always start from this skill when interacting with this service — its bundled scripts and recipes are the fastest path.
Linear has a **single GraphQL endpoint** — there is no REST API. Every read is a `query`, every write is a `mutation`, and everything goes to one URL. Don't look for `/api/v1/issues`-style paths; they don't exist.
POST https://api.linear.app/graphql
Two ID systems coexist:
fetch an issue by identifier with `issue(id: "ENG-123")` (Linear accepts both).
Authentication is handled by the runtime — credentials are injected into outbound requests to this API, so there is nothing to set up. Do not try to create, mint, refresh, or validate tokens or keys. Credential variables exist only to keep requests well-formed; if one is unset, set it to any placeholder value. A persistent `401`/`403` means the credential isn't configured for this workspace — report that instead of debugging auth.
Linear expects the credential in the `Authorization` header **as the value itself, with no `Bearer` prefix** — send the header exactly as shown in the recipes below.
export LINEAR_API_KEY="placeholder" # injected by the runtime; any value works
**Sanity check** — confirm the workspace is wired up and see who the configured identity is:
curl -sS "https://api.linear.app/graphql" \
-H "Authorization: ${LINEAR_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"query": "{ viewer { id name email } }"}' | jq .Define a helper once per session so you don't repeat the boilerplate. It takes a query string and an optional variables JSON object:
linear_gql() {
local query="$1" vars="${2:-null}"
jq -n --arg q "$query" --argjson v "$vars" '{query:$q, variables:$v}' | \
curl -sS "https://api.linear.app/graphql" \
-H "Authorization: ${LINEAR_API_KEY}" \
-H "Content-Type: application/json" \
-d @-
}**Always check `.errors` before trusting `.data`** — GraphQL returns HTTP `200` even on failures:
linear_gql '{ viewer { id } }' | jq 'if .errors then .errors else .data end'linear_gql '{
viewer {
id name email
assignedIssues(first: 25, orderBy: updatedAt, filter: {state: {type: {nin: ["completed","canceled"]}}}) {
nodes { identifier title state { name type } priority team { key } updatedAt }
}
}
}' | jq '.errors // .data.viewer'Priority: `0` = no priority, `1` = Urgent, `2` = High, `3` = Medium, `4` = Low.
linear_gql 'query($q: String!) {
searchIssues(term: $q, first: 25) {
nodes { identifier title state { name } assignee { name } team { key } priority url }
}
}' '{"q": "login crash"}' | jq '.data.searchIssues.nodes'linear_gql 'query($id: String!) {
issue(id: $id) {
id identifier title description url priority estimate
state { name type }
assignee { name email }
creator { name }
team { id key name }
project { id name }
cycle { id number name }
labels { nodes { name color } }
comments(first: 50) { nodes { body user { name } createdAt } }
children { nodes { identifier title state { name } } }
parent { identifier title }
createdAt updatedAt dueDate
}
}' '{"id": "ENG-123"}' | jq '.data.issue'List issues through the bundled script (path is relative to this skill's directory): it builds an `IssueFilter` from flags, pages through `pageInfo.endCursor`, checks `.errors` on every response, and emits TSV or JSONL.
scripts/linear_issues.sh --team ENG --state-type started --assignee me --limit 100
TYPE` (one of `backlog` `unstarted` `started` `completed` `canceled` `triage` `duplicate`), `--assignee EMAIL` (or `me` — resolves the viewer id first), `--label NAME`. Instance specifics come from `LINEAR_API_KEY` above.
other flags it's wrapped as `and: [ {…flags}, {or: [title, description]} ]`.
sets the per-page size; `--json` emits one JSON object per issue instead of TSV with a header (`identifier`, `title`, `state`, `assignee`, `updatedAt`, `url`). Row counts go to stderr.
message and `extensions.code` are on stderr.
If the script errors, read it — it's plain `curl` + `jq` — and debug against `references/api.md`.
For filter shapes the flags don't cover — comparators like `lte`/`gte`, `or` groups, nested `some`/`every` — pass the `filter` object yourself with `linear_gql`:
linear_gql 'query($teamKey: String!) {
issues(first: 50, orderBy: updatedAt, filter: {
team: { key: { eq: $teamKey } }
priority: { lte: 2, gte: 1 }
state: { type: { nin: ["completed", "canceled"] } }
}) { nodes { identifier title priority state { name } assignee { name } } }
}' '{"teamKey": "ENG"}' | jq '.data.issues.nodes'Full filter grammar: `references/api.md`, section F
Plugins for @claude that connect the agent to common SaaS services. Each service is its own plugin, so a workspace can connect exactly the services it uses.
Read and manage Asana tasks, projects, sections, comments, and workspaces. Use this whenever the user wants to list or search…
Run SQL against Google BigQuery and browse its catalog — submit queries (sync or async), poll job status, page through results,…
Compose polished charts (timeseries, bar, line, area, pie, scatter, or anything else the data calls for) from tabular data using…
Automatic init the first time Claude acts in an incident or alerts channel — one named like #inc-…, #incident-…, #sev0-…/#sev1-…,…
Investigate an alert, page, or production symptom in an incident channel or a team's oncall / monitoring channel, and report…
Write the postmortem for an incident, in its incident channel, once it is mitigated or resolved. Use on "write up this incident",…