Claude Code Skills × 自己完結スクリプト — MCP/CLI の先にある「トークン効率」設計

gunta85 さんが、Claude Code の Skill において自己完結スクリプト(Self-contained Scripts)の活用を推奨するポストを投稿しています。

Skill は MCP でも CLI ツールでもなく、Self-contained Script がおすすめ。 外部ライブラリの依存を 1 ファイル内で宣言でき、MCP に比べてトークン消費を劇的に削減できる。

https://x.com/gunta85/status/1929915853508456604

この発言の背景には、mizchi さんによる「MCP はただの CLI/API ラッパーに過ぎない」という指摘もあります。MCP のツール定義だけで数万トークンを消費する問題が顕在化するなか、Agent Skills 仕様が提供する「自己完結スクリプト」は、より効率的な選択肢として注目されています。

Agent Skills とは何か

Agent Skills は、AI エージェントにドメイン知識と実行能力を付与する仕様です。agentskills.io で公開されており、Claude Code をはじめとする複数のエージェントが対応しています。

ディレクトリ構成

.claude/skills/my-skill/
  SKILL.md          # スキルの説明と使用手順
  references/       # 参考ドキュメント(必要時のみ読込)
  scripts/          # 自己完結スクリプト
  templates/        # テンプレートファイル

プログレッシブ・ディスクロージャ

Agent Skills の設計思想の核心は「段階的な情報開示」です。

段階内容トークン目安
メタデータfrontmatter(名前・説明・引数)~100 トークン
指示文SKILL.md 本文<5,000 トークン
リソースreferences/ 配下のファイル必要時のみ

MCP サーバーがツール定義だけで大量のトークンを消費するのに対し、Skills は必要な情報を段階的に読み込むため、コンテキストウィンドウを効率的に使えます。

自己完結スクリプトの仕組み

scripts/ ディレクトリに配置するスクリプトは、依存関係をファイル内で宣言します。外部パッケージマネージャの事前セットアップが不要で、エージェントが即座に実行できます。

Python(PEP 723: Inline Script Metadata)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "requests",
#     "beautifulsoup4",
# ]
# ///

import requests
from bs4 import BeautifulSoup

def scrape(url: str) -> str:
    resp = requests.get(url)
    soup = BeautifulSoup(resp.text, "html.parser")
    return soup.get_text()

PEP 723 により、Python スクリプトが依存パッケージを自身の中で宣言できます。uv run --script で自動的に仮想環境を作成し、依存をインストールして実行します。

Bun(自動インストール)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/usr/bin/env bun
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();
const message = await client.messages.create({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Hello" }],
});
console.log(message.content);

Bun はインポート文を検出すると自動的にパッケージをインストールします。package.jsonnode_modules も不要です。

Deno(npm: 指定子)

1
2
3
4
5
#!/usr/bin/env -S deno run --allow-net
import Anthropic from "npm:@anthropic-ai/sdk";

const client = new Anthropic();
// ...

Deno は npm: プレフィックスで npm パッケージを直接参照できます。権限モデルにより --allow-net などを明示的に指定します。

ワンショットコマンド

スクリプトファイルを作成せず、既存ツールを直接呼び出す方法もあります。

