🤖

mcps: MCP Server Selectorを作った

に公開

はじめに

MCP(Model Context Protocol)を使っていると、プロジェクトごとに異なるMCPサーバーを有効にしたくなることがあります。しかし、設定ファイルを毎回手動で編集するのは面倒です。

そこで、Unixの哲学に基づいたMCPサーバーセレクタ「mcps」を作りました。

MCPとは

MCP(Model Context Protocol)は、AIモデルが外部のツールやデータソースと連携するためのプロトコルです。GitHubやファイルシステム、データベースなど、様々なサービスと連携できるサーバーが提供されています。

解決したい問題

MCPの設定ファイルは通常、以下のようなJSON形式です:

{
  "mcpServers": {
    "github": {
      "command": "node",
      "args": ["/path/to/github-server/index.js"],
      "env": {
        "GITHUB_TOKEN": "op://vault/github/token"
      }
    },
    "filesystem": {
      "command": "node",
      "args": ["/path/to/fs-server/index.js"]
    },
    "database": {
      "command": "node",
      "args": ["/path/to/db-server/index.js"]
    }
  }
}

プロジェクトごとに必要なサーバーは異なりますが、毎回JSONを手動で編集するのは面倒です。特に:

  • サーバーが多い場合、どれを有効にするか覚えておくのが大変
  • JSON編集時にシンタックスエラーを起こしやすい
  • プロジェクトごとに設定を切り替えるのが煩雑

mcpsの設計思想

mcpsはUnixの哲学に基づいて設計されています:

  1. 一つのことをうまくやる - MCPサーバーの選択に特化
  2. 標準入力から読む - 他のツールと組み合わせやすい
  3. 標準出力に書く - リダイレクトで自由に出力先を選べる
  4. 静かに動作する - 余計な出力をしない
  5. シンプルなインターフェース - JSONを受け取ってJSONを返すだけ

使い方

インタラクティブモード

fzfを使った対話的な選択が可能です:

cat database.json | mcps > config.json

mcps interactive mode

TABキーで複数選択、ENTERで確定します。fzfの強力な検索機能も使えるので、サーバーが多くても素早く選択できます。

スクリプタブルモード

CIやスクリプトでの利用を想定したモードです:

cat database.json | mcps --enable github,filesystem > config.json

その他のオプション

# アルファベット順にソート
cat database.json | mcps --enable-all --sort > sorted.json

実装のポイント

Unixフィルタとして動作

mcpsは標準的なUnixフィルタとして実装されています:

# 標準入力からJSONを読む
try:
    data = json.load(sys.stdin)
except:
    sys.exit(1)  # エラー時は静かに終了

# 処理...

# 標準出力にJSONを出力
json.dump(output, sys.stdout, indent=2)

fzfとの統合

fzfは外部プロセスとして呼び出されます:

def select_servers_fzf(servers: List[str]) -> List[str]:
    """Use fzf for interactive server selection."""
    result = subprocess.run(
        [
            "fzf",
            "--multi",
            "--height", "50%",
            "--layout", "reverse",
            "--header", "Select MCP servers (TAB to select, ENTER to confirm)",
            "--prompt", "Search> ",
            "--marker", "✓",
            "--border", "rounded"
        ],
        input="\n".join(servers),
        text=True,
        capture_output=True
    )

エラーハンドリング

Unixの哲学に従い、エラー時は静かに失敗します:

# fzfが見つからない場合
except FileNotFoundError:
    sys.exit(1)  # メッセージを出さずに終了

# 不正なJSONの場合
except:
    sys.exit(1)  # 同様に静かに終了

実際の使用例

1Passwordと組み合わせた安全な設定管理

1Password CLIのop injectと組み合わせることで、機密情報を安全に管理できます:

cat database.json | mcps --enable github | op inject > claude_desktop_config.json

database.jsonの例:

{
  "mcpServers": {
    "github": {
      "command": "/path/to/github-mcp-server",
      "args": ["stdio"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "op://Private/GITHUB/credential"
      }
    },
    "filesystem": {
      "command": "/path/to/fs-mcp-server",
      "args": ["stdio"]
    }
  }
}

このコマンドの流れ:

  1. mcpsがgithubサーバーのみを選択
  2. op injectop://Private/GITHUB/credentialを実際のトークンに置換
  3. 最終的な設定がclaude_desktop_config.jsonに出力される

これにより、機密情報をGitリポジトリにコミットすることなく、安全に設定を管理できます。

プロジェクト固有の設定を作る

# マスター設定からプロジェクト用の設定を生成
cat ~/.config/mcp/all-servers.json | mcps > .mcp-config.json

Makefileでの利用

.mcp-config.json: ~/.config/mcp/all-servers.json
	cat $< | mcps --enable github,filesystem,database > $@

シェルスクリプトでの条件分岐

#!/bin/bash
if [ "$1" = "dev" ]; then
    SERVERS="github,filesystem,sqlite"
else
    SERVERS="github,postgres"
fi

cat ~/.config/mcp/all-servers.json | mcps --enable "$SERVERS" > config.json

まとめ

mcpsは、Unixの哲学に基づいたシンプルなツールです。標準入出力を使うことで、他のツールと組み合わせやすく、様々な場面で活用できます。

MCPを使っている方は、ぜひ試してみてください。

リンク

Discussion