mcpField
L
linear-sdk-scripting

linear-sdk-scripting

github.com/cline生産性401.2k 回インストール15 週間前に更新
リポジトリ

linear-sdk-scripting について

linear-sdk-scriptingは、公式TypeScript SDKとNode.jsスクリプトでLinearを操作するスキルです。認証やSDKの使い方に加え、課題、チーム、プロジェクト、サイクルの操作例を扱います。

主な機能

  1. 01@linear/sdkでLinearを操作
  2. 02課題の読み取りと作成
  3. 03コメント追加と課題ステータス変更
  4. 04チーム、プロジェクト、サイクルの検索
  5. 05ページネーションと更新の例

活用シーン

  1. 01Linearの課題の読み取りや絞り込み
  2. 02課題の作成とコメント追加
  3. 03課題のワークフローステータス変更
  4. 04チーム、プロジェクト、サイクルの検索

MCP 対応

このスキルはLinear MCPサーバーの代替として説明されており、MCPではなくLinear SDKのメソッドで同様の操作を行います。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/cline/skills --skill linear-sdk-scripting

インストール後、Claude Code で/linear-sdk-scriptingを入力して読み込まれたか確認します。

同梱ファイルreferences/docs-index.mdreferences/recipes.md

詳細

Linear SDK スクリプティング

公式の TypeScript SDK(@linear/sdk)を使い、使い捨ての Node スクリプトを作成して実行することで、Linear を操作します。これは Linear MCP サーバーの代わりとなる方法です。MCP でできること(イシューの読み取り、イシューの作成、コメント、ステータスの変更、チーム/プロジェクト/サイクルの検索)は、すべて SDK のメソッドを呼び出して行います。

ページネーション、関連情報のたどり方、ミューテーションのペイロードが標準化されており、メソッド名と入力名も予測しやすいため、手書きの GraphQL より SDK を推奨します。必要なフィールドやフィルターがわからない場合は、references/docs-index.md のドキュメントインデックスを確認し、推測するのではなく、該当するページを取得してください。

ワークフローの概要

状況に応じて対応してください。まずスクリプトを試し、認証に失敗したら対処します。キーの作成は最後の手段にしてください。現在のシェルで $LINEAR_API_KEY が設定されていることを条件にしないでください。Setup に記載のとおり、有効なキーがすでに保存されていても、この環境ではその変数が空であることがほとんどです。

  1. SDK が作業ディレクトリにインストールされていることを確認します。Setup を参照してください。
  2. LinearClient をインポートしてタスクを実行する小さな .mjs スクリプトを作業ディレクトリに作成します。
  3. Execution pattern に従い、保存済みのキーが読み込まれるよう、先にシェルのプロファイルを読み込んでから node で実行します。
  4. 401/AuthenticationLinearError で失敗した場合は、シェルのプロファイルを読み込んでから一度だけ再試行します。それでも失敗する場合に限り、キーが実際にないか無効です。その場合は、ユーザーと一緒に API キーの設定手順を進めます。

セットアップ

1. Personal API key

SDK は、LINEAR_API_KEY 環境変数から読み込む Linear の個人用 API キーで認証します。

最初に環境変数を確認して、キーがあるかどうかを判断しないでください。ここで実行するスクリプトは、~/.zshrc、~/.zshenv、~/.bashrc などを読み込まない、非対話型の非ログインシェルで動作します。そのため、これらのファイルのいずれかに有効なキーがすでに保存されていても、$LINEAR_API_KEY は空になります。このシェルで変数が空でも、キーが設定されていないとは限りません。

代わりに、スクリプトに処理を試行させてください(Execution pattern で先にプロファイルを読み込みます)。その後も認証に失敗した場合に限り、キーがないと判断します。Handling auth failures を参照してください。

