Dependency Doctor
Tools for resolving dependency conflicts
Documentation
dependency-doc
An MCP server that explains Maven dependency resolution. Ask your AI assistant why a version is on your classpath — and get the actual answer: which rule decided, who requested what, and the full path of the dependency that dragged it in.
You: why do I have commons-lang3 3.9 in my project?
Claude (via dependency-doc): The chain is
spring-boot-testcontainers → testcontainers 2.0.5 → commons-compress 1.28.0 → commons-lang3 3.20.0(test scope) — but Maven resolved to 3.9 anyway. Maven doesn't pick the newest version, it picks the nearest declaration in the tree, and your pom declares 3.9 directly. Your one-line declaration silently downgraded the whole project by eleven versions.
Why this exists
mvn dependency:tree -Dverbose shows you that a version was omitted. It never explains why — and the why involves rules most developers have never been taught: nearest-wins mediation, dependencyManagement pins, BOM imports, exclusion shadowing. A typical Spring Boot project inherits over 1,900 managed versions it never wrote. When an upgrade mysteriously doesn't take effect, the answer is buried in that machinery.
dependency-doc runs Maven's own resolution machinery (Maven Resolver + Model Builder) against your actual pom.xml and exposes the results as MCP tools, so an AI assistant can answer dependency questions with evidence instead of guesses.
Tools
analyzeDependencies(pomPath) — full-tree health check: node counts, direct dependencies, and every version conflict with its complete explanation.
explainVersion(pomPath, groupArtifact) — the core feature. For one library: the resolved version, the rule that decided it (direct declaration / dependencyManagement / nearest-wins), and every request with its path and outcome.
findDependencyPaths(pomPath, groupArtifact) — every chain by which a library enters your build. Useful for planning exclusions.
Setup
Requires Java 21+.
git clone https://github.com/sindhunaydu/dependency-doc.git
cd dependency-doc
./gradlew bootJar
Add to Claude Desktop's config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"dependency-doc": {
"command": "java",
"args": ["-jar", "/absolute/path/to/dependency-doc/build/libs/dependency-doc-0.0.1-SNAPSHOT.jar"]
}
}
}
Restart Claude Desktop fully, then ask it something like: "Analyze the dependencies of /path/to/my-project/pom.xml — why is jackson-databind at the version it's at?"
How it works
dependency-doc embeds the same libraries Maven itself is built on. The Model Builder turns your pom.xml into the effective model — parents inherited, BOMs imported, properties interpolated. Maven Resolver then collects the full dependency graph with conflict-loser preservation enabled, so superseded requests stay in the graph, marked with what beat them. The analysis layer walks that graph and turns markings into explanations.
Analysis differs from a build in one important way: your project's own test and provided dependencies are part of the truth (a custom scope selector encodes Maven's exact semantics — direct test deps in, other libraries' test universes out).
A note on strict mode (a debugging saga)
This tool refuses to silently omit branches. During development, a stack of quiet defaults — a lenient artifact-descriptor policy plus an empty-looking exception list — produced a confident "Conflicts: 0" on a project that verifiably had conflicts. The cause: parent poms with JDK-activated profiles failed to build when the resolver session lacked system properties, and the lenient policy swallowed every failure, leaving childless nodes and a clean-looking report.
dependency-doc therefore runs with a strict descriptor policy and surfaces every collection problem in its responses. An analysis that fails loudly is useful; one that lies confidently is worse than none. If a response includes a "⚠ Analysis incomplete" section, believe it.
Limitations & roadmap
- Maven only, for now. Gradle resolution uses a genuinely different model (highest-wins, constraints, resolution rules) and is planned as v2 via the Gradle Tooling API.
- Single-module projects; multi-module reactor support is planned.
- Tree diffing (
what changes if I bump X?) is on the roadmap.
Issues and PRs welcome.
License
Apache 2.0