Skip to main content
ClaudeWave

ariadne is an MCP (Model Context Protocol) server that provides AI agents with the ability to identify affected tests.

MCP ServersRegistry oficial1 estrellas0 forksKotlinApache-2.0Actualizado today
Install in Claude Code / Claude Desktop
Method: Docker · /path/to/project
Claude Code CLI
claude mcp add ariadne -- docker run -i --rm /path/to/project
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "ariadne": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "/path/to/project"]
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Casos de uso

Resumen de MCP Servers

<p align="center">
  <img src="doc/ariadne-banner.svg" alt="ariadne banner" width="100%">
</p>

<p align="center">
  <h1 align="center">ariadne</h1>
  <p align="center">
    <strong>MCP Server for Affected Test Selection</strong>
  </p>
  <p align="center">
    <a href="https://github.com/MikhailHal/ariadne/releases"><img src="https://img.shields.io/github/v/release/MikhailHal/ariadne?style=flat-square&color=success" alt="Release"></a>
    <a href="https://registry.modelcontextprotocol.io/v0/servers?search=io.github.MikhailHal/ariadne"><img src="https://img.shields.io/badge/MCP%20Registry-listed-6E56CF.svg?style=flat-square" alt="MCP Registry"></a>
    <a href="https://github.com/MikhailHal/homebrew-tap"><img src="https://img.shields.io/badge/homebrew-mikhailhal%2Ftap-FBB040.svg?style=flat-square&logo=homebrew&logoColor=white" alt="Homebrew"></a>
    <a href="https://github.com/MikhailHal/ariadne/pkgs/container/ariadne"><img src="https://img.shields.io/badge/ghcr.io-ariadne-2496ED.svg?style=flat-square&logo=docker&logoColor=white" alt="Container image"></a>
    <a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg?style=flat-square" alt="License"></a>
    <a href="https://kotlinlang.org"><img src="https://img.shields.io/badge/Kotlin-2.3.0-7F52FF.svg?style=flat-square&logo=kotlin&logoColor=white" alt="Kotlin"></a>
  </p>
</p>

<br>