キーが本当にない場合に限り、ユーザーがキーを作成できるよう案内してください。

  1. Security and access settings を開きます:https://linear.app/settings/account/security

  2. Personal API keys で新しいキーを作成します。キーをコピーします(lin_api_ で始まります)。

  3. ユーザーにキーを貼り付けてもらい、新しいターミナルを開かなくてもすぐに使えるよう、現在のセッションに読み込みます。

    export LINEAR_API_KEY="lin_api_REPLACE_ME"
    
  4. 保存する前にユーザーに確認します。キーはシークレットであり、保存するとユーザーが所有するファイルに書き込まれるため、自分の判断で保存してはいけません。たとえば、「今後のセッションでも使えるよう、このキーをシェルプロファイル(~/.zshrc)に保存しますか?」と、明示的に確認してください。明確な許可を待ちます。

    ユーザーが確認した後に限り、ユーザーのシェルに応じたコマンドを使って、自分で書き込みを行います。

    • zsh:
      echo 'export LINEAR_API_KEY="lin_api_REPLACE_ME"' >> ~/.zshrc
      
    • bash(または macOS のログインシェルで ~/.bash_profile を使う場合):
      echo 'export LINEAR_API_KEY="lin_api_REPLACE_ME"' >> ~/.bashrc
      
    • fish:
      echo 'set -gx LINEAR_API_KEY "lin_api_REPLACE_ME"' >> ~/.config/fish/config.fish
      

    会話内で明示的な許可を得ることで、この書き込みはエージェントが自発的に行うのではなく、ユーザーから依頼された操作となります。ユーザーが断った場合や返答しなかった場合は、キーを保存しないでください。次のセッションで再設定する必要があります。

キーの値を会話の記録に出力したり、どこかにコミットしたりしないでください。シークレットとして扱ってください。

2. SDK を作業ディレクトリにインストールする

専用の作業ディレクトリを用意し、その中に独自の node_modules を置いてください。その中からスクリプトを実行すれば、NODE_PATH の小細工をせずに、トップレベル await を使った通常の import が利用できます。Node 18 以降が必要です。

LINEAR_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/linear-sdk-scripting"
mkdir -p "$LINEAR_DIR"
cd "$LINEAR_DIR"
[ -f package.json ] || npm init -y >/dev/null
npm ls @linear/sdk >/dev/null 2>&1 || npm install @linear/sdk

これは初回のみのセットアップです。以降は同じディレクトリを再利用してください。

実行パターン(標準)

各タスクでは、作業ディレクトリにスクリプトを書いて実行します。環境変数を使用し、キーを直接埋め込まないでください。

node を実行する前に共通のシェルプロファイルを読み込み、保存済みのキーが環境変数に設定されるようにします(このシェルでは自動的に読み込まれません)。キーが保存されていない場合でも、この前処理は問題ないため、すべてのスクリプトを実行する際の標準的な方法として使用してください。

LINEAR_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/linear-sdk-scripting"
cat > "$LINEAR_DIR/task.mjs" <<'EOF'
import { LinearClient } from "@linear/sdk"

const linear = new LinearClient({ apiKey: process.env.LINEAR_API_KEY })

const me = await linear.viewer
const myIssues = await me.assignedIssues({ first: 20 })
for (const issue of myIssues.nodes) {
  console.log(`${issue.identifier}  ${issue.title}`)
}
EOF
for f in ~/.zshenv ~/.zshrc ~/.zprofile ~/.profile ~/.bashrc ~/.bash_profile; do
  [ -f "$f" ] && source "$f"
done
node "$LINEAR_DIR/task.mjs"

注意:

  • スクリプトファイルは作業ディレクトリに置かれるため、import "@linear/sdk" はそのディレクトリの node_modules を参照します。
  • .mjs ではトップレベルの await が使えるため、非同期処理のラッパーは不要です。
  • 後続の手順で結果を解析する必要がある場合は、機械可読な出力(console.log(JSON.stringify(...)))を出力してください。

認証エラーへの対処

キーがない、または無効な場合は、status が 401 の AuthenticationLinearError が発生します。これを検出し、キーの設定フローに進んでください。

