Claude Code + Linear MCP integration eliminates the context switch between your issue tracker and your terminal. Instead of manually reading a Linear ticket, copying its requirements into the chat, and then switching back to mark it in progress, you can do all of that from within a Claude Code session. We tested this setup across several weeks of active development and documented exactly how the tools work, what the limitations are, and which CLAUDE.md patterns hold up in practice.
Why Linear MCP Changes How Developers Use Claude Code
The standard Claude Code workflow treats tickets as external context — you copy requirements from Linear into the conversation, Claude writes the code, and you close the ticket manually. That works, but it creates a synchronization problem: the state in your issue tracker frequently diverges from what Claude is actually doing.
Linear’s MCP server closes that gap. When Linear MCP is connected, Claude Code can:
- Fetch issue details (description, comments, priority, assignee, status)
- Update issue status and add comments during or after implementation
- Create sub-issues or linked issues to track discovered scope
- Search issues by team, cycle, project, or label
- Assign issues to specific team members as work proceeds
The practical result: Claude can open a sprint board, read the next unassigned issue, implement it, commit with the issue ID in the message, mark the issue as “In Review”, and leave a summary comment — all in one uninterrupted session.
Explore our rules gallery to see how other teams structure their CLAUDE.md for issue-tracker integrations.
Setting Up Linear MCP Server in Claude Code (Step-by-Step)
Linear’s official MCP server is distributed as @linear/mcp. It requires a Linear API key, which you can generate at Settings → API → Personal API keys in the Linear app.
Step 1: Generate a Linear API key
Go to Linear → Settings → API → Personal API Keys → Create Key. Give it a descriptive name like claude-code-mcp. Copy the key immediately — it won’t be shown again.
Step 2: Store the key securely
Never paste the API key directly into .mcp.json. Use 1Password CLI or an environment variable:
# Store in 1Password (recommended)
op item create --category "API Credential" \
--title "Linear MCP Key" \
--field "credential[password]=$YOUR_LINEAR_API_KEY"
# Or store in shell environment
export LINEAR_API_KEY="lin_api_xxxxxxxx"
Step 3: Add to .mcp.json
Create or edit .mcp.json in your project root:
{
"mcpServers": {
"linear": {
"command": "npx",
"args": ["-y", "@linear/mcp"],
"env": {
"LINEAR_API_KEY": "${LINEAR_API_KEY}"
}
}
}
}
If you use 1Password CLI, replace the env block with:
{
"mcpServers": {
"linear": {
"command": "op",
"args": ["run", "--", "npx", "-y", "@linear/mcp"],
"env": {
"LINEAR_API_KEY": "op://Private/Linear MCP Key/credential"
}
}
}
}
Step 4: Verify the connection
Start a new Claude Code session and run:
/mcp
You should see linear listed as a connected server. If not, check that LINEAR_API_KEY is exported in your shell profile and restart the session.
Core Linear MCP Tools and What They Do
Once connected, Claude Code can call these Linear MCP tools. Understanding the tool set helps you write accurate CLAUDE.md instructions.
| Tool | What It Does | Common Use Case |
|---|---|---|
mcp__linear__get_issue | Fetch a single issue by ID | Load requirements before implementation |
mcp__linear__list_issues | List issues filtered by team, state, assignee, cycle | Find the next issue to work on |
mcp__linear__search_issues | Full-text search across issues | Find related issues before creating new ones |
mcp__linear__create_issue | Create a new issue | Log discovered scope during implementation |
mcp__linear__update_issue | Update state, priority, assignee, estimate | Mark “In Progress” at session start, “In Review” at commit |
mcp__linear__create_comment | Add a comment to an issue | Post implementation summary |
mcp__linear__list_teams | List all teams | Identify the correct team ID for filters |
mcp__linear__list_projects | List all projects | Scope issue queries to a project |
mcp__linear__get_viewer | Get the authenticated user | Assign issues to the current user |
We found mcp__linear__list_issues most useful at session start and mcp__linear__update_issue + mcp__linear__create_comment most useful at commit time. The create_issue tool pays off during implementation when you discover scope that doesn’t belong in the current ticket.
CLAUDE.md Template for Linear-Integrated Projects
A CLAUDE.md that embeds Linear context helps Claude make better decisions throughout a session — not just when explicitly asked to check tickets.
# CLAUDE.md
## Project Identity
- Linear Team: ENG
- Linear Project: Backend API (project ID: PRJ-xxxxx)
- Current Cycle: Q3 Sprint 5 (ends 2026-07-25)
## Linear Workflow Rules
### Issue Lifecycle
1. At session start: call `list_issues` to show unstarted issues assigned to me
2. When picking an issue: call `update_issue` to set state → "In Progress"
3. During implementation: if you discover out-of-scope work, create a sub-issue
4. Before committing: ensure the commit message starts with the issue ID
5. After pushing: call `update_issue` state → "In Review", then `create_comment` with implementation summary
### Commit Message Format
ENG-{issue_number}: {imperative_description}
{body_if_needed}
Examples:
- `ENG-412: Add rate limiting to /api/auth endpoints`
- `ENG-388: Fix null pointer in user.getProfile() when avatar is unset`
### Labels to Respect
- `blocked`: Do not start. Call `create_comment` to ask for clarification
- `needs-design`: Do not implement. Flag to human for design review first
- `security`: Call `create_comment` with threat model before any code changes
## Issue Context Loading
When I give you an issue ID (e.g., "work on ENG-412"), always:
1. Call `get_issue` first to load the full description + comments
2. Summarize what you understand before writing any code
3. Ask if anything is unclear before proceeding
This pattern — embed team/project IDs, define the lifecycle steps explicitly, and specify the commit format — eliminates the most common failure modes we saw in early testing (wrong team filters, missing issue IDs in commits, forgotten status updates).
Workflow Patterns: Issue → Branch → PR → Close
The full end-to-end workflow, from picking an issue to closing it, looks like this in practice:
1. Session start: load the sprint board
Claude: "Show me unstarted issues in ENG assigned to me for the current cycle"
→ mcp__linear__list_issues(
filter: {
assignee: { isMe: true },
state: { name: { eq: "Todo" } },
cycle: { isActive: true }
}
)
2. Pick an issue and mark it in progress
Claude picks ENG-412 and runs:
→ mcp__linear__update_issue(
id: "ENG-412",
stateId: "in-progress-state-id"
)
3. Implement with full context
→ mcp__linear__get_issue(id: "ENG-412")
Returns: title, description, comments, priority, labels, linked issues
Claude reads requirements and implements
4. Create branch with issue ID
Claude Code’s bash tool:
git checkout -b ENG-412-rate-limiting-auth-endpoints
5. Commit with issue reference
git commit -m "ENG-412: Add rate limiting to /api/auth endpoints
- Implement token bucket algorithm (100 req/min per IP)
- Add X-RateLimit-* response headers
- Return 429 with Retry-After header on limit hit"
6. Mark in review and leave summary comment
→ mcp__linear__update_issue(id: "ENG-412", stateId: "in-review-state-id")
→ mcp__linear__create_comment(
issueId: "ENG-412",
body: "Implementation complete. Branch: ENG-412-rate-limiting-auth-endpoints\n\nChanges:\n- Added middleware in src/middleware/rateLimit.ts\n- 100 req/min per IP, configurable via ENV\n- Unit tests in src/middleware/__tests__/rateLimit.test.ts"
)
This full loop takes roughly the same time as a manual implementation, but the Linear board stays current automatically. During code review, teammates can read the comment to understand what changed without digging through the diff first.
Multi-Agent Setup: Parallel Issue Processing
Claude Code’s sub-agent system supports parallel execution. Combined with Linear MCP, you can assign different sub-agents to different Linear issues and run them simultaneously.
This pattern works well for issues that are independent — different files, different services, no shared state:
# CLAUDE.md (multi-agent section)
## Parallel Issue Processing
When asked to work on multiple issues in parallel:
1. Verify issues are independent (no shared files, no sequential dependency)
2. Create a git worktree per issue: `git worktree add ../worktrees/ENG-{N} -b ENG-{N}-{slug}`
3. Launch one sub-agent per worktree with the issue context
4. Each sub-agent follows the standard lifecycle (mark in progress, implement, commit, mark in review)
5. Merge back to main after all sub-agents complete
Sub-agent isolation rule: each agent works exclusively in its own worktree directory.
Do not share files between agents during implementation.
Example invocation:
"Work on ENG-412, ENG-415, and ENG-419 in parallel.
Verify they're independent first, then use worktrees."
Claude will:
- Call
get_issueon all three to check for dependencies - Create three worktrees
- Spawn three sub-agents, each with one issue in their context
- Report back when all three complete
We found parallel issue processing reliable for test-first work (TDD) and straightforward bug fixes. For features that require cross-cutting changes (database migrations, shared types, config changes), sequential is safer.
FAQ
How do I find my Linear state IDs for update_issue?
Call mcp__linear__list_teams to get your team ID, then mcp__linear__list_workflow_states with that team ID. Each state object returns an id field — that’s what you pass to update_issue. We recommend putting your most-used state IDs in CLAUDE.md as constants.
Does Linear MCP work with Linear’s OAuth, or only personal API keys?
The current @linear/mcp package supports only personal API keys. OAuth support is tracked in the Linear MCP GitHub repository. For team environments, create a shared “bot” API key scoped to the relevant teams rather than using a personal key.
Can Claude Code create Linear issues from code TODOs automatically?
Not natively, but a PostToolUse hook makes this straightforward. Configure a hook that runs after file writes and scans for // TODO(ENG): comments, then calls create_issue with the TODO text as the description. We have a working example in our rules gallery.
What happens if the MCP server loses connection mid-session?
Claude Code displays an MCP error in the tool call output. The session itself doesn’t crash — Claude continues working but cannot call Linear tools until the connection is restored. If you run op run as the command wrapper, connection resets usually recover automatically when the next tool call retries.
Is Linear MCP read-only or can it modify my board?
It can modify your board. update_issue, create_issue, and create_comment all write to Linear. The only protection is your API key’s permission scope. We recommend testing with a dedicated Linear workspace or a low-priority team before rolling this out to production sprint boards.
Can I filter list_issues to a specific assignee who isn’t me?
Yes. Pass assignee: { id: { eq: "user-uuid" } } in the filter. Get the user UUID from mcp__linear__list_users or from the URL when you view their profile in the Linear app.
Keep MCP Secrets Out of Your Repo
Never put your LINEAR_API_KEY directly in .mcp.json. 1Password CLI’s op run injects secrets at runtime — no committed keys, no keys in shell history, and a full access log for every secret your MCP servers touch. It’s the same binary you use for SSH and AWS keys, so there’s no new infrastructure to manage.