mcpField
D
Drone CI/CD MCP Server

Drone CI/CD MCP Server

ローカル
github.com/yusiwenクラウド・インフラ16 週間前に更新

Drone CI/CD MCP Server について

Drone CI/CD MCP Serverは、Drone CI/CDインスタンスのリポジトリやビルドなどを照会するMCPインターフェースです。既定では読み取り専用ツールのみを有効にし、書き込みや破壊的操作は明示的な有効化を必要とします。認証付きStreamable HTTPにも対応します。

主な機能

  1. 01リポジトリ・ビルド・cronジョブ用ツール
  2. 02既定で読み取り専用ツールを登録
  3. 03書き込み・破壊的操作は明示的に有効化
  4. 04Bearer認証付きStreamable HTTP
  5. 05入力検証とビルド詳細リソース

活用シーン

  1. 01リポジトリのビルド状況やログの確認
  2. 02Droneのリポジトリやcronジョブの調査
  3. 03書き込みツールを有効にしてビルドやシークレットを管理

MCP 対応

Droneのリポジトリ、ビルド、cronジョブ、シークレット、ユーザー、テンプレート用ツールと、ビルド詳細のリソースをMCPクライアントに提供します。stdioと、HTTPモードではBearer認証が必須のStreamable HTTPに対応します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"yusiwen-drone": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/yusiwen/drone-mcp-server:2.0.0"
]
}
}
}
起動コマンドdocker run -i --rm ghcr.io/yusiwen/drone-mcp-server:2.0.0

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
ocighcr.io/yusiwen/drone-mcp-server:2.0.0

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

Drone MCP Server

Drone CI/CD とやり取りするための Model Context Protocol(MCP)サーバーです。このサーバーは、Drone インスタンスからビルド情報やリポジトリなどを照会するためのツールとリソースを提供します。

機能

  • 45 個のツールで、リポジトリ、ビルド、cron ジョブ、シークレット、ユーザー、テンプレートをカバーします
  • デフォルトでは読み取り専用:書き込みおよび破壊的な 27 個のツールは、--enable-write-tools を指定した場合にのみ登録されます
  • ストリーミング可能な HTTP トランスポートを使用し、必須のベアラー認証、DNS リバインディング保護、クロスオリジン保護を備えています
  • 入力を検証:リポジトリ識別子、名前、ブランチ、ビルド番号が Drone API に渡される前にチェックされます
  • リソースアクセス:drone://builds/{owner}/{repo}/{build} でビルドの詳細を取得できます

インストール

go mod tidy
go build -o drone-mcp-server .

設定

環境変数
変数必須説明
DRONE_SERVERはいDrone インスタンスのベース URL。例:https://drone.example.com
DRONE_TOKENはいDrone の個人用アクセストークン。すべての Drone API 呼び出しで Authorization: Bearer <token> として送信されます
MCP_AUTH_TOKENHTTP モードクライアントが提示する必要のあるベアラートークン。HTTP モードでは、このトークンがないと起動できません
MCP_AUTH_TOKEN_FILEいいえベアラートークンを格納したファイル(Docker/Kubernetes シークレット)。MCP_AUTH_TOKEN より優先されます
MCP_ENABLE_WRITE_TOOLSいいえtrue にすると、書き込みおよび破壊的なツールが登録されます。--enable-write-tools と同等です
export DRONE_SERVER=https://drone.example.com
export DRONE_TOKEN=your_drone_token
export MCP_AUTH_TOKEN="$(openssl rand -base64 32)"   # HTTP mode only

公開するツールをカバーする最小限の Drone 権限セットを付与してください。読み取り専用のツールセットには、リポジトリとビルドへの読み取りアクセスのみが必要ですが、delete_user、create_org_secret、chown_repo などの書き込みツールには管理者権限が必要です。

セキュリティ

