Yappli Tech Blog

株式会社ヤプリの開発メンバーによるブログです。最新の技術情報からチーム・働き方に関するテーマまで、日々の熱い想いを持って発信していきます。

gRPCのCLIツールを操作するAgent Skillを作った話

はじめに

サーバーエンジニアの 水戸(@penguin4glte) です。 皆さん、AI使ってますか?

今回は、私が作ったAgent Skill「grpcurl」を紹介します。

背景

弊社のバックエンドは gRPC を使っています。開発中、「このエンドポイントちゃんと動くかな」と確認したいとき、毎回 grpcurl コマンドを手書きするのが地味に面倒でした。

具体的には:

  • サーバーの種別によってポート番号が異なる
  • 認証ヘッダーの指定方法がサーバーごとに異なる(種別によって必要なヘッダーが変わる)
  • メソッド名のフルパスを調べるのが手間(<パッケージ名>.<サービス名>/<メソッド名> みたいな長い名前)

これらを毎回ゼロから組み立てるのをやめたくて、Claude Code のスキルとして実装しました。

Agent Skill とは

Claude Code にはスキル(Skill)という仕組みがあります。.claude/skills/<スキル名>/SKILL.md にマークダウンで「どう動くか」を記述しておくと、/<スキル名> と打つだけでそのスキルが発動します。

スキルの中身は自然言語の手順書です。Claude がその手順に従いながらユーザーと対話し、最終的にコマンドを組み立てて実行してくれます。

最小構成はこのようなイメージです:

---
name: grpcurl
description: grpcurlコマンドを使ってgRPCエンドポイントの疎通確認を行う
---

## 手順

### Step 1: ...
### Step 2: ...

frontmatter に namedescription を書き、あとは自然言語で手順を記述するだけです。コードは一切書かずに済みます。

grpcurl スキルの動き

スキルを起動すると、以下のステップで進みます。

Step 1: サーバー種別の選択

まず利用可能なサーバーの一覧を提示します。

弊社では用途ごとに複数の gRPC サーバーが分かれており、それぞれ固有のポートと起動コマンドが割り当てられています。

スキルにはこのマッピングをあらかじめ埋め込んでおき、サーバー種別を選ぶとポートが自動で決まります。

Step 2: 対話形式で必要な情報を収集

続いて、ユーザーに順番に質問します。

  1. ホスト — デフォルトは localhost
  2. サーバー種別 — サーバー種別を選ぶとポートが自動で決まる
  3. サービス/メソッドパッケージ名.サービス名/メソッド名 形式
  4. 認証ヘッダー — サーバー種別によって聞く内容が変わる

認証ヘッダーはサーバーごとに異なります。たとえば:

  • セッション系のトークンが必要なサーバー
  • アプリ識別子+ユーザー識別子の組み合わせが必要なサーバー
  • エンドポイントのグループによって必要なヘッダーが変わるサーバー

このあたりの条件分岐をスキルに埋め込んでおき、サーバー種別を選ぶだけで Claude が適切なヘッダーを聞いてくれるようにしました。

Step 3: コマンドの構築と実行

収集した情報から grpcurl コマンドを組み立て、実行前にユーザーへ提示して確認を取ります。

(ヘッダー名・サービス名は社内情報のため伏せています)

grpcurl \
  -plaintext \
  -H "<認証ヘッダー1>: <値>" \
  -H "<認証ヘッダー2>: <値>" \
  -d @ \
  localhost:<ポート> \
  <パッケージ名>.<サービス名>/<メソッド名> <<EOM
{ "key": "value" }
EOM

Step 4: 結果の表示

レスポンス JSON を整形して表示します。エラーが出た場合は原因の候補も案内します:

  • PermissionDenied → 認証ヘッダーの誤り
  • Unavailable → サーバー未起動(対応する make コマンドを案内)
  • Unimplemented → メソッド名の誤り

作っていて詰まったこと

proto ファイル指定から reflection に切り替えた

最初のバージョンでは、proto ファイルのパスを -import-path / -proto で明示的に渡していました。

(パス・ヘッダー名は社内情報のため伏せています)

grpcurl \
  -plaintext \
  -import-path <protobufリポジトリのルート> \
  -proto <サービス定義の.protoファイルパス> \
  -H "<認証ヘッダー>: <値>" \
  ...

この方式だと、Claude がまずリポジトリを Glob で探して該当の .proto ファイルを特定する必要があり、手順が複雑でした。

ローカルサーバーは gRPC reflection が有効になっているため、実は proto ファイルなしで grpcurl が動きます。これに気づいて reflection ベースに切り替えたら、スキルの手順がシンプルになりました。

# reflection が有効なのでこれだけでサービス一覧が取得できる
grpcurl -plaintext localhost:<ポート> list

認証ヘッダーの条件分岐が複雑だった

各サーバーの認証方式を正確に把握するのに時間がかかりました。特に

  • サーバーによっては、見た目は似ていても全く異なる種類のヘッダーが必要
  • 同じサーバー内でも、エンドポイントのグループごとに認証要件が変わる

最初のスキルの記述が不正確で、いざ使ってみると認証エラーが出て気づきました。実際に動かしながら修正する過程が必要でした。

使ってみた感想

一番よかったのは「サービス一覧から選べる」ところです。grpcurl -plaintext localhost:<ポート> list でサービス名を確認し、そこから選ぶだけでフルパスのメソッド名が決まります。

長いパッケージ名を手で打つミスがなくなりました。

認証ヘッダーの組み立ても、サーバー種別を選ぶだけで Claude が判断してくれるので、「あのサーバーのヘッダーなんだっけ」と調べる手間が省けています。

まとめ

grpcurl スキルを作って以来、疎通確認のたびに「ポート何番だっけ」「このサーバーの認証ヘッダーなんだっけ」とドキュメントを開く習慣がなくなりました。地味な変化ですが、作業中に集中が途切れなくなった感覚があります。

Claude Code のスキルは自然言語で書けるので、コードを書かなくても CLI ツールの操作を自動化できます。繰り返し手でやっている操作があればスキル化するのがおすすめです。

スキルのファイルはリポジトリに置いておけばチームで共有できるので、「このコマンドどう使うんだっけ」を解決する手段としても活用できそうです。次は別のコマンドもスキル化してみようと思っています。