Linear
通過 GraphQL API 管理 Linear 的問題(issues)、項目和團隊。創建、更新、搜索和組織問題。使用 API 密鑰認證(無需 OAuth)。所有操作均通過 curl 執行——無依賴項。
技能元數據
| 來源 | 捆綁(默認安裝) |
| 路徑 | skills/productivity/linear |
| 版本 | 1.0.0 |
| 作者 | Hermes Agent |
| 許可證 | MIT |
| 標籤 | Linear, Project Management, Issues, GraphQL, API, Productivity |
參考:完整 SKILL.md
信息
以下是 Hermes 在觸發此技能時加載的完整技能定義。這是技能激活時代理所看到的指令。
Linear — 問題與項目管理
直接使用 curl 通過 GraphQL API 管理 Linear 的問題、項目和團隊。無需 MCP 服務器,無需 OAuth 流程,無額外依賴項。
設置
- 從 Linear Settings > API > Personal API keys 獲取個人 API 密鑰
- 在環境中設置
LINEAR_API_KEY(通過hermes setup或你的環境配置)
API 基礎
- 端點:
https://api.linear.app/graphql(POST) - 認證頭:
Authorization: $LINEAR_API_KEY(API 密鑰無需 "Bearer" 前綴) - 所有請求均為 POST,且
Content-Type: application/json - UUID 和短標識符(例如
ENG-123)均可用於issue(id:)
基礎 curl 模式:
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ viewer { id name } }"}' | python3 -m json.tool
工作流狀態
Linear 使用帶有 type 字段的 WorkflowState 對象。6 種狀態類型:
| 類型 | 描述 |
|---|---|
triage | 需要審查的新增問題 |
backlog | 已確認但尚未規劃 |
unstarted | 已規劃/準備就緒但未開始 |
started | 正在積極處理 |
completed | 已完成 |
canceled | 不再處理 |
每個團隊都有其自己的命名狀態(例如,“In Progress” 的類型為 started)。要更改問題的狀態,你需要目標狀態的 stateId(UUID)——請先查詢工作流狀態。
優先級值: 0 = 無, 1 = 緊急, 2 = 高, 3 = 中, 4 = 低
常見查詢
獲取當前用戶
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ viewer { id name email } }"}' | python3 -m json.tool
列出團隊
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ teams { nodes { id name key } } }"}' | python3 -m json.tool
列出團隊的工作流狀態
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ workflowStates(filter: { team: { key: { eq: \"ENG\" } } }) { nodes { id name type } } }"}' | python3 -m json.tool
列出問題(前 20 個)
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ issues(first: 20) { nodes { identifier title priority state { name type } assignee { name } team { key } url } pageInfo { hasNextPage endCursor } } }"}' | python3 -m json.tool
列出分配給我的問題
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ viewer { assignedIssues(first: 25) { nodes { identifier title state { name type } priority url } } } }"}' | python3 -m json.tool
獲取單個問題(通過標識符,如 ENG-123)
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ issue(id: \"ENG-123\") { id identifier title description priority state { id name type } assignee { id name } team { key } project { name } labels { nodes { name } } comments { nodes { body user { name } createdAt } } url } }"}' | python3 -m json.tool
按文本搜索問題
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ issueSearch(query: \"bug login\", first: 10) { nodes { identifier title state { name } assignee { name } url } } }"}' | python3 -m json.tool
按狀態類型過濾問題
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ issues(filter: { state: { type: { in: [\"started\"] } } }, first: 20) { nodes { identifier title state { name } assignee { name } } } }"}' | python3 -m json.tool
按團隊和受理人過濾
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ issues(filter: { team: { key: { eq: \"ENG\" } }, assignee: { email: { eq: \"user@example.com\" } } }, first: 20) { nodes { identifier title state { name } priority } } }"}' | python3 -m json.tool
列出項目
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ projects(first: 20) { nodes { id name description progress lead { name } teams { nodes { key } } url } } }"}' | python3 -m json.tool
列出團隊成員
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ users { nodes { id name email active } } }"}' | python3 -m json.tool
列出標籤
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ issueLabels { nodes { id name color } } }"}' | python3 -m json.tool
常見變更操作 (Mutations)
創建問題
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "mutation($input: IssueCreateInput!) { issueCreate(input: $input) { success issue { id identifier title url } } }",
"variables": {
"input": {
"teamId": "TEAM_UUID",
"title": "Fix login bug",
"description": "Users cannot login with SSO",
"priority": 2
}
}
}' | python3 -m json.tool
更新問題狀態
首先從上述工作流狀態查詢中獲取目標狀態的 UUID,然後:
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { stateId: \"STATE_UUID\" }) { success issue { identifier state { name type } } } }"}' | python3 -m json.tool
分配問題
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { assigneeId: \"USER_UUID\" }) { success issue { identifier assignee { name } } } }"}' | python3 -m json.tool
設置優先級
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { priority: 1 }) { success issue { identifier priority } } }"}' | python3 -m json.tool
添加評論
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "mutation { commentCreate(input: { issueId: \"ISSUE_UUID\", body: \"Investigated. Root cause is X.\" }) { success comment { id body } } }"}' | python3 -m json.tool
設置截止日期
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { dueDate: \"2026-04-01\" }) { success issue { identifier dueDate } } }"}' | python3 -m json.tool
為問題添加標籤
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { labelIds: [\"LABEL_UUID_1\", \"LABEL_UUID_2\"] }) { success issue { identifier labels { nodes { name } } } } }"}' | python3 -m json.tool
將問題添加到項目
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "mutation { issueUpdate(id: \"ENG-123\", input: { projectId: \"PROJECT_UUID\" }) { success issue { identifier project { name } } } }"}' | python3 -m json.tool
創建項目
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "mutation($input: ProjectCreateInput!) { projectCreate(input: $input) { success project { id name url } } }",
"variables": {
"input": {
"name": "Q2 Auth Overhaul",
"description": "Replace legacy auth with OAuth2 and PKCE",
"teamIds": ["TEAM_UUID"]
}
}
}' | python3 -m json.tool
分頁
Linear 使用 Relay 風格的遊標分頁:
# First page
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ issues(first: 20) { nodes { identifier title } pageInfo { hasNextPage endCursor } } }"}' | python3 -m json.tool
# Next page — use endCursor from previous response
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "{ issues(first: 20, after: \"CURSOR_FROM_PREVIOUS\") { nodes { identifier title } pageInfo { hasNextPage endCursor } } }"}' | python3 -m json.tool
默認頁面大小:50。最大:250。始終使用 first: N 來限制結果數量。
過濾參考
比較運算符:eq, neq, in, nin, lt, lte, gt, gte, contains, startsWith, containsIgnoreCase
使用 or: [...] 組合過濾器以實現 OR 邏輯(過濾器對象內默認為 AND 邏輯)。
典型工作流
- 查詢團隊以獲取團隊 ID 和鍵
- 查詢目標團隊的工作流狀態以獲取狀態 UUID
- 列出或搜索問題以查找需要處理的內容
- 創建問題,包含團隊 ID、標題、描述、優先級
- 更新狀態,通過將
stateId設置為目標工作流狀態 - 添加評論以跟蹤進度
- 標記完成,通過將
stateId設置為團隊的“completed”類型狀態
速率限制
- 每個 API 密鑰每小時 5,000 次請求
- 每小時 3,000,000 複雜度點數
- 使用
first: N限制結果並降低複雜度成本 - 監控響應頭
X-RateLimit-Requests-Remaining
重要說明
- 始終使用
terminal工具配合curl進行 API 調用——不要使用web_extract或browser - 始終檢查 GraphQL 響應中的
errors數組——HTTP 200 仍可能包含錯誤 - 如果在創建問題時省略
stateId,Linear 默認使用第一個 backlog 狀態 description字段支持 Markdown- 使用
python3 -m json.tool或jq格式化 JSON 響應以提高可讀性