Multi-workspace Linear MCP server with PAT auth — drop-in replacement for the official OAuth-only Linear connector.
Project description
linear-mcp
Multi-workspace Linear MCP server with Personal API Key auth. Drop-in replacement for the official OAuth-only Linear MCP at mcp.linear.app/mcp.
Why this exists. The official Linear MCP is OAuth-only and single-workspace per instance. PAT auth plus persistent token storage plus multi-workspace routing kills three failure modes:
- The OAuth flow is brittle across MCP client session boundaries — auth state expires when a session resumes mid-flow.
- The localhost callback fails in some setups, forcing fragile paste-back flows.
- One MCP instance per workspace doubles config + OAuth dances.
This server replaces both with one entry. One install, N workspaces, never an OAuth dance again.
Install
From PyPI
pipx install adelaidasofia-linear-mcp
From source
git clone https://github.com/adelaidasofia/linear-mcp ~/.claude/linear-mcp
cd ~/.claude/linear-mcp
pip install -e .
Claude Desktop one-click
Download the latest .mcpb from Releases and double-click.
Configure
-
Generate one Personal API Key per workspace at https://linear.app/settings/account/security. You must be logged into each workspace separately while generating the key for that workspace.
-
Create
~/.claude/linear-mcp/admin.env(chmod 600):
LINEAR_WORKSPACES=personal,work
LINEAR_PRIMARY_WORKSPACE=personal
LINEAR_PAT_PERSONAL=lin_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
LINEAR_PAT_WORK=lin_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
LINEAR_LABEL_PERSONAL=Personal
LINEAR_LABEL_WORK=Work
Aliases are arbitrary — name them whatever helps you route (acme,beta, team1,team2, home,client).
chmod 600 ~/.claude/linear-mcp/admin.env
- Register in Claude Code (user scope, so it loads in every project):
claude mcp add -s user linear-mcp python3 -m linear_mcp.server
Or, with pipx install:
claude mcp add -s user linear-mcp linear-mcp
- Restart Claude Code.
healthcheckshould returnok: trueper workspace.
Substrate-layer enforcement (v0.3)
Three server-side checks that protect issue quality without depending on any markdown rule file or client-side memory. Apply only to WRITE paths; reads stay unconstrained.
| Layer | What it does | Bypass env var |
|---|---|---|
[source:] first-line check |
save_issue / save_project reject CREATE calls whose description (or project content) does not start with [source: <canonical-key>]. UPDATE calls (id passed) skip the check so legacy backfills remain unblocked. |
LINEAR_MCP_SKIP_SOURCE_CHECK=1 |
| Idempotency check | Before any CREATE, the server runs searchIssues / searchProjects for [source: <key>] and refuses to create a duplicate. The error names the existing identifier + UUID so the caller can update in place. |
LINEAR_MCP_SKIP_IDEMPOTENCY=1 |
auth_phrase on bulk_save_issues |
bulk_save_issues now requires auth_phrase ∈ {"go", "yes do it", "confirmed", "execute", "go cancel", "go update"} (case-insensitive). Mass-modification surface stays explicit. |
(no bypass — surface the phrase to the operator) |
Canonical-key examples:
[source: 🍄 Mycelium AI/📝 Meeting Notes/2026-05-22 - sync.md][source: ⚙️ Meta/Decisions/2026-05-23-merger-public-comms.md][source: linear-kickoff:sweep-myc-p1][source: ~/.claude/linear-mcp/BUILD_PROMPT_V03.md]
Tool surface (v0.3 — 57 tools + 3 prompts)
Every tool takes an optional workspace parameter (the alias from LINEAR_WORKSPACES). Omit it to use LINEAR_PRIMARY_WORKSPACE.
Meta
| Tool | Purpose |
|---|---|
list_workspaces |
Show configured workspaces and primary |
healthcheck |
Verify each PAT + surface remaining rate-limit budget |
Core entities
| Tool | Purpose |
|---|---|
list_teams / get_team |
Teams (with inline workflow states) |
list_users / get_user |
Users (me resolves to PAT owner) |
list_projects / get_project / save_project |
Projects (v0.3: save_project enforces [source:] on content + idempotency on CREATE) |
list_initiatives / get_initiative / save_initiative |
Initiatives |
list_issues / get_issue / save_issue / bulk_save_issues |
Issues (id or ONDE-123; bulk uses issueBatchUpdate; v0.3: save_issue enforces [source:] + idempotency on CREATE; bulk_save_issues requires auth_phrase) |
list_cycles |
Cycles |
list_milestones / get_milestone / save_milestone |
Project milestones |
list_issue_statuses / get_issue_status |
Workflow states |
list_issue_labels / create_issue_label |
Labels |
list_comments / save_comment |
Comments |
list_documents / get_document / save_document |
Documents |
save_status_update |
Post a project status update |
Webhooks (v0.2)
| Tool | Purpose |
|---|---|
list_webhooks / get_webhook |
Inspect subscriptions |
create_webhook / update_webhook |
Manage subscriptions |
delete_webhook |
Destructive — draft+confirm |
Notifications / inbox (v0.2)
| Tool | Purpose |
|---|---|
list_notifications / get_notification |
Inbox read |
notifications_unread_count |
Top-of-mind counter |
mark_notification_read / mark_all_notifications_read |
Triage |
archive_notification |
Sweep |
Attachments (v0.2)
| Tool | Purpose |
|---|---|
list_attachments / get_attachment |
Per-issue reads |
attachments_for_url |
Reverse lookup: which issues link to this URL? |
link_url_to_issue |
Attach any URL to an issue |
delete_attachment |
Destructive — draft+confirm |
Issue relations (v0.2)
| Tool | Purpose |
|---|---|
list_issue_relations |
The blocks/duplicate/related graph |
create_issue_relation / delete_issue_relation |
Manage the graph |
Agent sessions (v0.2)
| Tool | Purpose |
|---|---|
list_agent_sessions / get_agent_session |
Linear's first-class agent surface |
create_agent_session_on_issue / create_agent_session_on_comment |
Spawn |
Search (v0.2 — replaces v0.1's broken search_documentation)
| Tool | Purpose |
|---|---|
search_issues / search_documents / search_projects |
Full-text per entity type |
semantic_search |
Workspace-wide semantic across all entities |
MCP prompts (v0.2)
Available as slash commands in MCP clients that surface prompts:
/triage-issue— full triage pass: classify, label, prioritize, assign, link duplicates/project-status— draft a weekly status update from current Linear state/inbox-sweep— sweep today's notifications, propose actions, archive what's handled
Multi-workspace usage
Switch workspaces inline:
list_teams(workspace="work")
save_issue(workspace="personal", title="Ship", team_id="...")
Without workspace, the primary is used.
Auth
Linear PATs use header Authorization: <key> (no Bearer prefix). Each PAT is scoped to one workspace and grants access only to data the owning user can see. There is no shared org token.
Rate limit: 2500 requests/hour per token (verified against live API 2026-05-23). The server passes Linear's Retry-After header through on 429 and surfaces remaining budget via healthcheck.
Safety
Read tools and routine writes (create/update issues, comments, labels, status updates) pass through. Destructive ops (delete_webhook, delete_attachment) use the draft+confirm pattern: the first call stages the change and returns a draft_id + preview of what will happen; the second call (with confirm_draft_id) commits. Drafts expire after 1 hour (override with LINEAR_MCP_DRAFT_TTL_SECONDS).
Every tool call appends one JSONL line to ~/.claude/linear-mcp/audit.log (override with LINEAR_MCP_AUDIT_LOG_PATH, disable with LINEAR_MCP_AUDIT_LOG=false). Tokens are stripped from audit records.
healthcheck surfaces each PAT's remaining rate-limit budget (X-RateLimit-Requests-Remaining + X-Complexity-Remaining) per workspace, so agents can self-throttle without making a separate observability call.
Related MCPs
- adelaidasofia/slack-mcp — multi-workspace Slack with draft+confirm
- adelaidasofia/whatsapp-mcp — WhatsApp via whatsmeow + vault export
- adelaidasofia/imessage-mcp — iMessage chat.db + vault export
- adelaidasofia/github-mcp — GitHub PR/issue/release
License
MIT.
Built by Adelaida Diaz-Roa. Full install or team version at diazroa.com.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file adelaidasofia_linear_mcp-0.3.0.tar.gz.
File metadata
- Download URL: adelaidasofia_linear_mcp-0.3.0.tar.gz
- Upload date:
- Size: 35.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
22dab76f49eef4f40ccf38e0ab44e66b7138c0c1ad5c746845b642f4a2a2c260
|
|
| MD5 |
9bfb20fdbfaeb2f08c739876a5ef03f9
|
|
| BLAKE2b-256 |
b61978a86fdd4ddb5d90526634dfc00ec5465a4e0c030a196042a9d5cf0dc961
|
Provenance
The following attestation bundles were made for adelaidasofia_linear_mcp-0.3.0.tar.gz:
Publisher:
publish-mcp.yml on adelaidasofia/linear-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adelaidasofia_linear_mcp-0.3.0.tar.gz -
Subject digest:
22dab76f49eef4f40ccf38e0ab44e66b7138c0c1ad5c746845b642f4a2a2c260 - Sigstore transparency entry: 1617040549
- Sigstore integration time:
-
Permalink:
adelaidasofia/linear-mcp@035cdd81599d59e80cfd8dd066f9ed21f9dcc201 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/adelaidasofia
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-mcp.yml@035cdd81599d59e80cfd8dd066f9ed21f9dcc201 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file adelaidasofia_linear_mcp-0.3.0-py3-none-any.whl.
File metadata
- Download URL: adelaidasofia_linear_mcp-0.3.0-py3-none-any.whl
- Upload date:
- Size: 48.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d891c0319bbd9dadf4fc9f9338e07ef1ba2e8d70a6ba9c043872b36f3775c217
|
|
| MD5 |
814fdc362ecef8b83a2bff797e1aa041
|
|
| BLAKE2b-256 |
22adfac892abaa511f9828ebc5624f1af9bfde474da18730bc1439bfe3e039cb
|
Provenance
The following attestation bundles were made for adelaidasofia_linear_mcp-0.3.0-py3-none-any.whl:
Publisher:
publish-mcp.yml on adelaidasofia/linear-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adelaidasofia_linear_mcp-0.3.0-py3-none-any.whl -
Subject digest:
d891c0319bbd9dadf4fc9f9338e07ef1ba2e8d70a6ba9c043872b36f3775c217 - Sigstore transparency entry: 1617040812
- Sigstore integration time:
-
Permalink:
adelaidasofia/linear-mcp@035cdd81599d59e80cfd8dd066f9ed21f9dcc201 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/adelaidasofia
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-mcp.yml@035cdd81599d59e80cfd8dd066f9ed21f9dcc201 -
Trigger Event:
workflow_dispatch
-
Statement type: