MCP より Skill + CLI。Sentry MCP をやめて マルチプロファイル対応 CLI にした

2026-02-22 03:38 (20 days ago)
Whence Trick
この記事をテーマにした曲を再生

背景

Sentry の CLI ツール sentry-cli を複数の組織 (Organization) で使いたいが、AWS CLI の --profile のようなネイティブなマルチプロファイル機能は存在しない。

sentry-cli のインストール

brew install getsentry/tools/sentry-cli

設定の優先順位

公式ドキュメント (Configuration and Authentication) によると、設定は以下の優先順位で読み込まれる:

  1. コマンドライン引数 (-o, -p, --auth-token)
  2. 環境変数 (SENTRY_AUTH_TOKEN, SENTRY_ORG, SENTRY_PROJECT)
  3. カレントディレクトリから上方向に .sentryclirc ファイルを検索
  4. ~/.sentryclirc (グローバルデフォルト)

.sentryclirc はファイル名が固定で、リネームした別名のファイル(.sentryclirc-staging 等) は読み込まれない (参考)。

Sentry MCP Server はどうか

Sentry は MCP サーバー も提供しており、AI エージェントから直接 Sentry を操作できる。しかし、いくつかの課題がある:

  • 旧版 (stdio transport + Auth Token) は事実上の後継版に置き換えられたsentry-mcp-stdio リポジトリは「教育目的」として残っているが、現在は リモート版 MCP サーバー の使用が推奨されている
  • 新版 (OAuth + Streamable HTTP) は、セッションの有効期限が切れるたびに再認証が必要。ブラウザで OAuth 認証フローを再度行う必要があり、作業の流れが中断されるのがストレスになる
  • コンテキストを大量消費する。Sentry のイベントやイシュー情報は構造が複雑で、MCP のツール定義だけでもかなりのトークンを使う
  • マルチアカウントに対応していない。複数の MCP サーバーインスタンスを作ることで対応は可能だが、消費コンテキストがインスタンス数に比例して増えるのでつらい

結局、CLI ラッパー + AI エージェントのスキルという構成の方が、軽量かつ柔軟に扱える。

解決策: zsh ラッパー関数

zsh の function は PATH 上の同名バイナリより常に優先されるため、sentry-cli という名前の function を定義するだけで、brew でインストールした本物の sentry-cli をラップできる。

プロファイルの保存場所

~/.config/sentry-cli/profiles/<name>.env

中身はシンプルな env ファイル:

SENTRY_AUTH_TOKEN=sntrys_xxx...
SENTRY_ORG=my-org
SENTRY_URL=https://my-org.sentry.io/

SENTRY_PROJECT はプロファイルに固定せず、コマンド実行時に -p で指定する運用が良い。1つの org に複数の project があるのが普通なので。

ラッパー関数

~/.zshrc や alias ファイル等に以下の function を追加する:

# sentry-cli wrapper with --profile support
# Profiles: ~/.config/sentry-cli/profiles/<name>.env
function sentry-cli () {
  local _sentry_cli
  # whence -p: function を無視してバイナリのパスだけ返す
  _sentry_cli=$(whence -p sentry-cli) || { echo "sentry-cli not found in PATH" >&2; return 1; }
  local profile_dir="${HOME}/.config/sentry-cli/profiles"
  local profile=""
  local setup=0
  local args=()

  while [[ $# -gt 0 ]]; do
    case "$1" in
      --profile=*) profile="${1#--profile=}"; shift ;;
      --profile)   profile="$2"; shift 2 ;;
      --profiles)
        if [[ -d "$profile_dir" ]]; then
          for f in "$profile_dir"/*.env(N); do
            echo "${f:t:r}"
          done
        else
          echo "No profiles directory: $profile_dir" >&2
        fi
        return 0
        ;;
      --setup) setup=1; shift ;;
      *) args+=("$1"); shift ;;
    esac
  done

  # --setup: create or edit a profile
  if [[ $setup -eq 1 ]]; then
    if [[ -z "$profile" ]]; then
      echo "Usage: sentry-cli --profile=<name> --setup" >&2
      return 1
    fi
    mkdir -p "$profile_dir"
    local pfile="${profile_dir}/${profile}.env"
    if [[ -f "$pfile" ]]; then
      echo "Editing existing profile: $profile"
    else
      echo "Creating new profile: $profile"
      cat > "$pfile" <<TMPL
SENTRY_AUTH_TOKEN=
SENTRY_ORG=${profile}
SENTRY_URL=https://${profile}.sentry.io/
TMPL
    fi
    ${EDITOR:-vim} "$pfile"
    return 0
  fi

  # No profile: passthrough
  if [[ -z "$profile" ]]; then
    "$_sentry_cli" "${args[@]}"
    return $?
  fi

  # Load profile and run
  local pfile="${profile_dir}/${profile}.env"
  if [[ ! -f "$pfile" ]]; then
    echo "Profile not found: $pfile" >&2
    echo "Run: sentry-cli --profile=${profile} --setup" >&2
    return 1
  fi

  # サブシェルで source して現在の環境変数を汚さない
  (
    set -a
    source "$pfile"
    set +a
    "$_sentry_cli" "${args[@]}"
  )
}

ハマりポイント: command -v の罠

最初の実装では command -v sentry-cli でバイナリパスを取得していたが、zsh の command -v は同名の function 自身も返してしまうため、無限再帰になり maximum nested function level reached; increase FUNCNEST? エラーが発生した。

whence -p を使うことで、function を無視してバイナリパスだけを取得できる。これは zsh 固有のビルトインコマンド。

使い方

# プロファイル作成 (エディタが開く)
sentry-cli --profile=myorg --setup

# 接続確認
sentry-cli --profile=myorg info

# プロジェクト一覧
sentry-cli --profile=myorg projects list

# リリース一覧 (プロジェクト指定)
sentry-cli --profile=myorg releases list -p my-project

# プロファイル一覧
sentry-cli --profiles

# プロファイルなし (通常の sentry-cli として動作)
sentry-cli info

Claude Code のスキルとして登録

このラッパーを Claude Code のスキルとしても登録した。SKILL.md を書いておくことで、AI エージェントが自然に sentry-cli --profile=xxx を使って Sentry を操作できるようになる。

以下がスキル定義の全体像:

---
name: sentry-cli
description: Sentry CLI のマルチプロファイル対応ラッパー。リリース管理・ソースマップアップロード・イベント送信など。
allowed-tools: Bash(sentry-cli:*)
---

# Sentry CLI (multi-profile wrapper)

Sentry CLI をマルチプロファイルで使うための zsh ラッパー。

## 重要: 操作前にヘルプを確認

sentry-cli のサブコマンドや引数が不明な場合、まずヘルプを読むこと。

  sentry-cli --help
  sentry-cli <subcommand> --help

## プロファイル管理

### プロファイル作成・編集

  sentry-cli --profile=<name> --setup

### プロファイル一覧

  sentry-cli --profiles

### プロファイルを指定して実行

  sentry-cli --profile=<name> <subcommand> [options]

### プロファイルなしで実行 (通常の sentry-cli として動作)

  sentry-cli <subcommand> [options]

## よく使うサブコマンド

- info: 接続情報と認証状態を確認
- releases: リリースの一覧・作成・ファイナライズ
- sourcemaps: ソースマップのアップロード
- send-event: テストイベントの送信
- deploys: デプロイの記録
- issues: イシューの一覧・解決
- projects: プロジェクトの一覧

ポイントは:

  • allowed-tools: Bash(sentry-cli:*) で、エージェントに sentry-cli コマンドの実行を許可
  • 操作前に --help を読む指示を含めることで、サブコマンドの引数ミスを防ぐ
  • プロファイル管理コマンドよく使うサブコマンドをリファレンスとして記載し、エージェントがすぐに使えるようにする

まとめ

  • sentry-cli にはネイティブなマルチプロファイル機能がない
  • Sentry MCP Server は OAuth の再認証やコンテキスト消費の問題があり、マルチアカウント対応も弱い
  • zsh function でラップすれば、--profile オプションで簡単に切り替えられる
  • whence -p を使わないと無限再帰になるので注意
  • Claude Code のスキルとして登録すれば、AI エージェントからもシームレスに操作可能

アーカイブ