linear-strict
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| LINEAR_API_TOKEN | Yes | Linear personal API key, or a lin_oauth_ token (sent as Bearer). Required to authenticate the server; the --token command line flag also works. | |
| ANTHROPIC_API_KEY | No | The judge's key, if not saved with 'auth judge-key set'. | |
| LINEAR_STRICT_DEBUG | No | 1 logs startup detail to stderr. | |
| LINEAR_STRICT_SIGN_OFF | No | Who approves dropping an unticked 'Done when' item: person or judge. | person |
| LINEAR_STRICT_STATE_DIR | No | Where claim records and pending sign-offs are kept. Defaults to $XDG_STATE_HOME/linear-strict. | |
| LINEAR_STRICT_CONFIG_DIR | No | Where 'auth login' stores credentials. Defaults to $XDG_CONFIG_HOME/linear-strict. | |
| LINEAR_OAUTH_ACCESS_TOKEN | No | Any OAuth access token, sent as Bearer. Used instead of LINEAR_API_TOKEN if set. | |
| LINEAR_STRICT_JUDGE_MODEL | No | The model that decides when LINEAR_STRICT_SIGN_OFF=judge. | claude-opus-5-5 |
| LINEAR_STRICT_MAIN_BRANCH | No | Branch a PR must merge into for Done to count as shipped. | main |
| LINEAR_STRICT_PRODUCTION_ENV | No | Environment named in posthog-<env>: flag labels that counts as live. | production |
| LINEAR_STRICT_SINGLE_INSTANCE | No | 0 turns off the check that lets a replaced server exit. | 1 |
| LINEAR_STRICT_HANDS_OFF_LABELS | No | Comma-separated labels that make a ticket people-only: every write through this server is refused, reads still work. | no-agents |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| get_issueA | Read one ticket whole: full description, every comment oldest-first (all pages), who edited the description and when, relations, children, attachments. |
| description_historyA | 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. |
| list_issuesA | 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. |
| whoamiA | 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. |
| list_teamsA | Every team with its key and workflow states in board order. State names are what set_status takes. |
| list_cyclesA | Cycles, earliest first. Defaults to the active and next cycle. Use a cycle number with list_issues (cycle + team) to see its tickets. |
| list_projectsA | Projects with status, lead, teams, dates and progress. Open projects only unless include_closed. |
| list_initiativesA | Initiatives with status, owner and target date. Unfinished ones only unless include_closed. |
| notificationsA | 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. |
| mark_notifications_readA | Mark notifications read once you have handled them. Reports each id separately. |
| claimA | 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. |
| check_claimA | Whether the description changed since your claim, with a line diff. Run before opening or merging a PR for the ticket. |
| set_stateA | 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 |
| commentA | 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. |
| set_statusA | 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. |
| set_fieldsA | 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. |
| 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. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
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.