linear-strict
Provides tools for interacting with Linear issues, comments, projects, teams, cycles, and initiatives. Enforces structured ticket descriptions, comment typing, drift detection, validated section patches, claim-based completion, Done-gate checks, and hands-off labels for agent workflows.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@linear-strictread ENG-412 whole, report drift, then claim it"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
linear-strict
Unofficial and opinionated. This is an independent project, not affiliated with or endorsed by Linear. It enforces one team's way of keeping tickets current, and it refuses writes that other Linear servers would make. For Linear's own MCP server, see linear.app/docs/mcp.
An MCP server for Linear for teams where agents keep tickets up to date. It reads a ticket whole and treats the description as the ticket's current state. The rules are enforced in the server, so a prompt that goes unread or a client hook that stops matching can't switch them off.
It has one runtime dependency, the MCP SDK. It began as a fork of tacticlaunch/mcp-linear (MIT), whose OAuth login it keeps.
The problem it addresses
Linear keeps full history, yet agents working from it drift:
State ends up in comments. A comment answers the ticket's open question and the description still says it is open. Nothing marks which claim is current.
Reads are lossy without saying so. Listings cut descriptions short, comment APIs default to newest first, and summaries read like the whole ticket.
Tickets change after they are read. An agent works from a snapshot, acceptance criteria are added later, and the work ships without them.
Rules in client hooks go dark when a server is renamed and the matcher no longer fires.
Related MCP server: Linear MCP Server
How it works
Description is state, comments are the log. The description has named sections:
Observed,Cause,Fix,Done when,Open questions. It changes only through validated section patches. AnObservedline must readYYYY-MM-DD · source · result(a time after the date is fine), andDone whenlines must be checklist items.A reconciled marker is the description's HEAD. It records the last comment the description accounts for, when that was checked, and the hash of the description it was checked against. It lives in one attachment on the ticket, titled "linear-strict: description reconciled through …", so the description stays clean. Every read reports comments after it, comments edited since the check, and edits to the description made outside this server, as
drift.Repair on read. Not everyone on a team will use this server.
get_issuereports formatfindingsanddrifton tickets written from any client, and tells the agent to fold them into the description.Whole reads. Every comment, oldest first, across all pages.
list_issuesand the workspace lists (teams, cycles, projects, initiatives) walk every page too, so an agent never holds a cursor it can stop following. Anything not fetched is listed inomitted; a gap is never silent.Typed comments.
evidence,correction,ask,answerandclosed_by. A correction must carry the description patch that makes it true. An answer flips its question row.closed_byalso sets the Linear relation.Writes name what they were written against.
get_issuereturns a hash of the description,description_sha. A patch passes it asbaseand is refused, with what changed, if the description moved since that read. Linear has no conditional update, so this is how a patch shows it was built from the current text.Claim, then a Done gate.
claimrecords the description as it stands. Moving to a completed state needs aDone whensection with every item ticked and cited (- [x] item · <SHA, PR, file:line, link, CI run, Observed 2, or a command and its result>), any cited PR that is linked to the ticket merged, and your claim, and is refused with a diff if the description changed since then. Priority or label changes don't count. Dropping an unticked item needs a reason and a yes from the person at the client, or from a model judge in unattended sessions.Shipped-state facts. A ticket marked Done or Merged with no linked pull request, or with PRs merged only into a non-main branch, gets a finding. The facts come from Linear's GitHub attachment metadata.
A hands-off label. A ticket labelled
no-agents(configurable) is people-only: every write through this server is refused, and reads still work.Authorship. An agent (app) token writes as the agent. A personal key writes comments headed
🤖 <agent> via <person>. Each comment on a read is markedagentorperson, with the basis for that call.
Related work
Linear's agent best practices warn that "Comments may not be reliable to read from, as they are editable and may have changed since your agent’s last run." Their answer, Agent Activities, covers agents running in Linear's Agent Sessions. Here,
driftlists comments edited after the description accounted for them.Linear's agent team found it "more effective to encode constraints into the design of Linear Agent’s tools than to spell them out in a prompt", which is the approach this server takes.
claimfollows their delegation model: a person stays the assignee, accountable for the result, and the agent is the delegate.Linear keeps version history and text attribution for documents.
description_historyreads the same snapshots for an issue's description.OpenAI's Symphony keeps an agent's progress in one persistent comment per ticket and tells the agent to leave Backlog tickets alone. This server keeps that state in the description, which Linear versions and every client shows first, and enforces the hands-off label in the server rather than in the prompt.
Cyrus has each sub-issue's agent hand back verification commands for the parent to run, and openclaw-linear-plugin has a separate auditor so the worker "cannot self-certify". The Done gate here asks for cited evidence but still lets the agent that did the work supply it.
Staleness in the wild: herdr-factory#97 shipped work against a ticket snapshot that lacked acceptance criteria added later, trac-mcp#57 had an agent stop trusting an MCP server after silent data loss, and beads#3708 and catalyst-otel#68 had Linear mirrors go stale without saying so.
Install
Quickstart (Claude Code)
Get a Linear credential. A personal API key (Linear → Settings → Security & access → Personal API keys) writes as you. An agent (app) token, an OAuth token for a Linear app with
actor=appstarting withlin_oauth_, writes under the agent's own identity and can be set as a ticket's delegate.Add the server and the sign-off hooks:
npm install -g https://github.com/justinstimatze/linear-strict/releases/download/v0.1.0/linear-strict-0.1.0.tgz claude mcp add linear-strict -e LINEAR_API_TOKEN=<token> -- linear-strict linear-strict installReconnect with
/mcp, then ask the agent to read a ticket.
You need Node 22 or later. Each GitHub release carries the built package; it is not on npm. To upgrade, npm install -g the newer release's .tgz, then run linear-strict install again and reconnect.
To work on it, run it from a checkout instead:
git clone https://github.com/justinstimatze/linear-strict.git
cd linear-strict && npm ci && npm run build
claude mcp add linear-strict -e LINEAR_API_TOKEN=<token> -- node "$PWD/dist/index.js"
node dist/index.js installAfter a git pull, run npm run build again and reconnect the server.
Pin the version, and give the server its own name, linear-strict. Tool names such as get_issue also exist on Linear's official server, so the server name is what tells an agent and any hook matcher which rules apply. To sign in through the browser instead of pasting a token, see OAuth login.
The two hook installers
linear-strict installadds the sign-off hooks to~/.claude/settings.json, once per machine.install --statussays whether they are installed and whether they can still run;install --uninstallremoves them and nothing else. Installed through npx, the hooks run the same pinned version through npx, since npm prunes the cache npx runs from. After upgrading, runinstallagain so the hooks match the server; until then the server asks through the form.examples/claude-code-hooks/install.shis optional and per project: it refuses ticket writes through other Linear servers and runs a project's own Linear checks on strict writes (Blocking writes through other Linear servers). Its hooks run its scripts by path, so run it from a checkout or the global install above, not through npx.
The two write different entries and can both be installed.
Other clients
Claude Desktop, in claude_desktop_config.json, after the global install above:
{
"mcpServers": {
"linear-strict": {
"command": "linear-strict",
"env": { "LINEAR_API_TOKEN": "<token>" }
}
}
}Everything except sign-off works the same in any MCP client. Sign-off depends on what the client offers:
Client | How a descope is approved |
Claude Code with |
|
Claude Code without the hooks | An elicitation form, with rows of about 100 characters |
Other clients that support MCP elicitation | That client's elicitation form |
Clients without elicitation, Claude Desktop included as far as its docs say | Refused; a person makes the edit in Linear, or run with |
Hooks are a Claude Code feature, so no other client gets the preview route.
Sign-off
Dropping or rewording an unticked Done when item removes a check that has not passed, so someone other than the agent approves it. LINEAR_STRICT_SIGN_OFF picks who:
person(the default): the person at the client. In Claude Code with the sign-off hooks installed,set_statehands the agent anAskUserQuestionto put to them, and the change is shown in full in its preview box. A hook refuses the question if the agent changes a word of it, another hook records the answer, and the retry is approved from that record, never from what the agent says. Elsewhere, and in Claude Code without the hooks, the server asks through an MCP elicitation form, which Claude Code shows as rows of about 100 characters.judge: a model with no stake in the ticket decides, so an unattended session never waits for someone who isn't there. It reads the ticket's description, the change, the reason and the risk, approves only when the description backs the reason, and the descope comment names the model and gives its reason for a person to review later. It needs an Anthropic API key:linear-strict auth judge-key setsaves one from a hidden prompt to$XDG_CONFIG_HOME/linear-strict/anthropic-api-key(mode 600), next to theauth logincredentials, or setANTHROPIC_API_KEYin the server's environment, which wins. A key of its own, in a workspace with a spend limit, keeps the judge's cost on its own line.LINEAR_STRICT_JUDGE_MODELoverrides the model (defaultclaude-opus-5-5). Each verdict is one API call of about 2 seconds, roughly 900 input tokens (most of them the cached brief) and 90 output tokens, well under a cent at Opus 5.5's rates (measured 2026-09-27). If the call fails (no credit, an outage, a refusal), the descope is refused with the error and nothing changes. MCP sampling would let the judge run on the client's own model with no key, but Claude Code doesn't offer it to servers (2.1.283 declareselicitationandrootsonly).
The hooks only guard against an agent cutting corners. An agent with a shell could still write an answer record by hand; a third hook refuses tool calls that name the records' directory, which closes the obvious route.
Blocking writes through other Linear servers
The server can only enforce its rules on writes that go through it. If Linear's official server is also connected, an agent can still edit a ticket there. examples/claude-code-hooks has Claude Code hooks that refuse ticket writes through other Linear servers and run a project's own Linear checks on strict writes. They are optional, and they are the only part of this setup that lives in the client.
OAuth login
linear-strict auth login signs in through the browser and stores a refreshing token, which the server uses when no token is set in its environment. It needs a Linear OAuth application of your own: create one at https://linear.app/settings/api/applications/new with the redirect URI http://localhost:8734/callback, then:
linear-strict auth login --client-id <client id> # global install
node dist/index.js auth login --client-id <client id> # from a checkoutThe flow uses PKCE, so a client secret is optional. auth status shows whether you're signed in and when the token expires. auth logout revokes the token and deletes it. Credentials live in $XDG_CONFIG_HOME/linear-strict/credentials.json, readable only by you.
Configuration
Variable | Default | Purpose |
| — | Personal API key, or a |
| — | Any OAuth access token, sent as Bearer |
|
| Branch a PR must merge into for Done to count as shipped |
|
| Environment named in |
|
| Comma-separated labels that make a ticket people-only: every write through this server is refused, reads still work |
|
| Who approves dropping an unticked |
|
| The model that decides when |
| — | The judge's key, if not saved with |
|
| Where claim records and pending sign-offs are kept |
|
| Where |
|
|
|
| — |
|
Claim records live on the machine running the server. A Done check from a machine with no claim on record is refused.
One server per connection
Claude Code's /mcp reconnect starts a new server and leaves the old one running with its pipes open, so the old one never sees its input close. Each server records its pid under LINEAR_STRICT_STATE_DIR/instances, keyed by its parent process and launch settings. When a newer server has replaced it and it has served no tool call for a minute since, the older one exits. A server whose parent exits, or whose input closes, exits too.
Reconciled marker
Each ticket this server has reconciled carries one attachment titled "linear-strict: description reconciled through date". It records the last comment the description accounts for, when that was checked, and a hash of the description at the time, so the next agent to read the ticket knows which comments are new and whether the description was edited elsewhere since. Deleting it does no harm: agents then check the whole thread again, and the next reconcile puts it back. It is written by whoever runs this server, not by Linear.
Tools
Tool | What it does |
| Whole ticket, plus |
| Past versions of the description with who made each and a diff; |
| Every matching ticket in one call, paged to the end by the server: identifier, title, state, assignee, delegate and |
| Take a ticket and snapshot its description; refuses one another agent holds |
| Whether the description changed since your claim, with a diff |
| Patch description sections and/or move the reconciled marker |
| Typed comment: |
| Move to a workflow state; completed states pass the Done gate |
| Priority, owner, labels, cycle, project, milestone, parent, dates and relations; never the description or state |
| New ticket with validated sections |
| Teams with their workflow states in board order |
| Cycles, active and next by default; pair a number with |
| Open projects and initiatives with status, owner and dates |
| Your inbox as pointers (ticket, type, actor, time), no excerpt text, paginated |
| Mark handled notifications read |
| The user or app behind the token, which is who claims and |
The server also returns these rules as MCP instructions on initialize, so an agent learns the workflow when it connects. TOOLS.md has each tool's arguments, and docs/design.md the reasoning behind the rules, their limits, and what is still open.
Development
npm test # typecheck, lint, unit tests, MCP smoke test, and the sign-off routes end to end
npm run build
node scripts/e2e/sign-off.mjs --live-judge # the same, with the judge on the real API (one call, well under a cent)
npm run test:live # against a real workspace: creates temporary tickets on LIVE_TEAM and deletes them
npm run eval # a model works tickets in the fake Linear through the strict tools; graded on final state
npm run format # Prettier; `npm test` fails on unformatted codegit config core.hooksPath hooks once, after cloning, turns on the tracked pre-commit hook: a non-blocking CodeScene delta check on staged changes when cs is on PATH. It warns and never blocks the commit.
npm run test:live needs LINEAR_API_TOKEN and LIVE_TEAM (a team key). It writes to that workspace. npm run eval needs ANTHROPIC_API_KEY; evals/README.md covers cases, caching and results.
License
MIT. See LICENSE.md; the OAuth login code is from tacticlaunch/mcp-linear and keeps its notice.
Available Tools
17 toolscheck_claimARead-onlyIdempotent
Whether the description changed since your claim, with a line diff. Run before opening or merging a PR for the ticket.
| Name | Required | Description | Default |
|---|---|---|---|
| issue | Yes | Issue identifier (e.g. ENG-123) or UUID |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds the temporal scoping ('since your claim') and the diff output shape. However, it doesn't say what happens when no claim exists or what the diff looks like in edge cases, leaving gaps beyond the annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with zero filler; the core behavior and the invocation trigger are both front-loaded. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With rich annotations, a fully documented parameter, and an existing output schema, the description covers what the tool does and when to call it. Only minor edge-case behavior (no prior claim, empty diff) is missing, which is not essential for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single `issue` parameter is fully documented in the schema with a format example (ENG-123 or UUID). The description adds nothing parameter-specific, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific check: whether the ticket description changed since the caller's claim, plus a line diff of the change. It's phrased as a question rather than a verb+resource statement, but an agent can identify the operation. It relates to the `claim` and `description_history` siblings without explicitly distinguishing itself from them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit timing guidance: 'Run before opening or merging a PR for the ticket.' This gives clear context for invocation. It does not name alternatives (e.g., description_history) or state when not to use it, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
claimADestructive
Take a ticket and record the description as it stands, so a later Done check can tell whether it changed underneath you. Sets assignee to you when the ticket is unowned; sets delegate to you when a human owns it and you are an agent (app) identity. Refuses a ticket another agent holds. Claiming again after a change is how you acknowledge the new description.
| Name | Required | Description | Default |
|---|---|---|---|
| as | No | Override the automatic choice | |
| issue | Yes | Issue identifier (e.g. ENG-123) or UUID | |
| take_over | No | Take the assignment from the person who holds it. Only when they handed it to you; a ticket held by another agent is never taken. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations flag it as destructive, non-read-only and non-idempotent, and the description adds substantial context beyond them: the refusal rule for other agents, the identity-dependent assignee/delegate behavior, and that re-claiming after a change is an acknowledgement act. These are behavioral traits the annotations cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tightly packed sentences that lead with the core action and effect, then the routing rules, then the re-claim case. Dense but every clause carries information; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be described. Combined with the annotations, the description covers identity semantics, refusal conditions, and the acknowledgement workflow, leaving no significant gap for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the schema baseline is 3; the description adds meaning by explaining the automatic assignee/delegate choice that the 'as' override modifies, and reinforcing the take_over restriction. It goes beyond restating the schema, though it does not detail format for 'issue'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
It states a specific verb and resource ('Take a ticket and record the description as it stands') and immediately differentiates the action from its sibling check_claim by explaining the later Done check that consumes the record. An agent can tell what this does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit about when it applies (assignee when unowned, delegate when a human owns and you are an app identity), when it refuses (a ticket held by another agent), and the re-claim workflow as acknowledgement. This is when/when-not guidance rather than implied usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
commentADestructive
Post a typed comment. evidence: a finding, optionally with an Observed patch. correction: must carry the description patch that makes the description say the corrected thing. ask: adds an OPEN row to Open questions. answer: must name the row it closes (answers: "Q3") and flips it to ANSWERED with a link. closed_by: this ticket's work landed under another ticket; names it (closed_by), sets the Linear relation (relation "duplicate" or "fixed_there") and records it under Fix. Move the state separately with set_status.
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | Required with patch. description_sha of the description this patch was written against: from get_issue, or from your last write to this ticket. The write is refused, with what changed, if the description has moved since. | |
| body | Yes | Comment text. For ask, the first line becomes the question row. | |
| kind | Yes | ||
| issue | Yes | Issue identifier (e.g. ENG-123) or UUID | |
| patch | No | Description sections to change. Impact is the one plain-language line at the top saying who notices this work (mode replace). Observed lines must be "YYYY-MM-DD · <source: command, SHA or query> · <what it showed>". Done when lines must be checklist items ("- [ ] <check that proves it>"). Open questions changes only through comment kinds ask and answer. | |
| ask_to | No | For kind ask: who should answer | |
| answers | No | For kind answer: the question id, e.g. Q3 | |
| relation | No | For kind closed_by: duplicate (same problem) or fixed_there (a different ticket whose change fixed this one) | |
| closed_by | No | For kind closed_by: the ticket that carried the work | |
| author_label | No | Agent name for the comment header, e.g. the model. With a personal API key the header reads "<author_label> via <you>"; with an agent (app) token it defaults to the agent identity. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare a destructive, non-idempotent write, and the description adds rich behavioral detail beyond that: base is a stale-write guard that refuses with a diff, answer flips a row to ANSWERED with a link, closed_by sets a Linear relation and records under Fix. This is substantive disclosure for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action and then organizes by kind labels, with no filler. The single dense paragraph is slightly hard to scan for 10 parameters, but every sentence carries necessary information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and annotations covering the safety profile, the description need not explain returns. It covers kind semantics, patch requirements, base staleness handling, and cross-tool routing, which is complete for this tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 90%, so the schema already documents most parameters. The description still adds conditional meaning, such as correction requiring the description patch and answer requiring the question id, but much of it overlaps with the schema's own per-field descriptions. A 4 reflects modest added value over a very complete schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Post a typed comment') and then enumerates the five comment kinds with their distinct purposes. It also explicitly distinguishes itself from set_status, so an agent can route correctly without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives per-kind usage conditions: evidence for findings, correction for description patches, ask/answer for the open-questions row, closed_by for work landed elsewhere. It names the alternative for state changes ('Move the state separately with set_status'), which is explicit when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_issueA
Create a ticket. Its description is built from named sections (Observed, Cause, Fix, Done when), checked the same way set_state checks them, so the ticket starts in the form every other tool expects. Include a Done when section if the ticket will be closed through set_status.
| Name | Required | Description | Default |
|---|---|---|---|
| team | Yes | Team key, e.g. ENG | |
| title | Yes | ||
| parent | No | Parent issue identifier or UUID | |
| sections | No | Description sections to change. Impact is the one plain-language line at the top saying who notices this work (mode replace). Observed lines must be "YYYY-MM-DD · <source: command, SHA or query> · <what it showed>". Done when lines must be checklist items ("- [ ] <check that proves it>"). Open questions changes only through comment kinds ask and answer. | |
| project_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=false. The description adds genuinely useful behavior beyond that: sections are validated the same way set_state validates them, and the ticket "starts in the form every other tool expects," which tells the agent the creation guarantees a canonical shape. It does not cover permissions or failure modes, so not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core action, then the section model, then the conditional Done-when rule. No waste or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, so return values need not be explained. Annotations cover the safety profile. The description supplies the key cross-tool behavioral contract (section validation parity, canonical form) but leaves minor gaps such as the Impact section mentioned only in the schema and no note on team/title requirements.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 60%, so the schema already documents team, parent, sections (with detailed formatting rules) and project_id, leaving title and project_id thinner. The description reinforces the section model and its relationship to set_state, but omits the Impact section and adds no syntax beyond what the schema states. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Starts with a specific verb+resource ("Create a ticket"), so the agent immediately knows the operation. It also references sibling tools (set_state, set_status) to explain how the created ticket behaves, though it doesn't contrast with other creation-adjacent siblings. Clear, with partial sibling context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives one conditional rule: include a Done when section if the ticket will be closed via set_status. That is useful context but is guidance about a section rather than when to choose create_issue itself. No exclusions or alternative-selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
description_historyARead-onlyIdempotent
The description's past versions, from the snapshots Linear saves as it is edited: when, by whom, and a line diff against the version before. current says whether the live description is in a version yet, with a diff if not. With blame, every line of the current description names the version that introduced it and who made that version. Use it to see when and by whom a section or tick changed before overwriting or disputing it.
| Name | Required | Description | Default |
|---|---|---|---|
| blame | No | Also attribute each current line to the version that introduced it | |
| issue | Yes | Issue identifier (e.g. ENG-123) or UUID |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safe read-only, idempotent, non-destructive profile, so the bar is lower. The description adds behavioral context beyond annotations by explaining snapshots, line diffs against the previous version, what `current` means, and how blame attributes each line to a version and author.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with a clear definition and proceeds logically through return semantics, blame behavior, and usage. It is appropriately sized for a tool with an output schema, though the `current` and `blame` sentences overlap somewhat with structured documentation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering safety and an output schema covering return fields, the description supplies all remaining context an agent needs: what the tool retrieves, what blame does, and when to reach for it. Nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters, establishing a baseline of 3. The description elaborates on the `blame` effect and mentions `current`, but adds little syntax or meaning beyond what the schema already provides for `issue` and `blame`.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the resource: past versions of a description, with when, by whom, and line diffs. It is specific about what the tool returns, though it does not explicitly differentiate itself from sibling tools like get_issue or comment.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to use it: to see when and by whom a section or tick changed before overwriting or disputing it. No alternative tools or when-not conditions are named, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_issueARead-onlyIdempotent
Read one ticket whole: full description, every comment oldest-first (all pages), who edited the description and when, relations, children, attachments. omitted lists anything not returned; an empty list means nothing was left out. findings lists format problems in the description and drift.unreconciled_comments lists comments the description may not reflect yet, and drift.edited_after_reconcile comments edited after it accounted for them. When drift.needs_reconcile is true, fold what those comments establish into the description with set_state (reconciled_through = newest comment id) before acting on the ticket. Tickets written from other clients get repaired this way. Pass issue.description_sha as base to the write that patches the description.
| Name | Required | Description | Default |
|---|---|---|---|
| issue | Yes | Issue identifier (e.g. ENG-123) or UUID |
Output Schema
| Name | Required | Description |
|---|---|---|
| claim | No | Your claim on this ticket and whether the description changed since |
| drift | No | Comments after the reconciled marker, needs_reconcile and next_step |
| issue | No | Full description and fields, description_sha (pass it as base when you patch the description), and open_questions parsed from the description |
| omitted | No | Anything not fetched, with the reason; empty means nothing was left out |
| children | No | Sub-issues |
| comments | No | Every comment, oldest first, each with author_kind (agent or person) and its basis |
| findings | No | Format and shipped-state problems to fix with set_state |
| relations | No | Blocks, duplicates and related tickets, both directions |
| attachments | No | Other attachments |
| comment_order | No | Always oldest first |
| pull_requests | No | Linked GitHub PRs with status, target branch and merge time |
| description_edits | No | Who changed the description and when, oldest first |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so safety is covered. The description goes further by disclosing retrieval behavior (all comment pages, oldest-first) and the semantics of derived fields like `omitted` and `drift.unreconciled_comments`, plus the repair workflow for tickets edited by other clients. Return format details are partly duplicated by the output schema, but the drift semantics are genuinely additive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first clause, and every subsequent sentence carries substantive meaning for a tool with this many return structures. The middle sentences are dense run-ons packing several field semantics together, which costs a little readability but not enough to call it bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description does not need to spell out every returned field, and it correctly focuses on interpretation (omitted, findings, drift) and the reconcile-first workflow. An agent has enough to call the tool and act on results, though the relationship to description_history for non-full reads is left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a single parameter already documented in-schema as 'Issue identifier (e.g. ENG-123) or UUID'. The description adds no syntax or format nuance for `issue` itself (description_sha is a field of the ticket, not the argument), so the baseline of 3 for high-coverage schemas applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource ('Read one ticket whole') and enumerates exactly what is retrieved: description, comments oldest-first across all pages, editors, relations, children, attachments. This clearly separates it from list_issues (multiple tickets) and comment (writes) among the siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete follow-up guidance: when drift.needs_reconcile is true, fold the flagged comments into the description via set_state using reconciled_through, and pass issue.description_sha as the base for the description patch. That names the alternative tool and the triggering condition, though it never explicitly says when to prefer get_issue over description_history.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_cyclesARead-onlyIdempotent
Cycles, earliest first. Defaults to the active and next cycle. Use a cycle number with list_issues (cycle + team) to see its tickets.
| Name | Required | Description | Default |
|---|---|---|---|
| team | No | Team key; omit for every team | |
| when | No | current (active and next, default), upcoming, past or all |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly, idempotent, non-destructive, and non-open-world behavior, so the safety profile is covered. The description adds genuinely useful behavior the annotations cannot convey: results are ordered earliest-first and the default window is the active and next cycle.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with ordering and default scope front-loaded ahead of the cross-reference. Every clause carries information an agent can act on.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description need not explain return values, and the annotations cover safety. What remains is ordering and default scope, both stated; only a brief note on pagination or team-scoping behavior is absent, which is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both the team key and the when enum are fully documented in the schema; the description restates the default value ('active and next cycle') without adding format or syntax detail. The reference to a 'cycle number' describes a list_issues parameter rather than this tool's own inputs, so there is no real gain over the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The fragment 'Cycles, earliest first' names the resource and its ordering, and the follow-up sentence clarifies scope by noting the default of active-plus-next cycles. The verb is only implied (list), but the content is specific enough to separate it from list_issues, list_teams, and other siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the default scope and explicitly routes the agent to list_issues with a cycle number plus team to see a cycle's tickets, which is a concrete handoff condition. It does not state when-not to use this tool or contrast it with other listing tools, so it falls short of full when/when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_initiativesARead-onlyIdempotent
Initiatives with status, owner and target date. Unfinished ones only unless include_closed.
| Name | Required | Description | Default |
|---|---|---|---|
| include_closed | No | Include completed initiatives |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the safety burden is lifted. The description adds a real behavioral fact not in the annotations: the default result set silently excludes completed initiatives unless include_closed is set. That is the kind of default-behavior disclosure that prevents miscalls.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short, front-loaded sentences with no filler. Slightly telegraphic ('Initiatives with status, owner and target date' reads as a fragment), but every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need no explanation, and annotations cover the safety profile. The description supplies the only missing piece an agent needs — the default filtering behavior — so it is essentially complete for a one-parameter list tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter's description ('Include completed initiatives') is already documented structurally. The description reinforces the include_closed semantics by stating the default filter, but adds no format or edge-case detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names the resource (initiatives) and the fields it surfaces (status, owner, target date), so the agent knows what listing this returns. It does not differentiate from the many list_* siblings (list_issues, list_projects, list_cycles, list_teams), but the resource itself is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The second sentence defines the default scope ('Unfinished ones only unless include_closed'), which is genuinely useful selection guidance. However, there is no statement of when to prefer this tool over alternatives or any prerequisite context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_issuesARead-onlyIdempotent
Every ticket matching the filters, in one call: the server pages through Linear to the end, so the answer is the whole set (total, by_state, and one row per ticket under columns). Rows hold identifier, title, state, assignee, delegate and updatedAt; there are no description excerpts, so read a ticket with get_issue before acting on it. More than 2000 matches is refused; narrow with open, state, cycle, project, assignee_is_me or delegate_is_me. When a task covers a set, work every row.
| Name | Required | Description | Default |
|---|---|---|---|
| open | No | Only tickets not in a completed or canceled state | |
| team | No | Team key, e.g. ENG | |
| cycle | No | Cycle number within team (list_cycles gives them); needs team | |
| query | No | Full-text search term. Omit to list by most recently updated. | |
| state | No | Workflow state name, e.g. "In Progress" | |
| project | No | Project name or id | |
| assignee_is_me | No | ||
| delegate_is_me | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | No | One array per ticket: identifier, title, state, assignee, delegate, updatedAt; no descriptions |
| total | No | How many tickets match; rows holds every one of them |
| columns | No | Names of the values in each row, in order |
| by_state | No | Count of matching tickets per workflow state |
| complete | No | Always true: a partial set is refused, never returned |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile, but the description adds substantial non-obvious behavior: server-side pagination to completion, a hard refusal above 2000 matches, and the exact row columns returned. These are operational traits the annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, front-loaded with scope, then return shape, then constraints and routing. No filler; every clause carries information (cap, pagination, columns, alternative tool).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Even though an output schema exists, the description clarifies what the rows actually contain and the failure mode at 2000 matches. Combined with annotations and schema, an agent has everything needed to call and interpret this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 75%, so the schema already documents most params. The description enumerates the narrowing filters, which adds modest signal about which params constrain the result set, but does not add format or syntax detail beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Every ticket matching the filters, in one call') and distinguishes itself from get_issue by noting rows hold no description excerpts. An agent can tell what it returns and how it differs from the sibling detail tool without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: 'read a ticket with get_issue before acting on it', and 'narrow with open, state, cycle, project, assignee_is_me or delegate_is_me' when matches exceed 2000. Also names the use case 'when a task covers a set, work every row'. Covers when-to-use, when-not (too broad), and the alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_projectsARead-onlyIdempotent
Projects with status, lead, teams, dates and progress. Open projects only unless include_closed.
| Name | Required | Description | Default |
|---|---|---|---|
| team | No | Team key | |
| include_closed | No | Include completed and canceled projects |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds non-obvious behavior beyond that: results are filtered to open projects by default, which an agent would not know from the schema alone. It does not mention any pagination or result-limit behavior, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, no filler, with the returned-field summary front-loaded and the filtering caveat placed last where it is actionable. Nothing here is wasted or redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not explain return values, and it correctly covers the default filtering behavior for a simple two-parameter read tool. The only mild gap is the team scoping parameter, which is left entirely to the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters (team key, include_closed flag), making 3 the baseline. The description restates include_closed's semantics ('Open projects only unless include_closed') but says nothing about the team parameter's scoping behavior, so it adds little beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (projects) and enumerates the returned fields (status, lead, teams, dates, progress), which combined with the tool name 'list_projects' makes the operation unambiguous. It is distinguishable from sibling list_* tools (list_teams, list_issues, list_cycles), though it never states the verb explicitly and reads as a field listing rather than an action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The clause 'Open projects only unless include_closed' tells the agent when the default behavior applies and how to widen it, which is real usage guidance. However, no alternatives are named and there is no statement about when to prefer this tool over, say, list_issues or list_cycles when scoping a query.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_teamsARead-onlyIdempotent
Every team with its key and workflow states in board order. State names are what set_status takes.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds genuinely useful context beyond them: entries are returned in board order and the returned state names are the valid inputs for set_status, which is a cross-tool contract not captured anywhere in structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short, declarative sentences with no filler, and the content description is front-loaded before the set_status cross-reference. Every sentence carries information an agent can act on.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description is not obliged to detail return values, and the annotations cover the safety profile. The set_status linkage supplies the main missing rationale for calling it, leaving little an agent needs that is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline of 4 applies; there is nothing for the description to disambiguate. Schema coverage is reported at 100% with an empty property set, leaving no semantic gap to fill.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (teams) and enumerates what each entry contains (key plus workflow states in board order), so an agent knows exactly what comes back. It does not explicitly distinguish itself from sibling list tools like list_projects or list_cycles, but the resource naming makes the boundary self-evident.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: by noting that 'state names are what set_status takes,' it signals this is the lookup to run before calling set_status. There is no explicit when-to-use or when-not-to-use framing and no named alternative to prefer in other situations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mark_notifications_readAIdempotent
Mark notifications read once you have handled them. Reports each id separately.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | Ids from notifications |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true, destructiveHint=false and readOnlyHint=false, so the safety and repeatability profile is covered. 'Reports each id separately' hints at per-id outcome reporting, but with an output schema present that detail is already documented structurally, so the description adds only modest value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with the action and the timing cue front-loaded ahead of the reporting note.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-required-param tool with full schema coverage, annotations, and an output schema, the description covers the intent and the per-id reporting behavior. It is complete enough to invoke correctly, though it could say more about bulk failure handling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single 'ids' array parameter is fully described in the schema as 'Ids from notifications'. The description adds no syntax, ordering, or batch-limit meaning beyond that, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('mark notifications read') and scopes it with 'once you have handled them'. It is clearly distinguishable from the read-oriented sibling 'notifications', though it never names or contrasts with a sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'once you have handled them' gives an implied precondition for use, but there is no when-not guidance and no mention of alternatives such as the 'notifications' listing tool. Adequate but leaves routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notificationsARead-onlyIdempotent
Your Linear inbox, newest first, as pointers: ticket, notification type, who did it (agent or person) and when. Excerpt text is left out, so read the ticket with get_issue before acting. Unread only by default; paginated with next_cursor.
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | next_cursor from the previous call | |
| first | No | How many to return, default 50 | |
| since | No | Only notifications created on or after this date, e.g. 2026-09-24 | |
| unread_only | No | Default true |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | How to use these results |
| order | No | How results are ordered |
| has_more | No | True when more results exist; pass next_cursor as after |
| next_cursor | No | Cursor for the next page |
| unread_count | No | Linear's unread count |
| notifications | No | Pointers: id, type, time, read, actor, actor_kind and the ticket |
| stopped_early | No | Present when a later page failed; next_cursor resumes there |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a safe, idempotent read, so the bar is lower, yet the description adds real value: excerpt text is deliberately omitted, so a follow-up get_issue call is required before acting, and unread-only filtering is the default. It doesn't mention rate limits or the notification-type vocabulary, but the behavioral caveat it does give is the one an agent would otherwise get wrong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with what the tool is, then the critical caveat, then defaults. No sentence is filler; each carries a distinct fact.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the description still covers the three things an agent needs: the pointer-only return shape, the pre-action read requirement, and pagination/default filtering. Nothing required to call it correctly is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so 'unread_only' default true and cursor paging are already documented in the schema; the description only restates them at a high level. Baseline 3 is appropriate — no new syntax, format, or constraint meaning is added.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource ('Your Linear inbox') plus ordering ('newest first') and the exact shape of each row (ticket, notification type, actor, timestamp). An agent can distinguish it from sibling list tools like list_issues and from the mutating mark_notifications_read without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent onward ('read the ticket with get_issue before acting') and states the default filter and paging behavior. What's missing is a direct comparison point against mark_notifications_read or list_issues, but the when-to-use context is otherwise clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_fieldsADestructive
Change a ticket's fields other than its content: title, priority, assignee or delegate, labels, cycle, project, milestone, parent, due date, estimate, and relations to other tickets. The description changes only through set_state and the workflow state only through set_status. Names are resolved to ids first and the whole call is refused if any is unknown or ambiguous, so nothing is half-applied. Taking a ticket from its current assignee needs take_over; another agent's ticket, or one delegated to someone else, is refused.
| Name | Required | Description | Default |
|---|---|---|---|
| cycle | No | Cycle number, "current", "next", or null to remove it from its cycle | |
| issue | Yes | Issue identifier (e.g. ENG-123) or UUID | |
| title | No | ||
| blocks | No | Issue identifiers this ticket blocks | |
| parent | No | Parent issue identifier, or null | |
| project | No | Project name or id, or null | |
| assignee | No | Name, display name, email or id, "me", or null to unassign | |
| delegate | No | Agent (app) user to delegate to, "me", or null to clear | |
| due_date | No | YYYY-MM-DD, or null | |
| estimate | No | ||
| priority | No | 0 none, 1 urgent, 2 high, 3 medium, 4 low | |
| milestone | No | Milestone name in the ticket's project (or the project set in this call), or null | |
| take_over | No | Required to change a person's assignment to someone else | |
| add_labels | No | Label names on the team or workspace. Labels are not created here. | |
| blocked_by | No | Issue identifiers that block this ticket | |
| related_to | No | Issue identifiers to mark as related | |
| remove_labels | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and non-idempotent, so the mutation profile is known. The description adds genuinely useful behavior beyond that: all-or-nothing atomicity (names resolved first, whole call refused if any is unknown or ambiguous) and the permission rule that reassigning a person's ticket requires take_over.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each front-loaded and load-bearing: field scope, sibling routing, atomicity, then permission rules. Dense but no filler sentences; the field enumeration is the longest part but earns its place by scoping the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained. For a 17-parameter mutation tool the description covers scope, atomicity, and permission gates well; only minor gaps remain (e.g., whether omitted fields are left untouched).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 82%, so the schema carries most parameter meaning (baseline 3). The description supplements this by grouping the mutable fields and clarifying the take_over requirement and the assignee-refusal rule, adding semantics the schema cannot express.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (change) and resource (ticket fields) and immediately enumerates the field categories it covers, while explicitly excluding content and workflow state. It names the sibling tools that own those exclusions (set_state, set_status), so an agent can distinguish it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Routes the agent to alternatives with conditions: description changes go through set_state and workflow state through set_status. It also gives a clear precondition for the take_over flag and states that another agent's ticket, or one delegated to someone else, is refused.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_stateADestructive
Change what the ticket says is true by patching named description sections (Observed, Cause, Fix, Done when). The description is current state; comments are the log. Pass reconciled_through (a comment id) to record that the description now reflects the thread through that comment, with accounts_for saying how each skipped comment was handled. Tick a Done when item only once its check has run, and cite what showed it after the item text: "- [x] · ", where evidence is a commit SHA, a PR (#123), a file:line, a link, a CI run, "Observed 2" for a line under Observed, or command → result. A merge, a deploy, or being told something shipped is not the check; if nobody has run it, leave it open and say so. Removing or rewording an unticked Done when item needs descope_reason and descope_risk, and your user is asked to approve it from those two alone, so write them for someone without the ticket open. In Claude Code the call may come back asking you to put a question to your user with AskUserQuestion first; do exactly that, then retry with the sign_off token it gives.
| Name | Required | Description | Default |
|---|---|---|---|
| base | Yes | description_sha of the description this patch was written against: from get_issue, or from your last write to this ticket. The write is refused, with what changed, if the description has moved since. | |
| issue | Yes | Issue identifier (e.g. ENG-123) or UUID | |
| patch | No | Description sections to change. Impact is the one plain-language line at the top saying who notices this work (mode replace). Observed lines must be "YYYY-MM-DD · <source: command, SHA or query> · <what it showed>". Done when lines must be checklist items ("- [ ] <check that proves it>"). Open questions changes only through comment kinds ask and answer. | |
| sign_off | No | The token from a set_state refusal that asked you to put a sign-off question to your user. Retry the same call with it after they answer. | |
| accounts_for | No | With reconciled_through: for each comment the marker moves past, whether it was folded into this call's patch or changes nothing (with a reason). Typed comments that already changed the description count on their own. {comment: "*"} covers every comment not named. | |
| descope_risk | No | Required with descope_reason: what stops being checked if your user approves, and what could get through because of it. At most 100 characters; they see it on one line as "If you accept". | |
| descope_reason | No | Required when the patch removes or rewords an unticked Done when item: why that check no longer applies. At most 100 characters; your user sees it on one line as "Why the agent wants it", and it is recorded as a comment. Keep the detail in Observed. | |
| reconciled_through | No | Id of the newest comment the description now reflects |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructive=true and non-idempotent, and the description adds substantial behavior beyond them: the base-SHA optimistic-concurrency refusal ('The write is refused, with what changed, if the description has moved since'), the sign_off/AskUserQuestion retry flow, and the user-approval path for descopes. This tells the agent exactly what can go wrong and how the call may return without mutating.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose and its contrast with comments are front-loaded, and most sentences carry non-obvious rules. It is dense and runs long with several parenthetical asides (source lists, Claude Code sign-off), which slightly taxes readability but each clause is doing work.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and annotations carry the safety profile. Given the tool's complexity (8 params, nested patch array) the description covers the concurrency, sign-off, and descope flows that an agent would otherwise guess wrong; nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage the baseline is 3, but the description adds real meaning the schema lacks: the evidence format for ticked Done when items ('- [x] <item> · <evidence>'), what qualifies as a check versus a merge/deploy, and the semantics of reconciled_through/accounts_for ('accounts_for saying how each skipped comment was handled'). This meaningfully enriches several parameters beyond their structured definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Change what the ticket says is true by patching named description sections (Observed, Cause, Fix, Done when).' It immediately distinguishes itself from the sibling comment tool ('The description is current state; comments are the log'), so an agent can tell it apart from comment/set_status without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear conditional guidance: pass reconciled_through to record the description reflects a thread, tick a Done when item only once its check has run, and require descope_reason/descope_risk when removing unticked items. It contrasts with comments as the alternative, though it never states when *not* to use set_state versus a plain comment.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_statusADestructiveIdempotent
Move a ticket to a workflow state by name. Moving to a completed state (Done) needs a Done when section with every item ticked and cited, any cited PR linked here merged, and your claim, and refuses, returning the diff, if the description changed since you claimed it. This call carries no evidence of its own: write it into the description with set_state first, where this check and any close gate a project hooks onto this tool read it. Moving to a canceled state skips those checks, so it needs reason, which is posted as a comment.
| Name | Required | Description | Default |
|---|---|---|---|
| issue | Yes | Issue identifier (e.g. ENG-123) or UUID | |
| state | Yes | Workflow state name | |
| reason | No | Why the work stops. Required for a canceled state, optional otherwise; posted as a comment. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructive=true, idempotent=true, readOnly=false, but the description adds substantial unannotated behavior: it can refuse and return a diff if the description changed since claim, it reads gates a project may hook onto the tool, and reason gets posted as a comment. Only the valid state-name domain is left unstated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first sentence, and subsequent sentences carry real behavioral payload. However, the second sentence is a long run-on packing several conditional clauses, which slightly hurts parseability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained, and annotations carry the safety profile. The description covers gating, refusal, and comment side effects well; the main omission is that valid workflow state names are never enumerated or pointed to.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so issue, state, and reason are already documented in the schema (including that reason is required for canceled and posted as a comment). The description largely restates that for reason and adds little new syntax or format detail, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Move a ticket to a workflow state by name.' It also distinguishes itself from the sibling set_state by clarifying that this call 'carries no evidence of its own' while set_state writes it, so an agent can tell the two apart without reading schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit conditional routing: moving to Done requires a completed 'Done when' section, merged cited PRs, and a claim, while moving to canceled skips those checks and requires a reason. It names set_state as the prerequisite tool for embedding evidence, so when-to-use is fully covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoamiARead-onlyIdempotent
Who this server acts as: the Linear user or app behind the token. Claims, assignee_is_me and delegate_is_me all mean this identity.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | Linear user id |
| app | No | True for an app (agent) identity, false for a person |
| name | No | User name |
| displayName | No | Display name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly/idempotent/non-destructive safety, so the bar is lower; the description adds meaningful context by explaining what the returned identity semantically drives (claims, self-referential fields). It does not need to explain return values since an output schema exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, the core meaning front-loaded before the clarifying note about claims. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero params, a full output schema, and complete annotations, the description only needs to convey the identity's meaning and its relationship to related fields. It does so adequately.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. There are no argument semantics to clarify beyond the empty schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States specifically what the tool reveals: the Linear user or app behind the token. It clearly identifies the resource and scope, though it does not explicitly name which sibling (e.g. check_claim vs claim) it differs from.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by tying the result to claims, assignee_is_me, and delegate_is_me, giving the agent context for interpretation. However, it never states when to call this tool versus alternatives like check_claim, so guidance remains implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
17 tool updates
v0.1.0- First observed
check_claim - First observed
claim - First observed
comment - First observed
create_issue - First observed
description_history - First observed
get_issue - First observed
list_cycles - First observed
list_initiatives - First observed
list_issues - First observed
list_projects - First observed
list_teams - First observed
mark_notifications_read - First observed
notifications - First observed
set_fields - First observed
set_state - First observed
set_status - First observed
whoami
TDQS
Scored across 17 tools
Most tools target distinct resources or actions, but set_state and comment both can carry description patches, creating a slight overlap. claim and check_claim are complementary yet clearly separated by intent and timing. Overall, an agent can usually tell them apart from descriptions.
Names are mostly snake_case and follow verb_noun for actions (set_state, list_issues, create_issue), but noun phrases like description_history and notifications, plus standalone verbs like claim and comment, break the pattern. Still readable and predictable within tool categories.
17 tools is slightly above the typical 3-15 range, but the server's strict, multi-step workflow justifies each tool with a distinct operation. No obvious redundancy; borderline heavy but reasonable for this domain.
The surface covers ticket creation, reading, description state changes, comments, fields, status, claims, notifications, and supporting lists. Missing delete ticket and comment editing operations, but the core agent lifecycle is complete with workarounds for minor gaps.
Maintenance
Related MCP Connectors
Read and write a CRM built for agents. Every change carries who asserted it and how.
MCP server for Linear project management and issue tracking
Shared boards for agents: live text, reliable appends, and immutable UTC revision history.
Task management for people and AI agents, with scoped OAuth access to issues, projects, and docs.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to manage a file-backed ticketing system directly within a local repository using a structured state machine and directory hierarchy. It enforces strict markdown schemas and provides specialized tools for claiming tasks, appending work logs, and validating ticket metadata.-
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to manage Linear workspace resources such as issues, projects, teams, cycles, and comments via Streamable HTTP MCP, with LLM-optimized tools and batch operations.280 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables agents to manage an event-sourced, git-backed ticket store through MCP tools, supporting operations like ticket creation, claiming, and transitions.4Apache 2.0
- FlicenseAqualityBmaintenanceEnables reading and managing Linear issues by human-readable ID, with tools for searching, creating, updating, commenting, and resolving teams, states, labels, and assignees by name.11-