Meaningful linear issues
Agent skills we use daily in the studio — reusable, on-demand context for Claude Code, Cursor & other skills.sh-compatible AI agents. Install: npx skills add stealth-engine/skills
npx -y skills add stealth-engine/skills --skill meaningful-linear-issuesAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Create complete, analytics-ready Linear issues in ONE pass — resolve the right project (never guess it), and proactively fill the metadata that's technically optional but matters for planning/analytics: priority, estimate, labels (a Type + an Area from the team's existing taxonomy), milestone, assignee, cycle, and relations. Use when asked to 'create/file/open a Linear issue', 'log a ticket', 'add this to Linear', 'make an issue for X', or before any Linear `save_issue` that **creates** an issue or **backfills** missing metadata on a bare one — so the user doesn't have to come back and ask for the labels/estimate/project a second time, and so an issue doesn't land in the wrong project. NOT for routine field edits (status changes, reassignments) — those are also `save_issue` but don't need this.
SKILL.md
9.3 KB, as published. Nobody here has run it
Meaningful Linear issues
A good issue is not just a good description — that's the easy half. The half agents skip is the metadata that makes Linear actually work as a planning tool: estimates feed cycle velocity, labels feed breakdowns, milestones feed roadmaps, the project feeds everything. Those fields are optional in the API, so agents leave them blank and the user has to come back and ask again.
Flip the default: metadata is opt-OUT, not opt-in. Resolve and fill it before
calling save_issue, in one pass — propose concrete values, don't omit.
Cardinal rule: never guess the project
The single worst failure is dropping an issue into the wrong/random project. Resolve the project in this order — stop at the first that's certain:
- Context — the issue's repo/area maps to a known project; the user named it; a sibling issue you're relating to has one.
- Confirm — call
list_projectsand match by name; if one clearly fits, state which and proceed. - Ask — if it's still ambiguous, ask the user which project rather than picking one. A missing project is recoverable; a wrong one quietly pollutes the wrong roadmap.
Never pass a project you inferred from vibes. Team is required too — usually
unambiguous from the project, but resolve it the same way.
The one-pass workflow
- Discover what's available (only what you don't already know): projects, the team's label taxonomy, milestones, the current cycle, assignable users.
- Draft the issue with every applicable field filled (checklist below).
- Create with one
save_issuecall. If anything was genuinely a judgment call (estimate, priority), state the values you chose so the user can correct one — that's still one pass, not "I left them blank, ask me again."
Create vs. backfill — mind the id
Same checklist, two save_issue modes — don't conflate them:
- Create (new issue):
save_issuewith noid. Fill everything below. - Backfill (existing bare issue):
save_issueWITH itsid— update, don't create. Omitting theidhere would make a duplicate.get_issuefirst if you need to see what's already set, then pass only the fields you're adding.labelsreplaces the whole set — include existing labels alongside the new ones. Relations (blocks/blockedBy/relatedTo) are append-only — adding one won't drop existing links (useremoveBlocks/removeBlockedBy/removeRelatedToto remove). Other fields you don't pass are left untouched.
Metadata checklist — fill before save_issue
| Field | How to set it well |
|---|---|
| team (required) | From the project. list_teams / get_team if unknown. |
| project | Resolve, never guess (above). |
| title | Imperative, specific, scannable. Lead with the verb + the object. |
| description | The implementation detail (see template). |
| priority | 1 Urgent · 2 High · 3 Medium · 4 Low · 0 None. Infer from impact/urgency; default 3 for normal work, ask if it's clearly load-bearing. |
| estimate | Set a real value; Linear snaps it to the team's scale, so you don't need the scale up front — but read back and surface the stored value (it may change: 3 on an exponential team 0,1,2,4,8,16 returns 4; Fibonacci 0,1,2,3,5,8 keeps 3). get_team doesn't expose the scale (as of this MCP version) — infer it from existing issues' estimates (list_issues) only if you need exact pointing. Some teams disable estimates — if save_issue rejects it, drop the field. |
| labels | Pick from the existing taxonomy (list_issue_labels for the team) — don't invent labels. Typically one Type (Feature / Bug / Improvement / Chore / Docs / Refactor / Security / Performance / Test / …) and one Area (the relevant module/domain). Match the team's grouped labels rather than guessing names. |
| assignee | "me", the named owner, or the project/issue's usual owner (list_users to resolve a name/email). Don't leave unassigned if an owner is obvious. |
| milestone | list_milestones for the project; attach if one fits the work. (None exist? skip — don't fabricate.) |
| cycle | Set the current cycle (list_cycles → current) for active work unless the user opts out — don't rely on auto-add, which some teams disable, leaving the issue out of every cycle (and out of velocity). Skip only for backlog/future work that isn't for the current cycle. |
| relations | parentId for sub-work; blocks / blockedBy for ordering; relatedTo for siblings. Link issues you reference in the description — it's cheap and powers dependency views. |
| dueDate | ISO date (YYYY-MM-DD). Set only when there's a real deadline — a launch, a dependency, a commitment. Don't fabricate one; most issues have none. |
If a field genuinely doesn't apply (e.g. no milestones exist), skip it knowingly — the goal is "nothing useful left blank," not "every field stuffed."
Discover valid values
Only the values you don't already have in context. These are the Linear MCP tools:
list_projects(filter by name/team) — resolve the project.list_issue_labels(byteam) — the label taxonomy; reuse, don't invent.list_milestones(byproject) — fitting milestone, if any.list_cycles(byteamId,type: current) — to set the current cycle (don't rely on auto-add).list_users(by name/email, or"me") — resolve an assignee.list_teams/get_team— when the team isn't obvious from the project.
Then create with save_issue (omit id to create). labels and assignee accept
names or IDs; priority is the 0–4 int.
Description template
Keep what makes implementation unambiguous; drop ceremony:
<one-line summary of the outcome>
## Context / problem
<why this exists; the symptom or goal; link related issues/PRs>
## Scope
<what's in; explicitly what's out>
## Acceptance
<how we'll know it's done — checkable bullets>
Use real newlines and markdown, not escaped \n. Mention related issues by ID so
Linear links them (and add them to relatedTo).
Gotchas
- Don't guess the project — the one unrecoverable mistake. Ask if unsure.
- Estimate snaps to the team's scale (a passed
3stores as4on an exponential team) — read back and surface the stored value so the snap isn't silent; and some teams disable estimates entirely — drop the field if it's rejected. - Labels must already exist — pull them from
list_issue_labelsand pass the exact names; creating ad-hoc labels pollutes the taxonomy. Prefer one Type + one Area. - Milestone belongs to a project, cycle belongs to a team — don't cross them; a milestone from another project will be rejected.
- Don't rely on cycle auto-add — some teams disable it, leaving the issue out of every cycle. Set the current cycle explicitly; skip only for backlog/future work.
- One pass, not two — if you're unsure of priority/estimate, pick a sensible value and say so; don't ship a bare issue and wait to be asked for the rest.
Pre-flight checklist (before save_issue)
- Project resolved (from context/confirmed/asked) — not guessed.
- Team set; title imperative + specific; description has context + scope + acceptance.
- Priority set; estimate set (or knowingly skipped if the team disables it).
- Labels: a Type (always) + an Area if one fits — from the existing taxonomy, not invented.
- Assignee set (or deliberately left for triage); milestone attached if one fits.
- Relations linked for any issues/PRs referenced.
- Anything you judged (priority/estimate) stated back to the user in your reply.
See also
conventional-commits— the matching discipline for commit/PR titles, so the issue → branch → PR → release chain stays clean.
Sources
- Linear MCP tool surface (
save_issue,list_projects,list_issue_labels,list_milestones,list_cycles,list_users,get_team) and observed behaviour: estimates snap to the team's scale, new issues auto-join the active cycle when the team enables auto-add (don't rely on it), labels are a grouped Type/Area taxonomy that must pre-exist.