このサーバーは特権プロキシです。サーバーがアクセスできるものには、サーバーと通信できる人なら誰でもアクセスできます。デフォルト設定はこの点を踏まえています。

  • HTTP モードはフェイルクローズです。 MCP_AUTH_TOKEN(または MCP_AUTH_TOKEN_FILE)がない場合、サーバーは HTTP モードでの起動を拒否します。--insecure-allow-anonymous を指定するとこの動作を上書きし、警告をログに記録します。
  • デフォルトでは読み取り専用です。 書き込みアクセスが明示的に要求されない限り、読み取り専用の 18 個のツールのみが登録されます。すべてのツールには、クライアントが書き込みを制御できるように、MCP ヒント readOnlyHint、destructiveHint、idempotentHint が付与されています。
  • ストリーミング可能な HTTP トランスポートです。 従来の SSE トランスポートは MCP 仕様から削除され、DNS リバインディング保護やクロスオリジン保護なしで提供されていました。このサーバーでは Go SDK の StreamableHTTPHandler を使用しており、ループバックアドレスへのリクエストで Host ヘッダーがループバック以外を示すものを拒否し、クロスサイトのブラウザーリクエストも拒否します。
  • 許可リストは任意です。 --allowed-hosts と --allowed-origins を使用すると、トランスポートのデフォルトに加えて、明示的な Host および Origin の許可リストを設定できます。
  • ベアラートークンの取り扱い。 トークンは SHA-256 ダイジェストを用いて定数時間で比較され、1 つのアドレスからの繰り返しの認証失敗は制限されます(1 分あたり 10 回を超えると 429)。
  • 入力の検証。 リポジトリ識別子、シークレット名とテンプレート名、ブランチ、ビルド番号は Drone API クライアントに渡される前に検証されます。drone-go は文字列フォーマットでリクエストパスを組み立てるためです。
  • ログの安全性。 --trust-proxy が設定されていない限り、X-Forwarded-For / X-Real-IP は無視されます。また、ログに記録される値から制御文字が取り除かれるため、リクエストデータでログ行を偽造できません。
  • リクエストの制限。 リクエスト本文のサイズには上限があり(デフォルトは 1 MiB)、アイドル状態のセッションは期限切れになります。また、ヘッダー読み取りタイムアウトと無通信接続タイムアウトにより、低速クライアントによる悪用を抑制します。
デプロイのチェックリスト
  1. サーバーの前段で TLS を終端してください(バイナリは平文の HTTP を使用します)。信頼できないネットワーク経由でベアラートークンを送信しないでください。
  2. デフォルトのループバックバインドを維持してリバースプロキシを前段に配置するか、MCP クライアントだけがアクセスできるインターフェースにバインドしてください。
  3. エントロピーの高い MCP_AUTH_TOKEN(ランダムな 32 バイト以上)を生成し、コマンドラインではなくプラットフォームのシークレットとして注入してください。
  4. ワークフローで必要な場合を除き、書き込みツールは無効のままにしてください。
  5. --trust-proxy は、管理下のプロキシが X-Forwarded-For / X-Real-IP を書き換える場合にのみ設定してください。そうでない場合、ログに記録されるクライアントアドレスは攻撃者が制御できます。
  6. サーバーを localhost の外部に公開する前に、SECURITY.md をお読みください。

使用方法

MCP サーバーとして

MCP クライアントの設定(例:Claude Desktop)にサーバーを追加します。

{
  "mcpServers": {
    "drone": {
      "command": "/path/to/drone-mcp-server",
      "env": {
        "DRONE_SERVER": "https://drone.example.com",
        "DRONE_TOKEN": "your_token"
      }
    }
  }
}
直接実行

テスト目的でサーバーを直接実行できます。

# Stdio mode (default) - for local MCP clients
./drone-mcp-server