**ariadne** is an MCP (Model Context Protocol) server that provides AI agents with the ability to identify affected tests. Powered by [sazanami](https://github.com/MikhailHal/sazanami), it analyzes code changes and returns only the tests that need to be run.

<p align="center">
  <a href="https://glama.ai/mcp/servers/MikhailHal/ariadne">
    <img src="https://glama.ai/mcp/servers/MikhailHal/ariadne/badges/card.svg" alt="ariadne MCP server" />
  </a>
</p>

> [!IMPORTANT]
> ## ⚠️ MUST READ: Speed over Completeness
>
> ariadne is built for the agent inner loop — edit, verify, commit — where fast
> feedback matters more than exhaustive selection. Static analysis cannot trace
> every execution path: reflection, DI frameworks, and data-flow indirection
> (e.g., Flux/MVI dispatch) can hide dependencies from **any**
> affected-test-selection tool, not just ariadne.
>
> **Always keep a final line of defense in CI.** Run the full test suite (or a
> conservative selection) before merging. ariadne narrows what an agent runs
> while iterating; it is not a replacement for CI.
>
> When ariadne detects changes it cannot analyze (build scripts, resources,
> unscanned source sets), it says so explicitly in the tool response instead of
> silently reporting "no affected tests".

## Features

- **MCP Integration** — Works with Claude Code, Claude Desktop, and other MCP-compatible clients
- **Automatic Git Diff** — No need to pass diff manually; ariadne runs `git diff` internally
- **Powered by sazanami** — Uses Kotlin Analysis API for accurate static analysis

## Installation

### Homebrew (recommended)

```bash
brew install mikhailhal/tap/ariadne
```

Then register it with your MCP client — for Claude Code:

```bash
claude mcp add ariadne -- ariadne
```

Or add to your MCP client configuration manually (e.g., Claude Desktop):

```json
{
  "mcpServers": {
    "ariadne": {
      "command": "ariadne"
    }
  }
}
```

### Docker

```bash
docker run -i --rm -v /path/to/project:/workspace ghcr.io/mikhailhal/ariadne
```

Mount the project you want analyzed and pass `/workspace` as `project_path`.
The image is also listed in the [official MCP Registry](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.MikhailHal/ariadne) as `io.github.MikhailHal/ariadne`.

### Manual (release JAR)

Download `ariadne-<version>-all.jar` from [Releases](https://github.com/MikhailHal/ariadne/releases) (requires JDK 21+) and configure your client with `"command": "java", "args": ["-jar", "/path/to/ariadne-<version>-all.jar"]`.

### Build from Source

```bash
git clone --recursive https://github.com/MikhailHal/ariadne.git
cd ariadne
./gradlew shadowJar   # fat JAR: build/libs/ariadne-<version>-all.jar
```

## Usage

Once configured, AI agents can use the `get_affected_tests` tool:

### Tool: `get_affected_tests`

**Parameters:**
- `project_path` (required) — Path to the Kotlin project
- `scope` (optional, `deep` | `shallow`, default `deep`) — how far back to look:
  - **`deep`** — all changes since `base_branch` (committed *and* uncommitted). Safest; the whole branch is covered so nothing you already committed slips through unverified. May select more tests.
  - **`shallow`** — uncommitted changes only (diff against `HEAD`). Fastest, for the tight edit loop. Verifying already-committed work is left to the caller. `base_branch` is ignored.
- `base_branch` (optional, `deep` scope only) — Branch to compare against. When omitted, ariadne uses the repository's default branch (`origin/HEAD`). If that is not set (e.g. a repo with no remote), it returns an error asking you to pass `base_branch` explicitly rather than guessing.

**Returns:**
- List of affected test FQNs (fully qualified names), sorted
- If the diff contains changes outside the analyzed Kotlin sources (build scripts,
  resources, unscanned source sets), a note is appended recommending a full test run
  for those changes
- Analysis is bounded by a 120s timeout; on timeout an explicit error is returned

### Example

Agent request:
```json
{
  "name": "get_affected_tests",
  "arguments": {
    "project_path": "/path/to/your/kotlin/project"
  }
}
```

Response:
```
com.example.UserServiceTest.testCreateUser
com.example.UserRepositoryTest.testSave
```

## How It Works

```
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  MCP Client │ ──▶ │   ariadne   │ ──▶ │  sazanami   │
│  (Agent)    │     │ (MCP Server)│     │  (Analysis) │
└─────────────┘     └─────────────┘     └─────────────┘
                           │
                           ▼
                    ┌─────────────┐
                    │  git diff   │
                    └─────────────┘
```

1. **Agent calls tool** — Passes project path to ariadne
2. **Run git diff** — ariadne executes `git diff --unified=0` against base branch
3. **Analyze with sazanami** — Build call graph and find affected tests
4. **Return results** — List of test FQNs returned to agent

## Real-World Validation: Now in Android

Measured against [Now in Android](https://github.com/android/nowinandroid)
(Google's reference Android app — 34 modules, ~268 Kotlin files):

| Metric | Result |
|---|---|
| Recall audit — 19 target functions across all layers | **18/18 valid targets detected** (the 19th had no exercising unit test; correctly not selected) |
| End-to-end response time | **~4s** (module discovery + call-graph build + BFS) |
| Module discovery | 34 modules via `settings.gradle.kts`, incl. nested modules and type-safe accessor dependencies |
| Source sets | `main`, `debug`, `prod`, `benchmark`, `testDemo`, … discovered per module (`androidTest*` excluded by design) |

Verified patterns include repositories behind project interfaces, a library-interface
override (`androidx.datastore.Serializer`), `operator fun invoke` use cases,
`@Composable` functions, extension mappers, ViewModel property-initializer chains,
and callable references. Two representative results:

- Changing `core:common`'s `asResult()` selects **14 tests across three modules**,
  including ViewModel tests reachable only through `val uiState = ...stateIn(...)`
- Changing the mapper `PopulatedNewsResource.asExternalModel()` selects **14 tests**,
  including 11 repository tests reachable only through `.map(Type::mapper)` chains

### Test-class selection rate

Every unit-test class in Now in Android was measured by changing a function in the
class it tests and checking whether that test class was selected:

| Test style | Selected |
|---|---|
| Plain unit tests (construct the object, call it) | 13 / 13 valid targets |
| Robolectric / Compose screenshot tests | **12 / 12** |
| Framework-dispatched callbacks (lint `Detector`) | 0 / 2 — see below |

Robolectric turned out **not** to be a barrier: those tests call the composable
themselves (`setContent { NiaTheme { ... } }`), so the call exists in the source.
What decides coverage is not the test runner but whether the test's own code
contains the call.

### What ariadne cannot see

The rule of thumb: **if the framework calls your code instead of your test calling
it, ariadne cannot connect them.** These are limits of static analysis, not bugs —
plan your CI safety net around them:

| Pattern | Status |
|---|---|
| Framework-invoked callbacks — Fragment/Activity lifecycle (`launchFragmentInContainer`), lint `Detector` methods, `Application.onCreate` | Not traced: no call written in the test |
| Reflection / DI-container wiring | Not traced |
| UDF dispatch (Flux/MVI) | `dispatch → collect` is never an edge, but wiring in `init` (or a `start()` the test calls) is covered conservatively via constructor chains. Subscriptions started by DI/lifecycle are **not** covered ([sazanami#38](https://github.com/MikhailHal/sazanami/issues/38)) |
| `stateIn` / `shareIn` chains (`map`, `onEach`, `flatMapLatest`, `combine`) | Covered — verified with exact selection |
| Instrumented tests (`androidTest*`) | Out of scope by design |
| Build scripts, resources, unscanned source sets | Not analyzed — reported explicitly in the tool response |
| Same-name top-level extensions in one package | Over-selected (receiver types are not part of top-level FQNs) — safe direction |
| KMP source sets (`commonMain`, `expect`/`actual`) | Enumerated, but resolution quality unverified ([#1](https://github.com/MikhailHal/ariadne/issues/1)) |

Full audit notes: [sazanami#29](https://github.com/MikhailHal/sazanami/issues/29),
[sazanami#38](https://github.com/MikhailHal/sazanami/issues/38).

## Requirements

- **JDK 21** or later
- **Git** — For diff detection

## Limitations

- Module discovery is convention-based: 

Lo que la gente pregunta sobre ariadne

¿Qué es MikhailHal/ariadne?

+

MikhailHal/ariadne es mcp servers para el ecosistema de Claude AI. ariadne is an MCP (Model Context Protocol) server that provides AI agents with the ability to identify affected tests. Tiene 1 estrellas en GitHub y se actualizó por última vez today.

¿Cómo se instala ariadne?

+

Puedes instalar ariadne clonando el repositorio (https://github.com/MikhailHal/ariadne) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.

¿Es seguro usar MikhailHal/ariadne?

+

MikhailHal/ariadne aún no ha sido auditado por nuestro agente de seguridad. Revisa el repositorio original en GitHub antes de usarlo en producción.

¿Quién mantiene MikhailHal/ariadne?

+

MikhailHal/ariadne es mantenido por MikhailHal. La última actividad registrada en GitHub es de today, con 1 issues abiertos.

¿Hay alternativas a ariadne?

+

Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.

Despliega ariadne en tu cloud

Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.

¿Mantienes este repo? Añade un badge a tu README

Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.

Featured on ClaudeWave: MikhailHal/ariadne
[![Featured on ClaudeWave](https://claudewave.com/api/badge/mikhailhal-ariadne)](https://claudewave.com/repo/mikhailhal-ariadne)
<a href="https://claudewave.com/repo/mikhailhal-ariadne"><img src="https://claudewave.com/api/badge/mikhailhal-ariadne" alt="Featured on ClaudeWave: MikhailHal/ariadne" width="320" height="64" /></a>

Más MCP Servers

Alternativas a ariadne