Your AI coding assistant will confidently hand you a Kotlin method signature that does not exist. For a strongly-typed ecosystem, "plausible but wrong" is the worst failure mode — it compiles in your head and breaks in the build.

Here's it reading the **real** sources instead:

![Claude Code fetching a library and reading its KDoc via kotlin-lib-mcp](demo.gif)

One prompt. `kotlin-lib-mcp` downloaded Ktor's **sources jar**, parsed it with the Kotlin **Analysis API** (the same K2/FIR front-end that powers the IDE), and answered from the actual code.

## One coordinate, ten tools

```kotlin
fetch_library("io.ktor:ktor-client-core:3.5.1")
```

That's the whole setup. The server downloads the sources jar, extracts it, analyzes it once, and caches the parsed index on disk. Your agent then has ten tools over it:

- `list_packages` / `list_declarations` — the public API surface
- `get_api_signature` — a **type-resolved** signature (generics, nullability, receiver)
- `get_kdoc` — KDoc as structured data, not an HTML page
- `get_source` / `search_source` — the real implementation + bounded search
- `get_dependencies` — the dependency tree from `.pom` / `.module`
- `list_versions` / `get_latest_version` — resolve "latest stable" from Maven metadata

Pinned to the **exact version you depend on**, offline after the first fetch. No drift between "the docs" and the version in your build.

## Why "resolved" is the whole point

Regex over source gives you a signature-shaped *string*. The Analysis API actually ran the compiler front-end — so you get the resolved type, not a guess. When a transitive dependency is missing it degrades to a best-effort PSI signature and flags it `bestEffort: true`, instead of failing. Graceful degradation over an empty answer.

Two Kotlin-specific things made this more than "unzip a jar":

1. **KMP sources jars are per-target.** A Multiplatform library publishes `-jvm-sources.jar`, a common one, and so on — resolved via `.module` Gradle metadata, with every symbol tagged by target.
2. **The Analysis API is version-fragile.** Standalone mode must be version-locked to the exact Kotlin release, so it's quarantined behind one `SourceAnalyzer` interface.

## Try it in ~60 seconds

Docker, no build required:

```bash
claude mcp add kotlin-lib -- docker run -i --rm -v kotlin-lib-mcp-cache:/home/mcp/.cache ghcr.io/aoreshkov/kotlin-lib-mcp
```

Or grab the release zip (Java 21+), or install from the **official MCP registry** as `io.github.aoreshkov/kotlin-lib-mcp`. Then ask your agent to fetch a library and explain an API — it answers from the code.

It's also a tidy reference build: all three MCP primitives (tools, **resources** per cached library + a resource template, and a **prompt**), plus per-tool behavior annotations, typed `outputSchema`, progress notifications, and server→client log forwarding. Built on the current stable MCP spec (`2025-11-25`); the 2026 roadmap's stateless core and Tasks/Apps extensions are the natural next step.

**GitHub (demo GIF in the README):** https://github.com/aoreshkov/kotlin-lib-mcp — Apache-2.0. Analysis-API edge cases especially welcome.

*Enjoyed this? I also wrote about [generating a full Kotlin Multiplatform app in one dialog](production-grade-kmp-in-one-dialog.html).*