# Streamable HTTP mode - requires MCP_AUTH_TOKEN
export MCP_AUTH_TOKEN="$(openssl rand -base64 32)"
./drone-mcp-server --http --host localhost --port 8080
トランスポートモード
  1. Stdio モード(デフォルト):MCP プロトコルを使用して stdin/stdout 経由で通信します。MCP クライアントとのローカル統合に適しており、ネットワークへの公開や認証は必要ありません。

  2. Streamable HTTP モード(--http):POST(クライアントからサーバー)、GET(サーバーからクライアントへのストリーム)、DELETE(セッションの終了)を受け付ける単一のエンドポイントです。

    以前のリリースからのアップグレード: 古い --sse フラグと SSE トランスポートは廃止されました。--http と Streamable HTTP に対応したクライアントを使用してください。

    # Local only, read-only tools
    MCP_AUTH_TOKEN=... ./drone-mcp-server --http
    
    # Behind a TLS terminating proxy, write tools enabled
    MCP_AUTH_TOKEN=... ./drone-mcp-server --http --host 127.0.0.1 --port 8080 \
        --enable-write-tools --allowed-hosts mcp.example.com
    

    クライアントはデフォルトで http://localhost:8080/ に接続し、次のヘッダーを送信する必要があります。

    Authorization: Bearer <MCP_AUTH_TOKEN>
    

    リバースプロキシの背後で使用する場合:トランスポートは DNS リバインディング対策の一環として、ループバック接続でパブリックな Host ヘッダーを拒否し、403 を返します。ループバックの Host ヘッダーを維持する(proxy_set_header Host 127.0.0.1:8080;)か、単一のフラグを使って許可リストに Host の検証を委ねてください。

    ./drone-mcp-server --http --allowed-hosts mcp.example.com
    

    --allowed-hosts を設定するとループバックの判定方式が置き換わるため、--localhost-protection=false は不要です。--localhost-protection=true を明示的に指定すると、両方のチェックが適用され、パブリックな Host は再び拒否されます。

コマンドラインフラグ
フラグデフォルト説明
--httpfalseStreamable HTTP トランスポートを使用します
--host / --portlocalhost / 8080リッスンするアドレス(HTTP モードのみ)
--path/MCP エンドポイントのパス(HTTP モードのみ)
--enable-write-toolsfalse27 個の書き込みおよび破壊的なツールを登録します
--insecure-allow-anonymousfalseMCP_AUTH_TOKEN なしで HTTP モードを許可します
--trust-proxyfalseリバースプロキシからの X-Forwarded-For / X-Real-IP を信頼します
--allowed-hosts(空)カンマ区切りの Host 許可リスト。ループバックの判定方式を置き換えます
--allowed-origins(空)カンマ区切りのブラウザー Origin 許可リスト
--localhost-protectiontrueループバック接続にループバック以外の Host ヘッダーが含まれる場合に拒否します。両方のチェックを適用するには、--allowed-hosts と併せて明示的に設定します
--session-timeout30mMCP セッションのアイドルタイムアウト(HTTP モードのみ)
--max-request-bytes1048576MCP リクエスト本文の最大サイズ
--versionバージョン情報を表示して終了します

利用可能なツール

サーバーは45個のツールを実装しています。デフォルトの読み取り専用モードでは、読み取り専用ツール18個のみが登録されます。残りの27個は書き込みまたは破壊的なツールであり、--enable-write-tools(またはMCP_ENABLE_WRITE_TOOLS=true)が必要です。

書き込みおよび破壊的なツール: enable_repo、disable_repo、repair_repo、chown_repo、sync_repos、create_cron、delete_cron、execute_cron、create_secret、update_secret、delete_secret、create_org_secret、update_org_secret、delete_org_secret、create_user、update_user、delete_user、create_template、update_template、delete_template、restart_build、cancel_build、promote_build、rollback_build、approve_build、decline_build、create_build。

破壊的なツール(削除、無効化、キャンセル、昇格、ロールバック、所有権の変更)にはdestructiveHint: trueが設定されています。それ以外の書き込みツールにはdestructiveHint: falseが設定されています。読み取り専用ツール18個すべてにはreadOnlyHint: trueが設定されています。

リポジトリ管理
list_repos

Drone インスタンス内のすべてのリポジトリを一覧表示します。

get_repo

リポジトリの詳細を取得します。

引数:

  • owner(string):リポジトリの所有者
  • repo(string):リポジトリ名
enable_repo

リポジトリを有効にします。

引数:

  • owner(string):リポジトリの所有者
  • repo(string):リポジトリ名
disable_repo

リポジトリを無効にします。

引数:

  • owner(string):リポジトリの所有者
  • repo(string):リポジトリ名
repair_repo

