mcpField
A
ariadne

ariadne

本地服务
github.com开发工具314 周前更新

关于 ariadne

ariadne 是面向 Kotlin 项目的 MCP 服务,可分析 Git 变更并筛选需要运行的单元测试,帮助编码 Agent 加快编辑验证循环,同时明确提示分析范围之外的变更。

主要功能

  1. 01筛选受 Kotlin 变更影响的测试
  2. 02自动读取 Git 差异
  3. 03支持深层与浅层变更范围
  4. 04返回排序后的测试全限定名
  5. 05提示分析范围外的变更

适用场景

  1. 01编辑 Kotlin 时运行针对性单元测试
  2. 02提交前检查分支变更
  3. 03判断是否应运行完整测试

MCP 相关

它向 MCP 客户端提供 `get_affected_tests` 工具。该工具接收 Kotlin 项目路径,并根据检测到的 Git 变更返回受影响的测试。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"mikhailhal-ariadne": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/mikhailhal/ariadne:0.4.0"
]
}
}
}
启动命令docker run -i --rm ghcr.io/mikhailhal/ariadne:0.4.0

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
ocighcr.io/mikhailhal/ariadne:0.4.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

ariadne 横幅

ariadne

用于受影响测试选择的 MCP 服务

发布版本 MCP 注册表 Homebrew 容器镜像 许可证 Kotlin


ariadne 是一个 MCP(Model Context Protocol)服务,可帮助 AI Agent 识别受影响的测试。它由 sazanami 提供支持,可分析代码更改并仅返回需要运行的测试。

ariadne MCP 服务

重要

⚠️ 必须阅读:速度优先于完整性

ariadne 专为 Agent 的内循环而构建,即编辑、验证、提交;在此过程中,快速反馈比穷尽式选择更重要。静态分析无法追踪每一条执行路径:反射、DI 框架和数据流间接调用(例如 Flux/MVI 分发)可能会让任何受影响测试选择工具无法发现依赖关系,ariadne 也不例外。

始终在 CI 中保留最后一道防线。 合并前请运行完整测试套件(或采用保守的测试选择方案)。ariadne 会在 Agent 迭代期间缩小运行范围,但不能替代 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

挂载要分析的项目,并将 /workspace 作为 project_path 传入。 该镜像也已列入官方 MCP 注册表,名称为 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 Agent 可使用 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 秒;超时会返回明确的错误
示例

Agent 请求:

{
  "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   │
                    └─────────────┘
  1. Agent 调用工具 — 将项目路径传给 ariadne
  2. 运行 git diff — ariadne 针对基础分支执行 git diff --unified=0
  3. 使用 sazanami 分析 — 构建调用图并查找受影响的测试
  4. 返回结果 — 将测试 FQN 列表返回给 Agent

真实场景验证: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 属性初始化器链,以及可调用引用。两个有代表性的结果:

  • 更改 core:common 的 asResult() 会选中三个模块中的 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
  • 每次请求都会完整重建图(尚未提供缓存);分析上限为 120s
  • 分析层面的缺口请参阅 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。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。