集成

项目管理API

试用

通过托管的 OAuth GraphQL 接口查询与管理 Linear 的 issue、项目、团队、周期、标签和评论。

它能做什么

通过 Maton 托管的 OAuth 端点接入 Linear,使用 GraphQL 读写 issue、项目、团队、周期、标签、工作流状态、用户和评论。文档给出了 CLI、Python 和 JavaScript 三种调用方式,覆盖 Maton API Key 认证、多 Linear 连接管理,以及列表、搜索、创建、更新等常见操作。CLI 自动处理基于游标的分页;类似 ABC-123 的标识符可直接替代 UUID 使用。所有写操作都需要先获得用户明确确认;部分变更操作可能依赖额外的 OAuth 权限,遇到权限错误需联系 Maton 申请扩展。

什么时候用它

  • 按团队列出并筛选 Linear issue
  • 按关键词全文搜索 issue
  • 创建或更新 issue,并添加评论
  • 管理多个 Linear OAuth 连接以对接不同工作区

技能文档

Linear

Access the Linear API with managed OAuth authentication. Query and manage issues, projects, teams, cycles, labels, and comments using GraphQL.

Quick Start

CLI:

maton linear issue list -c ABC -L 10
maton api '/linear/graphql'

Python:

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'query': '{ viewer { id name email } }'}).encode()
req = urllib.request.Request('https://api.maton.ai/linear/graphql', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Base URL

https://api.maton.ai/linear/graphql

All requests use POST to the GraphQL endpoint. Maton proxies requests to api.linear.app and automatically injects your OAuth token.

Installation

NPM:

npm install -g @maton/cli

Homebrew:

brew install maton-ai/cli/maton

Authentication

CLI:

maton login                          # Opens browser for API key
maton login --interactive            # Skip browser, paste API key directly
maton whoami                         # Show current auth state

Manual:

  1. Sign in or create an account at maton.ai
  2. Go to maton.ai/settings
  3. Copy your API key
  4. Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"

Connection Management

Manage your Linear OAuth connections at https://api.maton.ai.

List Connections

CLI:

maton connection list linear --status ACTIVE
maton api -X GET /connections -f app=linear -f status=ACTIVE

Python:

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=linear&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Create Connection

CLI:

maton connection create linear
maton api /connections -f app=linear

Python:

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'linear'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Get Connection

CLI:

maton connection view {connection_id}
maton api /connections/{connection_id}

Python:

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Response:

{
  "connection": {
    "connection_id": "{connection_id}",
    "status": "ACTIVE",
    "creation_time": "2026-02-04T23:03:22.676001Z",
    "last_updated_time": "2026-02-04T23:03:51.239577Z",
    "url": "https://connect.maton.ai/?session_token=...",
    "app": "linear",
    "metadata": {}
  }
}

Open the returned url in a browser to complete OAuth authorization.

Delete Connection

CLI:

maton connection delete {connection_id}
maton api -X DELETE /connections/{connection_id}

Python:

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Specifying Connection

If you have multiple Linear connections, specify which one to use:

CLI:

maton linear issue list -c ABC --connection {connection_id}
maton api /linear/graphql --connection {connection_id}

Python:

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'query': '{ viewer { id name } }'}).encode()
req = urllib.request.Request('https://api.maton.ai/linear/graphql', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

If you have multiple connections, always specify the connection to ensure requests go to the intended account.

Security & Permissions

  • Access is scoped to issues, projects, teams, cycles, and comments within the connected Linear account.
  • All write operations require explicit user approval. Before executing any create, update, or delete call, confirm the target resource and intended effect with the user.

API Reference

Linear uses a GraphQL API. All operations are sent as POST requests with a JSON body containing the query field.

Viewer (Current User)

POST /linear/graphql
Content-Type: application/json

{"query": "{ viewer { id name email } }"}

Example:

maton linear whoami

Organization

POST /linear/graphql
Content-Type: application/json

{"query": "{ organization { id name urlKey } }"}

Example:

maton linear org view

Teams

List Teams

POST /linear/graphql
Content-Type: application/json

{"query": "{ teams { nodes { id name key } } }"}

Example:

maton linear team list

Get Team

POST /linear/graphql
Content-Type: application/json

{"query": "{ team(id: \"ABC\") { id name key issues { nodes { id identifier title } } } }"}

Example:

maton linear team view ABC

Issues

List Issues

POST /linear/graphql
Content-Type: application/json

{"query": "{ issues(first: 10, filter: { team: { key: { eq: \"ABC\" } } }) { nodes { id identifier title state { name } priority createdAt } pageInfo { hasNextPage endCursor } } }"}

Example:

maton linear issue list -c ABC -L 10

Get Issue by ID or Identifier

POST /linear/graphql
Content-Type: application/json

{"query": "{ issue(id: \"ABC-123\") { id identifier title description state { name } priority assignee { name } team { key name } createdAt updatedAt } }"}

Example:

maton linear issue view ABC-123

Filter Issues

Filter by state type:

POST /linear/graphql
Content-Type: application/json

{"query": "{ issues(first: 10, filter: { state: { type: { eq: \"started\" } } }) { nodes { id identifier title state { name type } } } }"}

Example:

maton linear issue list --state started -L 10

Filter by title:

POST /linear/graphql
Content-Type: application/json

{"query": "{ issues(first: 10, filter: { title: { containsIgnoreCase: \"bug\" } }) { nodes { id identifier title } } }"}

Example:

maton linear issue list --title bug -L 10

Search Issues

POST /linear/graphql
Content-Type: application/json

{"query": "{ searchIssues(first: 10, term: \"shopify\") { nodes { id identifier title } } }"}

Example:

maton linear issue search shopify -L 10

Create Issue

POST /linear/graphql
Content-Type: application/json

{"query": "mutation { issueCreate(input: { teamId: \"TEAM_ID\", title: \"New issue title\" }) { success issue { id identifier title state { name } } } }"}

Example:

maton linear issue create --team-id TEAM_ID -t 'New issue title'

Update Issue

POST /linear/graphql
Content-Type: application/json

{"query": "mutation { issueUpdate(id: \"ABC-123\", input: { title: \"Updated title\", priority: 2 }) { success issue { id identifier title priority } } }"}

Example:

maton linear issue update ABC-123 -t 'Updated title' --priority 2

Projects

List Projects

POST /linear/graphql
Content-Type: application/json

{"query": "{ projects(first: 10) { nodes { id name state createdAt } } }"}

Example:

maton linear project list

Cycles

List Cycles

POST /linear/graphql
Content-Type: application/json

{"query": "{ cycles(first: 10) { nodes { id name number startsAt endsAt } } }"}

Example:

maton linear cycle list

Labels

List Labels

POST /linear/graphql
Content-Type: application/json

{"query": "{ issueLabels(first: 20) { nodes { id name color } } }"}

Example:

maton linear label list

Workflow States

POST /linear/graphql
Content-Type: application/json

{"query": "{ workflowStates(first: 20) { nodes { id name type team { key } } } }"}

Example:

maton linear state list

Users

POST /linear/graphql
Content-Type: application/json

{"query": "{ users(first: 20) { nodes { id name email active } } }"}

Example:

maton linear user list

Comments

List Comments

POST /linear/graphql
Content-Type: application/json

{"query": "{ issue(id: \"ABC-123\") { comments(first: 10) { nodes { id body createdAt user { name } } } } }"}

Example:

maton linear comment list --issue ABC-123 -L 10

Create Comment

POST /linear/graphql
Content-Type: application/json

{"query": "mutation { commentCreate(input: { issueId: \"ABC-123\", body: \"Looking into this\" }) { success comment { id body } } }"}

Example:

maton linear comment create --issue ABC-123 -b 'Looking into this'

Pagination

Linear uses Relay-style cursor-based pagination. The CLI automatically paginates with '--paginate'.

Example:

maton linear issue list -c ABC --paginate

Code Examples

CLI

# List issues for a team
maton linear issue list -c ABC -L 10

# View a specific issue
maton linear issue view ABC-123

# Create a new issue
maton linear issue create --team-id TEAM_ID -t 'Fix login'

# Add a comment
maton linear comment create --issue ABC-123 -b 'Looking into this'

JavaScript

const response = await fetch('https://api.maton.ai/linear/graphql', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.MATON_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    query: `{ issues(first: 10) { nodes { id identifier title state { name } } } }`
  })
});
const data = await response.json();