リポジトリを修復します。

引数:

  • owner(string):リポジトリの所有者
  • repo(string):リポジトリ名
chown_repo

リポジトリの所有権を変更します。

引数:

  • owner(string):リポジトリの所有者
  • repo(string):リポジトリ名
sync_repos

リポジトリ一覧を同期します。

list_incomplete

ビルドが未完了のリポジトリを一覧表示します。

ビルド管理
list_builds

特定のリポジトリのビルドを一覧表示します。

引数:

  • owner(string):リポジトリの所有者
  • repo(string):リポジトリ名
get_build

特定のビルドの詳細情報を取得します。

引数:

  • owner(string):リポジトリの所有者
  • repo(string):リポジトリ名
  • build(number):ビルド番号
get_build_last

リポジトリの最新ビルドを取得します(ブランチを指定することもできます)。

引数:

  • owner(string):リポジトリの所有者
  • repo(string):リポジトリ名
  • branch(string、任意):ブランチ名
get_build_logs

特定のビルドのステージとステップのログを取得します。

引数:

  • owner(string):リポジトリの所有者
  • repo(string):リポジトリ名
  • build(number):ビルド番号
  • stage(number):ステージ番号
  • step(number):ステップ番号
restart_build

ビルドを再起動します(パラメーターを指定することもできます)。

引数:

  • owner(string):リポジトリの所有者
  • repo(string):リポジトリ名
  • build(number):ビルド番号
  • params(object、任意):ビルドパラメーター
cancel_build

実行中のビルドをキャンセルします。

引数:

  • owner(string):リポジトリの所有者
  • repo(string):リポジトリ名
  • build(number):ビルド番号
promote_build

ビルドを対象環境に昇格します。

引数:

  • owner(string):リポジトリの所有者
  • repo(string):リポジトリ名
  • build(number):ビルド番号
  • target(string):対象環境
  • params(object、任意):昇格パラメーター
rollback_build

デプロイを以前のビルドにロールバックします。

引数:

  • owner(string):リポジトリの所有者
  • repo(string):リポジトリ名
  • build(number):ビルド番号
  • target(string):対象環境
  • params(object、任意):ロールバックパラメーター
approve_build

ビルドのステージを承認します(承認ゲート付きデプロイ用)。

引数:

  • owner(string):リポジトリの所有者
  • repo(string):リポジトリ名
  • build(number):ビルド番号
  • stage(number):ステージ番号
decline_build

(ゲート付きデプロイメント用に)ビルドステージを却下します。

引数:

  • owner (string):リポジトリのオーナー
  • repo (string):リポジトリ名
  • build (number):ビルド番号
  • stage (number):ステージ番号
create_build

コミットまたはブランチから新しいビルドを作成します。

引数:

  • owner (string):リポジトリのオーナー
  • repo (string):リポジトリ名
  • commit (string, optional):コミット SHA
  • branch (string, optional):ブランチ名
  • params (object, optional):ビルドパラメーター
Cron ジョブの管理
list_crons

リポジトリの Cron ジョブを一覧表示します。

引数:

  • owner (string):リポジトリのオーナー
  • repo (string):リポジトリ名
get_cron

Cron ジョブの詳細を取得します。

引数:

  • owner (string):リポジトリのオーナー
  • repo (string):リポジトリ名
  • cron (string):Cron ジョブ名
create_cron

新しい Cron ジョブを作成します。

引数:

  • owner (string):リポジトリのオーナー
  • repo (string):リポジトリ名
  • name (string):Cron ジョブ名
  • expr (string):Cron 式
  • branch (string):ブランチ名
  • disable (boolean, optional):Cron ジョブを無効にするかどうか
delete_cron

Cron ジョブを削除します。

引数:

  • owner (string):リポジトリのオーナー
  • repo (string):リポジトリ名
  • cron (string):Cron ジョブ名
execute_cron

Cron ジョブを直ちに実行します。

引数:

  • owner (string):リポジトリのオーナー
  • repo (string):リポジトリ名
  • cron (string):Cron ジョブ名
シークレットの管理
list_secrets

リポジトリのシークレットを一覧表示します。