1
2
3
4
5
6
7
## 使い方
画像を最適化するには:
\`\`\`bash
uvx ruff check --fix .
npx prettier --write .
bunx tsc --noEmit
\`\`\`

uvxnpxbunx はそれぞれ一時的な環境でツールを実行し、グローバルインストールを汚しません。

MCP のトークン消費問題

MCP(Model Context Protocol)が抱える根本的な問題は、ツール定義のトークンコストです。

数字で見る問題

構成トークン消費
GitHub MCP サーバー(93 ツール)~55,000 トークン(定義だけ)
MCP サーバー 3 つスタック150,000+ トークン(クエリ前)
CLI 代替MCP 比で 35 分の 1 に削減

93 個のツール定義がコンテキストに常駐するため、実際の質問を処理する前にウィンドウの大部分を消費します。

mizchi さんの指摘

mizchi さんは「MCP はただの CLI/API のラッパー」と指摘し、以下の問題を提起しています。

  • MCP サーバーの多くは、既存の CLI コマンドや REST API をラップしているだけ
  • ツール定義のオーバーヘッドが大きく、シンプルなタスクには過剰
  • エージェントが直接 CLI を呼べるなら、MCP レイヤーは不要な場合が多い

Skills vs MCP vs CLI の使い分け

3 つのアプローチは排他的ではなく、タスクの性質に応じて使い分けます。

観点Skills(スクリプト)MCPCLI 直接呼出
トークン効率高い(段階的読込)低い(全定義常駐)高い
ドメイン知識SKILL.md で付与ツール説明に依存なし
外部データ接続スクリプト内で実装プロトコル標準化個別実装
セットアップファイル配置のみサーバー起動が必要PATH に存在
再利用性リポジトリ共有可能サーバー単位で共有環境依存

Skills が適するケース:

  • プロジェクト固有のワークフロー自動化
  • チーム内で共有するコード品質チェック
  • ドメイン知識が必要な定型作業(例: デプロイ手順、レポート生成)

MCP が適するケース:

  • 外部サービスとのリアルタイム連携(DB、API)
  • 複数のエージェント間でのデータ共有
  • 認証が必要な外部システムへのアクセス

CLI が適するケース:

  • 既存ツールの単純な呼び出し(git, docker, aws)
  • 一度きりのアドホック操作

エージェント向けスクリプト設計のベストプラクティス

agentskills.io の仕様では、スクリプトを「エージェントが実行する前提」で設計することを推奨しています。

5 つの設計原則

  1. 対話的プロンプトを排除input()readline を使わず、全てコマンドライン引数で受け取る
  2. --help を実装 — エージェントがスクリプトの使い方を自己発見できるようにする
  3. 構造化出力 — JSON で結果を返し、エージェントがパースしやすくする
  4. 冪等性 — 同じ引数で複数回実行しても同じ結果になる設計
  5. 終了コード — 成功は 0、失敗は非ゼロで、エージェントがエラーを検知できる
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = ["requests"]
# ///
import argparse, json, sys, requests

def main():
    parser = argparse.ArgumentParser(description="APIステータスチェック")
    parser.add_argument("url", help="チェック対象のURL")
    parser.add_argument("--timeout", type=int, default=10)
    args = parser.parse_args()

    try:
        resp = requests.get(args.url, timeout=args.timeout)
        print(json.dumps({
            "status": resp.status_code,
            "ok": resp.ok,
            "elapsed_ms": resp.elapsed.total_seconds() * 1000
        }))
    except Exception as e:
        print(json.dumps({"error": str(e)}), file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    main()

実践: Skills スクリプトの導入手順

1. ディレクトリ作成

1
mkdir -p .claude/skills/my-tool/scripts

2. SKILL.md 作成

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
---
name: api-health-check
description: API エンドポイントの死活監視
arguments:
  - name: url
    description: チェック対象の URL
    required: true
---

# API Health Check

指定された URL の HTTP ステータスとレスポンスタイムを JSON で返します。

## 使い方

\`\`\`bash
./scripts/check.py <url> [--timeout 10]
\`\`\`

3. スクリプト配置と権限付与

1
chmod +x .claude/skills/my-tool/scripts/check.py

これだけで、エージェントは /api-health-check のようにスキルを呼び出し、スクリプトを実行できます。

まとめ

  • 自己完結スクリプトは、依存関係をファイル内で宣言し、パッケージマネージャの事前設定なしで実行できる
  • PEP 723(Python)、Bun 自動インストールDeno npm: 指定子が、主要な言語でインライン依存宣言を実現している
  • MCP のトークン消費問題は深刻で、93 ツールの GitHub サーバーだけで ~55,000 トークンを消費する
  • Skills のプログレッシブ・ディスクロージャ設計により、メタデータ ~100 トークンから段階的に情報を読み込み、コンテキストを節約できる
  • CLI 直接呼出は MCP 比 35 分の 1 のトークン消費で、単純な操作には最適解
  • エージェント向け設計原則(非対話・–help・JSON 出力・冪等性・終了コード)を守ることで、スクリプトの信頼性が向上する
  • Skills / MCP / CLI は排他ではなく補完関係にあり、トークン効率・外部連携・ドメイン知識の必要性で使い分ける

参考