SuperAPI AI Directory

ariadne

Affected-test selection for Kotlin/Android projects: finds the unit tests impacted by working-tree changes via function-level static analysis.

Open website

About this tool

Purpose

ariadne is an MCP (Model Context Protocol) server designed to provide AI agents with the ability to identify affected tests. Powered by sazanami, it analyzes code changes and returns only the tests that need to be run, thereby helping agents get fast feedback in the inner loop of editing, verifying, and committing.

Main Capabilities

  • Affected Test Selection: Based on function-level static analysis, identifies the unit tests affected by workspace changes.
  • MCP Integration: Can be used with Claude Code, Claude Desktop, and other MCP-compatible clients.
  • Automatic Git Diff: No need to manually pass a diff; ariadne runs git diff internally.
  • Powered by sazanami: Uses the Kotlin Analysis API for accurate static analysis.
  • Tool Interface: Provides the get_affected_tests tool, which accepts parameters such as the project path, scope (deep/shallow), and base branch.
  • Clearly Indicates Cases That Cannot Be Analyzed: When changes that cannot be analyzed are detected (build scripts, resources, unscanned source sets), this is clearly stated in the tool response instead of silently reporting "no affected tests."

Usage

Installation

  • Homebrew (recommended): After installing via Homebrew, register it in the MCP client.
  • Docker: Mount the project to be analyzed and pass /workspace as project_path . The image is listed in the official MCP Registry under the identifier io.github.MikhailHal/ariadne.
  • Manual (release JAR): Download ariadne-<version>-all.jarfrom Releases (requires JDK 21+), and configure "command": "java", "args": ["-jar", "/path/to/ariadne-<version>-all.jar"]in the client.
  • Build from source: You can build it yourself.

Usage After Configuration

AI agents can use the get_affected_tests tool:

  • project_path(required) — Kotlin project path.
  • scope(optional,deep | shallow, default deep) — Lookback scope:
    • deep — All changes since base_branch (committed and uncommitted). Safest, covers the entire branch, but may select more tests.
    • shallow — Only uncommitted changes (compared with HEAD). Fastest, suitable for tight edit loops. Verifying committed work is the caller's responsibility.base_branch is ignored.
  • base_branch(optional, deep scope only) — The branch to compare against. When omitted, ariadne uses the repository's default branch (origin/HEAD). If it is not set (for example, in a repository with no remote), an error is returned requiring base_branchto be passed explicitly, rather than guessing.

Workflow

  1. The agent calls the tool — passing the project path to ariadne.
  2. Run git diff — ariadne executes git diff --unified=0.
  3. Analyze using sazanami — build a call graph and find affected tests.
  4. Return results — return the list of test FQNs (fully qualified names) to the agent.

Output

  • A sorted list of affected test FQNs.
  • If the diff contains changes outside the analysis scope (build scripts, resources, unscanned source sets), a note is appended recommending that the full test suite be run for these changes.
  • Analysis is subject to a 120-second timeout; on timeout, a clear error is returned.

When to use

  • The agent's inner loop for Kotlin/Android projects (edit, verify, commit), where fast feedback is needed.
  • To narrow down the tests the agent needs to run before CI.
  • Integration with MCP clients such as Claude Code and Claude Desktop.

Limitations

  • Speed takes priority over completeness: static analysis cannot trace all execution paths; reflection, dependency injection frameworks, and indirect data flow (such as Flux/MVI dispatch) may hide dependencies.
  • The CI line of defense must be kept: run the full test suite (or a conservative selection) before merging. ariadne only narrows the tests run during agent iteration; it cannot replace CI.
  • Cases that cannot be analyzed: changes to build scripts, resources, unscanned source sets, etc. are explicitly flagged.
  • Static analysis blind spots: if a framework calls your code rather than a test calling it, ariadne cannot connect them. These are limitations of static analysis, not bugs.
  • Module discovery is convention-based: it parses settings.gradle(.kts) includes, enumerates src/<sourceSet>/{kotlin,java} layouts, and reads project(":x") / type-safe accessor dependencies. Dynamic includes,projectDir remapping, custom srcDirs, and dependencies injected by convention plugins cannot be detected.
  • The graph is fully rebuilt on every request (no caching yet); analysis is capped at 120 seconds.
  • Environment requirements: JDK 21 or higher; Git (for diff detection).

Real-world validation

Measured against Now in Android (Google's reference Android app — 34 modules, about 268 Kotlin files). Validated patterns include repositories behind project interfaces, library interface overrides (androidx.datastore.Serializer)、operator fun invoke use cases,@Composable functions, extension mappers, ViewModel property initialization chains, and callable references. Two representative results:

  • Changing core:common in asResult() selected 14 tests across three modules, including a ViewModel test reachable only through val uiState = ...stateIn(...) .
  • Changing the mapper PopulatedNewsResource.asExternalModel() selected 14 tests, including 11 repository tests reachable only through the .map(Type::mapper) chain.

Test class selection rate: measured for every unit test class in Now in Android by changing a function in the class under test and checking whether that test class was selected. Robolectric is not an obstacle: these tests call the composable themselves (setContent { NiaTheme { ... } }), so the calls exist in the source code. What determines coverage is not the test runner, but whether the test's own code contains the call.

License

See LICENSE for the full text.