引数:

  • owner (string):リポジトリのオーナー
  • repo (string):リポジトリ名
get_secret

リポジトリのシークレットの詳細を取得します。

引数:

  • owner (string):リポジトリのオーナー
  • repo (string):リポジトリ名
  • name (string):シークレット名
create_secret

リポジトリのシークレットを作成します。

引数:

  • owner (string):リポジトリのオーナー
  • repo (string):リポジトリ名
  • name (string):シークレット名
  • value (string):シークレット値
  • pull_request (boolean, optional):プルリクエストでの使用を許可するかどうか
  • pull_request_push (boolean, optional):プルリクエストのプッシュイベントでの使用を許可するかどうか
update_secret

リポジトリのシークレットを更新します。

引数:

  • owner (string):リポジトリのオーナー
  • repo (string):リポジトリ名
  • name (string):シークレット名
  • value (string):シークレット値
  • pull_request (boolean, optional):プルリクエストでの使用を許可するかどうか
  • pull_request_push (boolean, optional):プルリクエストのプッシュイベントでの使用を許可するかどうか
delete_secret

リポジトリのシークレットを削除します。

引数:

  • owner (string):リポジトリのオーナー
  • repo (string):リポジトリ名
  • name (string):シークレット名
Organization Secrets
list_org_secrets

組織のシークレットを一覧表示します。

引数:

  • namespace (string):組織の名前空間
get_org_secret

組織のシークレットの詳細を取得します。

引数:

  • namespace (string):組織の名前空間
  • name (string):シークレット名
create_org_secret

組織のシークレットを作成します。

引数:

  • namespace (string):組織の名前空間
  • name (string):シークレット名
  • value (string):シークレット値
  • pull_request (boolean, optional):プルリクエストでの使用を許可するかどうか
  • pull_request_push (boolean, optional):プルリクエストのプッシュイベントでの使用を許可するかどうか
update_org_secret

組織のシークレットを更新します。

引数:

  • namespace (string):組織の名前空間
  • name (string):シークレット名
  • value (string):シークレット値
  • pull_request (boolean, optional):プルリクエストでの使用を許可するかどうか
  • pull_request_push (boolean, optional):プルリクエストのプッシュイベントでの使用を許可するかどうか
delete_org_secret

組織のシークレットを削除します。

引数:

  • namespace (string):組織の名前空間
  • name (string):シークレット名
ユーザー管理
get_self

現在認証されているユーザーを取得します。

list_users

すべてのユーザーを一覧表示します。

get_user

ユーザーの詳細を取得します。

引数:

  • login (string):ユーザーのログイン名
create_user

新しいユーザーを作成します。

引数:

  • login(string):ユーザーのログイン名
  • email(string、任意):ユーザーのメールアドレス
  • admin(boolean、任意):管理者権限
  • active(boolean、任意):有効状態
  • token(string、任意):ユーザートークン
update_user

ユーザーを更新します。

引数:

  • login(string):ユーザーのログイン名
  • admin(boolean、任意):管理者権限
  • active(boolean、任意):有効状態
delete_user

ユーザーを削除します。

引数:

  • login(string):ユーザーのログイン名
テンプレート管理
list_templates

テンプレートを一覧表示します(任意で名前空間を指定できます)。

引数:

  • namespace(string、任意):テンプレートの名前空間
get_template

テンプレートの詳細とデータを取得します。

引数:

  • namespace(string):テンプレートの名前空間
  • name(string):テンプレート名
create_template

新しいテンプレートを作成します。

引数:

  • namespace(string):テンプレートの名前空間
  • name(string):テンプレート名
  • data(string):テンプレートデータ(YAML)
update_template

テンプレートを更新します。

引数:

  • namespace(string):テンプレートの名前空間
  • name(string):テンプレート名
  • data(string):テンプレートデータ(YAML)
delete_template

テンプレートを削除します。

引数:

  • namespace(string):テンプレートの名前空間
  • name(string):テンプレート名

リソース

ビルド詳細リソース

リソース URI drone://builds/{owner}/{repo}/{build} からビルドの詳細にアクセスします。

例:

