ariadne について
ariadneはKotlinプロジェクト向けのMCPサーバーで、Gitの変更を分析して実行対象のユニットテストを特定します。コーディングエージェントの編集・検証を短縮しつつ、分析対象外の変更も明示します。
主な機能
- 01Kotlinの変更に影響されるテストを選択
- 02Git差分を自動取得
- 03deepとshallowの変更範囲に対応
- 04テストの完全修飾名をソートして返却
- 05分析対象外の変更を通知
活用シーン
- 01Kotlinの編集時に対象を絞ってユニットテストを実行
- 02コミット前にブランチの変更を確認
- 03全テスト実行が必要か判断
MCP 対応
MCPクライアントに`get_affected_tests`ツールを提供します。Kotlinプロジェクトのパスを受け取り、検出したGitの変更に基づいて影響を受けるテストを返します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm ghcr.io/mikhailhal/ariadne:0.4.0ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ghcr.io/mikhailhal/ariadne:0.4.0stdioツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
ariadne
影響を受けるテストを選定する MCP サーバー
ariadne は、AI エージェントが影響を受けるテストを特定できるようにする MCP(Model Context Protocol)サーバーです。sazanami を利用し、コードの変更を分析して、実行が必要なテストのみを返します。
重要
⚠️ 必読:網羅性より速度を優先
ariadne は、編集、検証、コミットを行うエージェントの内部ループ向けに構築されています。ここでは、網羅的な選定よりも素早いフィードバックが重要です。静的解析では、すべての実行パスを追跡できるわけではありません。リフレクション、DI フレームワーク、データフローの間接化(例:Flux/MVI のディスパッチ)により、ariadne だけでなく、あらゆる影響テスト選定ツールから依存関係が見えなくなることがあります。
CI では必ず最終防衛線を設けてください。 マージ前に、テストスイート全体(または保守的な選定)を実行してください。ariadne は、エージェントが反復作業を行う際に実行するテストの範囲を絞り込むものであり、CI の代替ではありません。
ariadne が、ビルドスクリプト、リソース、スキャンされていないソースセットなど、分析できない変更を検出した場合、「影響を受けるテストはありません」と黙って報告するのではなく、ツールの応答で明示的に知らせます。
機能
- MCP 統合 — Claude Code、Claude Desktop、その他の MCP 対応クライアントで動作します
- Git 差分の自動取得 — 差分を手動で渡す必要はありません。ariadne が内部で
git diffを実行します - sazanami を利用 — Kotlin Analysis API を使用した正確な静的解析を行います
インストール
Homebrew(推奨)
brew install mikhailhal/tap/ariadne
その後、MCP クライアントに登録します。Claude Code の場合:
claude mcp add ariadne -- ariadne
または、MCP クライアントの設定に手動で追加します(例:Claude Desktop)。
{
"mcpServers": {
"ariadne": {
"command": "ariadne"
}
}
}
Docker
docker run -i --rm -v /path/to/project:/workspace ghcr.io/mikhailhal/ariadne
分析するプロジェクトをマウントし、project_path に /workspace を指定してください。
このイメージは、公式 MCP Registry に io.github.MikhailHal/ariadne としても掲載されています。
手動(リリース JAR)
Releases から ariadne-<version>-all.jar をダウンロードし(JDK 21 以降が必要)、"command": "java", "args": ["-jar", "/path/to/ariadne-<version>-all.jar"] を使用してクライアントを設定してください。
ソースからビルド
git clone --recursive https://github.com/MikhailHal/ariadne.git
cd ariadne
./gradlew shadowJar # fat JAR: build/libs/ariadne-<version>-all.jar
使い方
設定が完了すると、AI エージェントは get_affected_tests ツールを使用できます。
ツール:get_affected_tests
パラメーター:
project_path(必須)— Kotlin プロジェクトへのパスscope(任意、deep|shallow、デフォルトはdeep)— どこまでさかのぼって確認するか:deep—base_branch以降のすべての変更(コミット済み および 未コミット)。最も安全です。ブランチ全体が対象となるため、コミット済みの変更が検証されないまま残ることはありません。より多くのテストが選択される場合があります。shallow— 未コミットの変更のみ(HEADとの差分)。短い編集サイクル向けで、最速です。コミット済みの作業の検証は呼び出し元に委ねられます。base_branchは無視されます。
base_branch(任意、deepスコープのみ)— 比較対象のブランチ。省略した場合、ariadne はリポジトリのデフォルトブランチ(origin/HEAD)を使用します。これが設定されていない場合(リモートのないリポジトリなど)、推測するのではなく、base_branchを明示的に指定するよう求めるエラーを返します。
戻り値:
- 影響を受けるテストの FQN(完全修飾名)のリスト(ソート済み)
- 差分に解析対象の Kotlin ソース以外の変更(ビルドスクリプト、リソース、スキャン対象外のソースセット)が含まれる場合、それらの変更について全テストの実行を推奨する注記が追加されます
- 解析には 120 秒のタイムアウトが設定されており、タイムアウト時には明示的なエラーが返されます
例
エージェントのリクエスト:
{
"name": "get_affected_tests",
"arguments": {
"project_path": "/path/to/your/kotlin/project"
}
}
レスポンス:
com.example.UserServiceTest.testCreateUser
com.example.UserRepositoryTest.testSave
仕組み
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ MCP Client │ ──▶ │ ariadne │ ──▶ │ sazanami │
│ (Agent) │ │ (MCP Server)│ │ (Analysis) │
└─────────────┘ └─────────────┘ └─────────────┘
│
▼
┌─────────────┐
│ git diff │
└─────────────┘
- エージェントがツールを呼び出す — プロジェクトのパスを ariadne に渡します
- git diff を実行 — ariadne がベースブランチとの差分に対して
git diff --unified=0を実行します - sazanami で解析 — 呼び出しグラフを構築し、影響を受けるテストを見つけます
- 結果を返す — テスト FQN のリストがエージェントに返されます
実環境での検証:Now in Android
Now in Android (Google の Android リファレンスアプリ — 34 モジュール、約 268 個の Kotlin ファイル)を対象に測定しました。
| 指標 | 結果 |
|---|---|
| 再現率の監査 — すべてのレイヤーにわたる 19 個の対象関数 | 有効な対象 18/18 個を検出(19 個目には実行するユニットテストがなく、正しく選択されませんでした) |
| エンドツーエンドの応答時間 | 約 4 秒(モジュール検出 + 呼び出しグラフの構築 + BFS) |
| モジュール検出 | settings.gradle.kts による 34 個のモジュール(ネストされたモジュールとタイプセーフなアクセサーの依存関係を含む) |
| ソースセット | モジュールごとに main、debug、prod、benchmark、testDemo、… を検出(設計上 androidTest* は除外) |
検証済みのパターンには、プロジェクトのインターフェースの背後にあるリポジトリ、ライブラリインターフェースのオーバーライド(androidx.datastore.Serializer)、operator fun invoke のユースケース、@Composable 関数、拡張マッパー、ViewModel のプロパティ初期化子の連鎖、呼び出し可能参照が含まれます。代表的な結果を 2 つ紹介します。
core:commonのasResult()を変更すると、3 つのモジュールにまたがる 14 個のテストが選択されます。これには、val uiState = ...stateIn(...)を経由してのみ到達できる ViewModel テストも含まれます- マッパー
PopulatedNewsResource.asExternalModel()を変更すると、14 個のテストが選択されます。これには、.map(Type::mapper)の連鎖を経由してのみ到達できる 11 個のリポジトリテストも含まれます
テストクラスの選択率
Now in Android のすべてのユニットテストクラスについて、そのクラスがテストする関数を変更し、そのテストクラスが選択されるかを確認しました。
| テストスタイル | 選択数 |
|---|---|
| 通常のユニットテスト(オブジェクトを構築して呼び出す) | 有効な対象 13 / 13 個 |
| Robolectric / Compose スクリーンショットテスト | 12 / 12 |
フレームワークがディスパッチするコールバック(lint の Detector) | 0 / 2 — 以下を参照 |
Robolectric は障壁にならないことが分かりました。これらのテストはコンポーザブルを直接呼び出す(setContent { NiaTheme { ... } })ため、その呼び出しがソース内に存在します。カバレッジを決めるのはテストランナーではなく、テスト自体のコードにその呼び出しが含まれているかどうかです。
ariadne が検出できないもの
目安は次のとおりです。テストからコードを呼び出すのではなく、フレームワークがコードを呼び出す場合、ariadne は両者を関連付けられません。 これは静的解析の限界であり、バグではありません。これらを踏まえて、CI の安全策を計画してください。
| パターン | 状態 |
|---|---|
フレームワークから呼び出されるコールバック — Fragment/Activity のライフサイクル(launchFragmentInContainer)、lint の Detector メソッド、Application.onCreate | 追跡されません。テスト内に呼び出しが記述されていないためです |
| リフレクション/DI コンテナーによる配線 | 追跡されません |
| UDF ディスパッチ(Flux/MVI) | dispatch → collect はエッジとして扱われません。ただし、init 内での配線(またはテストから呼び出される start())は、コンストラクターチェーンを通じて保守的に対象となります。DI/ライフサイクルによって開始されるサブスクリプションは対象外です(sazanami#38) |
stateIn/shareIn のチェーン(map、onEach、flatMapLatest、combine) | 対象です — 正確な選択を検証済みです |
インストルメンテーションテスト(androidTest*) | 設計上、対象外です |
| ビルドスクリプト、リソース、スキャン対象外のソースセット | 解析されません — ツールの応答に明示的に報告されます |
| 同じパッケージ内で名前が重複するトップレベル拡張関数 | 過剰に選択されます(レシーバー型はトップレベルの FQN に含まれません)— 安全側の挙動です |
KMP ソースセット(commonMain、expect/actual) | 列挙されますが、解決品質は未検証です(#1) |
監査の詳細は、sazanami#29、 sazanami#38 を参照してください。
要件
- JDK 21 以降
- Git — 差分の検出に使用します
制限事項
- モジュールの検出は規約に基づいています。
settings.gradle(.kts)の include を解析し、src/<sourceSet>/{kotlin,java}のレイアウトを列挙して、ビルドファイルからproject(":x")/型安全アクセサーによる依存関係を読み取ります。動的 include、projectDirの再マッピング、カスタムsrcDirs、規約プラグインによって注入される依存関係は検出されません — #1 を参照してください - リクエストごとにグラフ全体を再構築します(キャッシュはまだありません)。解析時間は 120 秒に制限されています
- 解析レベルの未対応項目については、ariadne が検出できないものを参照してください
ライセンス
Copyright 2025 ariadne contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
全文は LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。