# dependency-doc [![Listed on mcpservers.org](https://mcpservers.org/badge.svg)](https://mcpservers.org/servers/sindhunaydu/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): ```json { "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