Read resource: drone://builds/owner1/repo1/123

Docker

マルチアーキテクチャ対応の Docker イメージを GitHub Container Registry で利用できます。

# Pull the latest image
docker pull ghcr.io/yusiwen/drone-mcp-server:latest

# Run in stdio mode (for local MCP clients)
docker run --rm -i \
           -e DRONE_SERVER=https://drone.example.com \
           -e DRONE_TOKEN=your_token \
           ghcr.io/yusiwen/drone-mcp-server

# Run in Streamable HTTP mode: read-only, authenticated, published on loopback
docker run --rm \
           -e DRONE_SERVER=https://drone.example.com \
           -e DRONE_TOKEN=your_token \
           -e MCP_AUTH_TOKEN=your_mcp_token \
           -p 127.0.0.1:8080:8080 \
           ghcr.io/yusiwen/drone-mcp-server --http --host 0.0.0.0

# Add --enable-write-tools when the workflow must mutate Drone
docker run --rm \
           -e DRONE_SERVER=https://drone.example.com \
           -e DRONE_TOKEN=your_token \
           -e MCP_AUTH_TOKEN=your_mcp_token \
           -p 127.0.0.1:8080:8080 \
           ghcr.io/yusiwen/drone-mcp-server --http --host 0.0.0.0 --enable-write-tools

コンテナ内で公開ポートを機能させるには、--host 0.0.0.0 が必要です。そのため、ベアラートークンも必須です。前段に TLS 終端プロキシがない場合は、ポートを 127.0.0.1 で公開してください。

環境変数よりも、マウントしたシークレットを使用してください。

docker run --rm \
           -v /run/secrets/mcp_token:/run/secrets/mcp_token:ro \
           -e MCP_AUTH_TOKEN_FILE=/run/secrets/mcp_token \
           -e DRONE_SERVER=https://drone.example.com \
           -e DRONE_TOKEN=your_token \
           -p 127.0.0.1:8080:8080 \
           ghcr.io/yusiwen/drone-mcp-server --http --host 0.0.0.0
Docker Compose の例
services:
  drone-mcp-server:
    image: ghcr.io/yusiwen/drone-mcp-server:latest
    environment:
      DRONE_SERVER: https://drone.example.com
      DRONE_TOKEN: ${DRONE_TOKEN:?DRONE_TOKEN is required}
      MCP_AUTH_TOKEN: ${MCP_AUTH_TOKEN:?MCP_AUTH_TOKEN is required}
      # MCP_ENABLE_WRITE_TOOLS: "true"   # only when the workflow needs writes
    ports:
      - "127.0.0.1:8080:8080"
    command: ["--http", "--host", "0.0.0.0"]
    restart: unless-stopped
    read_only: true
    security_opt:
      - no-new-privileges:true

リリース

Linux(x64、arm64)、macOS(x64、arm64)、Windows(x64)向けのビルド済みバイナリをGitHub リリースから入手できます。

バージョン情報

バイナリにはバージョン情報が含まれています。

./drone-mcp-server --version

出力例:

drone-mcp-server
Version: v1.0.0
Commit: abc123
Build date: 2024-01-01T00:00:00Z
Go version: go1.25.1

プロジェクト構成

.
├── main.go              # Entry point: CLI flags, transports, auth, HTTP hardening, tool registration
├── main_test.go         # Auth middleware, allowlists, log hygiene and tool registration tests
├── tool/                # Tool handlers module
│   ├── build.go         # Build-related tools (list_builds, get_build, restart_build, etc.)
│   ├── repo.go          # Repository-related tools (list_repos, enable_repo, disable_repo, etc.)
│   ├── resource.go      # Resource handling (drone://builds/...)
│   ├── cron.go          # Cron job management tools
│   ├── secret.go        # Secret management tools
│   ├── user.go          # User management tools
│   ├── template.go      # Template management tools
│   ├── validate.go      # Input validation helpers used by every tool
│   ├── validate_args.go # Validate implementation for each tool argument struct
│   └── validate_test.go # Validation tests, including injection attempts
├── SECURITY.md          # Threat model, deployment guidance and reporting process
├── server.json          # MCP registry metadata
├── test_env.sh          # Manual smoke test script (uses environment variables)
├── test_mcp.go          # In-memory MCP integration test (build tag: test)
└── README.md