Python

import os
import requests

response = requests.post(
    'https://api.maton.ai/linear/graphql',
    headers={
        'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
        'Content-Type': 'application/json'
    },
    json={
        'query': '{ issues(first: 10) { nodes { id identifier title state { name } } } }'
    }
)
data = response.json()

Notes

  • Linear uses GraphQL exclusively (no REST API)
  • Issue identifiers like ABC-123 can be used in place of UUIDs for the id parameter
  • Priority values: 0 = No priority, 1 = Urgent, 2 = High, 3 = Medium, 4 = Low
  • Workflow state types: backlog, unstarted, started, completed, canceled
  • The GraphQL schema is introspectable at https://api.linear.app/graphql
  • Use searchIssues(term: "...") for full-text search across issues
  • Some mutations (delete, create labels/projects) may require additional OAuth scopes. If you receive a scope error, contact Maton support at support@maton.ai with the specific operations/APIs you need and your use-case

Error Handling

StatusMeaning
400Missing Linear connection or GraphQL validation error
401Invalid or missing Maton API key
403Insufficient OAuth scope for the operation
429Rate limited
4xx/5xxPassthrough error from Linear API

GraphQL errors are returned in the errors array:

{
  "errors": [
    {
      "message": "Invalid scope: `write` required",
      "extensions": {
        "type": "forbidden",
        "code": "FORBIDDEN",
        "statusCode": 403
      }
    }
  ]
}