try {
  const me = await linear.viewer
  console.log(me.displayName)
} catch (e) {
  if (e?.status === 401 || e?.constructor?.name === "AuthenticationLinearError") {
    console.error("AUTH_FAILED: set up LINEAR_API_KEY")
    process.exit(2)
  }
  throw e
}

AUTH_FAILED が表示された場合(またはデータが得られる前にスクリプトがクラッシュした場合)は、すぐにキーを作成するのではなく、次の順序で対処してください。

  1. シェルプロファイルを読み込んで、もう一度試してください。キーがこのシェルでは読み込まれなかったプロファイルファイルに、すでに保存されている可能性があります。キーを読み込んで、同じスクリプトを再実行してください。

    for f in ~/.zshenv ~/.zshrc ~/.zprofile ~/.profile ~/.bashrc ~/.bash_profile; do
      [ -f "$f" ] && source "$f"
    done
    node "$LINEAR_DIR/task.mjs"
    

    (すでに標準の実行パターンの前処理を実行している場合は、プロファイルが読み込まれているため、この再試行が役立つのは、前処理なしで実行した場合のみです。)

  2. それでも認証に失敗する場合に限り、キーが本当に存在しないか、無効です。この場合は、ユーザーと一緒に個人用 API キーを設定(新しいキーを作成して保存)してから、再実行してください。

一般的な操作

簡潔なレシピを以下に示します。より詳しい例(フィルタリング、ページネーションのループ、ワークフローの状態を使った課題のクローズ、一括操作)は references/recipes.md にあります。ドキュメントのインデックスは references/docs-index.md にあります。

読み取り:

// Current user
const me = await linear.viewer

// List issues (newest first), with a filter
const issues = await linear.issues({
  first: 25,
  filter: { state: { type: { eq: "started" } } },
})

// A single issue by UUID
const issue = await linear.issue("UUID")

// Teams, users, projects
const teams = await linear.teams()
const users = await linear.users()
const projects = await linear.projects({ first: 50 })

書き込み(変更操作は success とエンティティを含むペイロードを返します。多くの場合、これは Promise です):

// Create
const created = await linear.createIssue({
  teamId: "TEAM_UUID",
  title: "Title",
  description: "Markdown body",
})
const newIssue = await created.issue

// Update (e.g. retitle, reassign)
await linear.updateIssue("ISSUE_UUID", { title: "New title", assigneeId: "USER_UUID" })

// Comment
await linear.createComment({ issueId: "ISSUE_UUID", body: "Comment text" })

人が入力した値を ID(ENG のようなチームキー、Done のようなワークフロー状態名、担当者のメールアドレス)に対応付けるには、まず検索してください。チームの完了済みワークフロー状態を見つけて課題をクローズする方法など、検索してから変更するパターンについては references/recipes.md を参照してください。

ここに記載されていないことが必要な場合

Linear のスキーマは大規模です。フィールド名やフィルター名を推測するのではなく、次の手順に従ってください。

  1. references/docs-index.md を開き、関連するページを選びます。
  2. そのページ(フィルタリング、ページネーション、SDK によるデータの取得と変更、または GraphQL スキーマリファレンス)を取得し、記載されている正確な名前を使用します。

注意点

  • @linear/sdk が解決されるよう、作業ディレクトリからスクリプトを実行する(またはそのディレクトリ内のスクリプトを指定する)必要があります。NODE_PATH は ESM の import ではパッケージを解決しません。CommonJS の require でのみ機能します。
  • SDK のプロパティやネストされたリレーションの多くは非同期であり、Promise または接続を返します。await issue.state や await issue.assignee のように await を使用してください。
  • 接続はページネーションされます。connection.pageInfo.hasNextPage と await connection.fetchNext() を使うか、反復処理してください。references/recipes.md を参照してください。
  • 変更操作の結果には success と変更後のエンティティが含まれます。エンティティのアクセサーは通常 Promise です(await payload.issue)。

コメント