開発

依存関係
  • Go 1.25.14+(ツールチェーンは go.mod で固定されています。これより前の Go 1.25 パッチリリースには標準ライブラリの脆弱性があり、govulncheck のゲートで失敗します)
  • github.com/modelcontextprotocol/go-sdk - MCP SDK(ストリーミング可能な HTTP トランスポート)
  • github.com/drone/drone-go - Drone API クライアント
ビルド
make build           # build with version info injected through ldflags
go build -o drone-mcp-server .
テスト
make test                                  # unit tests
make test-race                             # with the race detector
make smoke                                 # end-to-end security smoke test
make vuln                                  # govulncheck (module + standard library)
go vet ./...

ユニットテストでは、認証ミドルウェア(定数時間比較と失敗時のスロットリングを含む)、Host ポリシー、ログのサニタイズ、クライアントアドレスの処理、入力の検証、読み取り専用ツールの登録を網羅しています。Drone インスタンスは必要ありません。

セキュリティ強化の検証

scripts/security-smoke-test.sh はループバックポートで実際のバイナリを起動し、Drone インスタンスに接続することなく、重要な動作を検証します。

./scripts/security-smoke-test.sh          # builds the binary first
BIN=./drone-mcp-server ./scripts/security-smoke-test.sh

HTTP モードでトークンなしの起動が拒否されること、認証情報の欠落や誤り、不正な Content-Type、サイズ超過のリクエストボディ、偽装された Host ヘッダー、クロスサイトの Origin がそれぞれ 401/401/415/413/403/403 で拒否されること、デフォルトのツール一覧が読み取り専用ツール18個だけであり、非表示の書き込みツールを呼び出せないこと、ツール引数のパストラバーサルが拒否されること、ログインジェクションと X-Forwarded-For の偽装が無効化されること、--allowed-hosts によってループバックの推定ロジックが置き換えられること、書き込みツールが --enable-write-tools を指定した場合にのみ表示されること、--sse が削除されていること、SIGTERM によってサーバーがシャットダウンすることを確認します。最初の失敗セットでゼロ以外の終了コードを返し、CI でも実行されるため、リグレッションを防ぐゲートとしても機能します。

実際の Drone に対する手動検証

まず読み取り専用トークンを使い、ツールが応答することを確認します。

export DRONE_SERVER=https://ci.example.com
export DRONE_TOKEN=<read-only token>
export MCP_AUTH_TOKEN="$(openssl rand -base64 32)"
./drone-mcp-server --http --host 127.0.0.1 --port 8080

次に、MCP クライアントから接続します。Stdio モード:

{
  "mcpServers": {
    "drone": {
      "command": "/path/to/drone-mcp-server",
      "env": { "DRONE_SERVER": "https://ci.example.com", "DRONE_TOKEN": "..." }
    }
  }
}

Streamable HTTP モード(ほとんどのクライアントでは headers ブロックを使用できます。npx @modelcontextprotocol/inspector も使えます。「Streamable HTTP」を選択し、同じヘッダーを追加してください):

{
  "mcpServers": {
    "drone": {
      "url": "http://127.0.0.1:8080/",
      "headers": { "Authorization": "Bearer <MCP_AUTH_TOKEN>" }
    }
  }
}

実際のインスタンスでの確認項目:get_self(トークンが機能することを確認)、list_repos、get_build_last、get_build_logs(モデルコンテキスト内の信頼できないコンテンツを検証)、続いて owner: "../users" を指定した get_repo(検証によって拒否されることを確認)。書き込みツールは使い捨てのリポジトリに対してのみ実行してください。

ローカルでの実行
export DRONE_SERVER=https://drone.example.com
export DRONE_TOKEN=...

# Read-only stdio server
./drone-mcp-server

# HTTP mode with authentication and write tools
MCP_AUTH_TOKEN=dev-token ./drone-mcp-server --http --enable-write-tools

ライセンス

MIT

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。