Troubleshooting: API Key Issues

CLI:

  1. Check your auth state:
maton whoami
  1. Verify the API key is valid by listing connections:
maton connection list

Manual:

  1. Check that the MATON_API_KEY environment variable is set:
echo $MATON_API_KEY
  1. Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Troubleshooting: Invalid App Name

  1. Ensure your URL path starts with linear. For example:
  • Correct: https://api.maton.ai/linear/graphql
  • Incorrect: https://api.maton.ai/graphql

Resources

常见问题

这个技能会调用 Linear 的 REST 接口吗?
不会。Linear 只提供 GraphQL API,技能通过 https://api.maton.ai/linear/graphql 发送带 JSON 查询体的 POST 请求,再由 Maton 转发到 api.linear.app。
认证流程是怎样的?
需要将 Maton API Key 设置为 MATON_API_KEY 环境变量。Linear 的 OAuth 令牌由 Maton 自动托管;当存在多个连接时,可通过 Maton-Connection 请求头或 CLI 的 --connection 参数指定目标连接。
能否创建或修改 issue?
可以。文档涵盖了 issueCreate、issueUpdate 以及 commentCreate 等变更操作。所有写操作在执行前都需要用户明确确认;部分变更可能依赖未默认授予的额外 OAuth 权限。

相关技能

用 PIL 逐帧绘制并校验,生成符合 Slack 尺寸与体积限制的动图 GIF。

作者 Anthropic182.7k 星标

Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Codex's capabilities with specialized knowledge, workflo

作者 OpenAI28.2k 星标

yeet

官方

Use only when the user explicitly asks to stage, commit, push, and open a GitHub pull request in one flow using the GitHub CLI (`gh`).

作者 OpenAI28.2k 星标

Migrate supported instruction files, skills, agents, and MCP config into Codex project and global files.

作者 OpenAI28.2k 星标

linear

官方

Manage issues, projects & team workflows in Linear. Use when the user wants to read, create or updates tickets in Linear.

作者 OpenAI28.2k 星标

Install Codex skills into $CODEX_HOME/skills from a curated list or a GitHub repo path. Use when a user asks to list installable skills, install a curated skill, or install a skill from another repo (

作者 OpenAI28.2k 星标

byungkyu 的更多技能

浏览全部技能

按提示词自动选用合适的 dlazy CLI 音频模型,完成语音、音乐、音效与声音克隆。

作者 dlazy

类型化知识图谱引擎,将知识表示为可验证的实体-关系图谱。每个实体拥有类型、属性和关系, 所有变更在提交前根据类型约束进行验证。核心能力涵盖类型化实体创建与验证、关系图谱与基数约束、 Schema约束系统、无环验证、追加式变更日志、图谱遍历查询、跨技能契约声明、计划即图谱变换。 支持 Person、Organiza...

作者 oswalpalash2 次安装

创建、检查和编辑Microsoft PowerPoint演示文稿和PPTX文件,确保布局可靠,支持中文交互和自动化操作。

作者 Iván

按意图把图像、视频、音频请求分发到合适的 dlazy CLI 模型。

作者 dlazy

自动化审查代码安全漏洞、认证流和依赖合规,提供结构化报告支持多语言,无需复杂配置,适用开发者与企业团队。

作者 jgarrison929