Claude Skills with Linear Project (2026)
Linear is a project management tool built for engineering teams, known for its speed and clean keyboard-driven interface. Integrating Claude skills with Linear lets you automate issue triage, generate technical specifications, analyze sprint data, and write issue descriptions that actually help developers. This tutorial covers Claude skills with Linear project management from API setup to automated workflows.
What You Can Automate
- Issue triage: Incoming bug reports run through
tddskill to assess test impact and suggest repro steps - Spec generation: Feature requests sent to Claude return structured technical specs ready to paste into Linear
- Sprint summaries: Completed issues analyzed by Claude and summarized for stakeholder updates
- PR-to-issue linking: GitHub PR descriptions processed to auto-update Linear issue status and add review notes
- Supermemory context:
supermemoryskill tracks patterns across sprint cycles
Prerequisites
- Linear workspace with API access
- Linear API key (Personal API Keys in Linear settings)
- Claude API key from console.anthropic.com
- Node.js 18+
Step 1: Get Your Linear API Key
- Open Linear → Settings → API
- Under Personal API keys, create a new key with label “Claude Skills Bot”
- Copy the key. it starts with
lin_api_
Step 2: Install Dependencies
mkdir claude-linear-bot && cd claude-linear-bot
npm install @linear/sdk @anthropic-ai/sdk dotenv
Create .env:
LINEAR_API_KEY=lin_api_your_key_here
ANTHROPIC_API_KEY=your_claude_api_key
LINEAR_TEAM_ID=your_team_id
Find your team ID from the Linear URL or API: https://linear.app/{workspace}/team/{team_id}/
Step 3: Initialize Clients
require('dotenv').config();
const { LinearClient } = require('@linear/sdk');
const Anthropic = require('@anthropic-ai/sdk');
const linear = new LinearClient({ apiKey: process.env.LINEAR_API_KEY });
const claude = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
Step 4: Fetch Issues and Run Claude Analysis
async function getRecentIssues(teamId, limit = 20) {
const issues = await linear.issues({
filter: { team: { id: { eq: teamId } } },
orderBy: 'createdAt',
first: limit,
});
return issues.nodes.map(issue => ({
id: issue.id,
identifier: issue.identifier,
title: issue.title,
description: issue.description || '',
state: issue.state?.name,
priority: issue.priority,
}));
}
async function triageIssue(issue) {
const prompt = `Issue: ${issue.identifier}. ${issue.title}
Description: ${issue.description || 'No description provided'}
As the TDD skill for Claude Code, analyze this bug report:
1. What tests would catch this bug?
2. What are the likely code areas affected?
3. Suggest concrete reproduction steps if missing
4. Estimate risk level: low/medium/high
Return JSON: { "test_suggestions": [], "affected_areas": [], "repro_steps": [], "risk_level": "", "triage_notes": "" }`;
const message = await claude.messages.create({
model: 'claude-opus-4-6',
max_tokens: 1024,
system: `You are the TDD skill for Claude Code. Analyze issues for test coverage implications and technical risk.`,
messages: [{ role: 'user', content: prompt }],
});
try {
return JSON.parse(message.content[0].text);
} catch {
return { triage_notes: message.content[0].text };
}
}
Step 5: Update Linear Issues with Claude Analysis
async function addTriageComment(issueId, analysis) {
const commentBody = `## Claude Triage Analysis
Risk Level: ${analysis.risk_level || 'Unknown'}
Suggested Tests
${(analysis.test_suggestions || []).map(t => `- ${t}`).join('\n')}
Affected Code Areas
${(analysis.affected_areas || []).map(a => `- ${a}`).join('\n')}
Reproduction Steps
${(analysis.repro_steps || []).map((s, i) => `${i + 1}. ${s}`).join('\n')}
Notes
${analysis.triage_notes || ''}
*Generated by Claude TDD Skill*`;
await linear.createComment({
issueId,
body: commentBody,
});
}
Step 6: Generate Technical Specs from Feature Requests
async function generateTechSpec(featureRequest) {
const message = await claude.messages.create({
model: 'claude-opus-4-6',
max_tokens: 2048,
system: `You are a senior software architect. Generate clear, actionable technical specifications for feature requests. Include implementation approach, API changes, database changes, and testing strategy.`,
messages: [{
role: 'user',
content: `Generate a technical spec for this feature request:\n\n${featureRequest}`,
}],
});
return message.content[0].text;
}
async function createSpecIssue(teamId, title, spec) {
const states = await linear.workflowStates({
filter: { team: { id: { eq: teamId } } },
});
const backlogState = states.nodes.find(s => s.name === 'Backlog' || s.name === 'Todo');
await linear.createIssue({
teamId,
title: `[Tech Spec] ${title}`,
description: spec,
stateId: backlogState?.id,
labelIds: [], // add your "spec" label ID here
});
}
Step 7: Sprint Summary with Supermemory Tracking
async function generateSprintSummary(teamId) {
// Get issues completed in last 2 weeks
const twoWeeksAgo = new Date(Date.now() - 14 * 24 * 60 * 60 * 1000).toISOString();
const completedIssues = await linear.issues({
filter: {
team: { id: { eq: teamId } },
completedAt: { gt: twoWeeksAgo },
},
first: 50,
});
const issueList = completedIssues.nodes
.map(i => `- ${i.identifier}: ${i.title} (${i.estimate || '?'} pts)`)
.join('\n');
const message = await claude.messages.create({
model: 'claude-opus-4-6',
max_tokens: 1024,
system: `You are the supermemory skill for Claude Code. Generate concise sprint summaries for stakeholders. Focus on impact, not tasks.`,
messages: [{
role: 'user',
content: `Summarize this sprint's completed work for a stakeholder update:\n\n${issueList}`,
}],
});
return message.content[0].text;
}
Step 8: Set Up a Webhook for Real-Time Triage
Linear supports webhooks for real-time events. Create an Express server to receive them:
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
app.post('/webhook/linear', async (req, res) => {
// Verify Linear webhook signature
const signature = req.headers['linear-signature'];
const expected = crypto
.createHmac('sha256', process.env.LINEAR_WEBHOOK_SECRET)
.update(JSON.stringify(req.body))
.digest('hex');
if (signature !== expected) {
return res.status(401).send('Invalid signature');
}
res.status(200).send('OK'); // Respond quickly
const { action, type, data } = req.body;
// Auto-triage new bug reports
if (type === 'Issue' && action === 'create' && data.labelNames?.includes('bug')) {
const analysis = await triageIssue(data);
await addTriageComment(data.id, analysis);
console.log(`Triaged: ${data.identifier}`);
}
});
app.listen(3000, () => console.log('Linear webhook server running on :3000'));
Step 9: Batch Triage Existing Issues
Run this once to triage your backlog:
async function triageBacklog(teamId) {
const issues = await getRecentIssues(teamId, 50);
const bugs = issues.filter(i => i.state === 'Todo' || i.state === 'Backlog');
for (const issue of bugs) {
console.log(`Triaging ${issue.identifier}...`);
const analysis = await triageIssue(issue);
await addTriageComment(issue.id, analysis);
// Respect rate limits
await new Promise(r => setTimeout(r, 1000));
}
console.log(`Triaged ${bugs.length} issues`);
}
triageBacklog(process.env.LINEAR_TEAM_ID);
Conclusion
Claude skills with Linear project management transforms routine PM work into automated intelligence. The tdd skill makes triage actionable, supermemory tracks patterns across sprints, and spec generation saves hours per feature. Start with the webhook-based real-time triage and add batch processing for your existing backlog.
Advanced: Automated Sprint Review Summaries
Automate sprint review generation by combining the Linear API with Claude:
async function generateSprintSummary(cycleId) {
const issues = await getCompletedIssues(cycleId);
const byLabel = issues.reduce((acc, issue) => {
const key = issue.labels.nodes[0]?.name || 'General';
acc[key] = acc[key] || [];
acc[key].push(issue.title);
return acc;
}, {});
const prompt = `Generate a sprint review summary from these completed issues grouped by area:\n${JSON.stringify(byLabel, null, 2)}\nFormat as a professional stakeholder update, 3-4 sentences per group.`;
return prompt; // Pass to Claude Code via stdin or API
}
Comparison with Native Linear Automation
| Feature | Claude Skills + Linear | Linear Workflow Automations | GitHub Actions |
|---|---|---|---|
| AI-powered triage | Yes | No | Via third-party action |
| Spec generation | Yes | No | No |
| Custom logic | Full | Rule-based only | Full (YAML) |
| Setup complexity | Medium | Low | Medium |
Troubleshooting Common Issues
API key not authorized for specific team: Ensure the API key has read/write access to the target team’s workspace. Linear uses team-specific permissions.
Triage comments in wrong format: Use the commentCreate mutation and escape markdown properly before sending to the Linear API.
Webhook timing out: Claude Code responses can take 5-10 seconds. Use a background job queue (BullMQ, Inngest) to acknowledge the webhook immediately and process triage asynchronously.
Duplicate triage comments on retries: Check for existing triage comments before adding a new one by filtering issue comments for your triage marker.
Claude skills with Linear transforms routine PM work into automated intelligence. The tdd skill makes triage actionable, supermemory tracks patterns across sprints, and spec generation saves hours per feature.
Try it: Paste your error into our Error Diagnostic for an instant fix.
Related Reading
- Best Claude Skills for Developers in 2026. Covers the tdd and supermemory skills used throughout this Linear integration guide, with usage patterns and invocation tips
- Best Claude Skills for DevOps and Deployment. Extends the Linear workflow into deployment pipelines, closing the loop from issue creation to production release
- Claude Skills Token Optimization: Reduce API Costs. Batch triage of Linear issues can generate significant API costs; these techniques help you keep them manageable
- Claude Skills for Puppet Chef Configuration Management
- Claude Skills for EdTech Learning Management Systems
Built by theluckystrike. More at zovo.one
Find the right skill → Browse 155+ skills in our Skill Finder.
Quick setup → Launch your project with our Project Starter.