kotlin-sdk/samples/kotlinlang-mcp-server
Repository files (latest commit first)
Filename Latest commit message Latest commit date
dependabot[bot] cce22c282a
chore(deps): bump ch.qos.logback:logback-classic from 1.6.0 to 1.6.1 in /samples/kotlinlang-mcp-server in the other-dependencies group across 1 directory (#924)
Bumps the other-dependencies group with 1 update in the
/samples/kotlinlang-mcp-server directory:
[ch.qos.logback:logback-classic](https://github.com/qos-ch/logback).

Updates `ch.qos.logback:logback-classic` from 1.6.0 to 1.6.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/qos-ch/logback/releases">ch.qos.logback:logback-classic's
releases</a>.</em></p>
<blockquote>
<h2>Logback 1.6.1</h2>
<p><strong>2026-07-28 Release of logback version 1.6.1</strong></p>
<p>• In TimeBasedRollingPolicy, when the file option is set, the
intermediate file renamed before asynchronous compression now receives
the target archive name without the compression suffix (e.g.
<code>.gz</code>, <code>.zip</code>, <code>.xz</code>). Previously it
used a nanotime-based <code>.tmp</code> suffix. This makes the file
easier to identify if compression fails during rollover. (See also the
following paragraph.)</p>
<p>• On GZ, ZIP, or XZ compression failure, the original (uncompressed)
log file is no longer deleted. Compression strategies now delete the
source file only after successful compression and emit a warning that
the original was left intact.</p>
<p>• ConsoleAppender with <!-- raw HTML omitted --> now probes JLine's
org.jline.jansi.AnsiConsole first and falls back to the legacy
FuseSource org.fusesource.jansi.AnsiConsole class. This keeps ANSI
coloring working after Jansi moved under the JLine project. The optional
org.jline:jansi-core artifact is declared as a dependency alongside the
existing FuseSource jansi dependency. A preferredJansiClassName property
was added for tests. This issue was reported in <a
href="https://redirect.github.com/qos-ch/logback/issues/1043">issues/1043</a>
by <a href="https://github.com/seonwooj0810">seonwoo_jung</a> who also
provided the relevant PR.</p>
<p>• LayoutWrappingEncoder now reports an error at start() when no
layout is set and guards encode() against a null layout. Previously, a
missing layout (for example after an ignored <!-- raw HTML omitted
-->/<!-- raw HTML omitted -->/<!-- raw HTML omitted --> branch) allowed
the encoder to start and then fail with a NullPointerException on every
event, resulting in silent log loss. This issue was reported in <a
href="https://redirect.github.com/qos-ch/logback/issues/1046">issues/1046</a>
by <a href="https://github.com/seonwooj0810">seonwoo_jung</a> who also
provided the relevant PR.</p>
<p>• FileCollisionAnalyser now detects file collisions involving nested
appenders of SiftingAppender. When the nested file or fileNamePattern
does not textually reference the discriminator key (e.g. ${userId}), a
warning is issued at configuration time naming the appender, the key,
and the shared target. This closes a gap where statically declared file
appenders were checked but sifted nested appenders were not. This
enhancement was contributed in [PR <a
href="https://redirect.github.com/qos-ch/logback/issues/1041">#1041</a>](<a
href="https://redirect.github.com/qos-ch/logback/issues/1041">qos-ch/logback#1041</a>)
by <a href="https://github.com/seonwooj0810">seonwoo_jung</a>.</p>
<p>• More defensive handling in SyslogOutputStream and
SyslogAppenderBase: the close() method now ensures that resources are
closed, writes and flushes check that the underlying resources are in a
valid state and fallback to no-op otherwise.</p>
<p>• A bit-wise identical binary of this version can be reproduced by
building from source code at commit
57759f433000a133088ef0441038963134437fbd associated with the tag
v_1.6.1. The release was built using Java &quot;21&quot; 2023-10-17 LTS
build 21.0.1.+12-LTS-29 under Linux Debian 11.6.</p>
<p>• See <a
href="https://logback.qos.ch/news.html#1.6.1">https://logback.qos.ch/news.html#1.6.1</a>
for the original text.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="57759f4330"><code>57759f4</code></a>
prepare release 1.6.1</li>
<li><a
href="175f99f209"><code>175f99f</code></a>
fix imports</li>
<li><a
href="4b8773ed12"><code>4b8773e</code></a>
add compressionFailureLeavesOriginalFileIntact test for XZ
compression</li>
<li><a
href="cafaf1115f"><code>cafaf11</code></a>
do not delete original file if compression fails</li>
<li><a
href="ee50125b29"><code>ee50125</code></a>
let the temporary file before compression be target file without the .gz
or ....</li>
<li><a
href="5626acc301"><code>5626acc</code></a>
minor refactoring</li>
<li><a
href="d97da4fbc0"><code>d97da4f</code></a>
minor refactoring</li>
<li><a
href="159c045d8f"><code>159c045</code></a>
more defensive coding in SyslogOutputStream and in
SyslogAppenderBase</li>
<li><a
href="9427d6b23d"><code>9427d6b</code></a>
slight refactoring for clarity</li>
<li><a
href="79c4179c0b"><code>79c4179</code></a>
slight refactoring</li>
<li>Additional commits viewable in <a
href="https://github.com/qos-ch/logback/compare/v_1.6.0...v_1.6.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ch.qos.logback:logback-classic&package-manager=gradle&previous-version=1.6.0&new-version=1.6.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-03 12:23:43 +02:00
..
gradle chore(deps): bump ch.qos.logback:logback-classic from 1.6.0 to 1.6.1 in /samples/kotlinlang-mcp-server in the other-dependencies group across 1 directory (#924) 2026-08-03 12:23:43 +02:00
src sample: kotlinlang mcp server (#713) 2026-04-27 15:07:03 +02:00
build.gradle.kts sample: kotlinlang mcp server (#713) 2026-04-27 15:07:03 +02:00
Dockerfile sample: kotlinlang mcp server (#713) 2026-04-27 15:07:03 +02:00
gradle.properties sample: kotlinlang mcp server (#713) 2026-04-27 15:07:03 +02:00
gradlew chore(deps): bump the other-dependencies group across 5 directories with 3 updates (#854) 2026-06-24 15:31:46 +02:00
gradlew.bat chore(deps): bump the other-dependencies group across 5 directories with 3 updates (#854) 2026-06-24 15:31:46 +02:00
README.md sample: kotlinlang mcp server (#713) 2026-04-27 15:07:03 +02:00
settings.gradle.kts sample: kotlinlang mcp server (#713) 2026-04-27 15:07:03 +02:00

Kotlinlang MCP Server

A Streamable HTTP MCP server that exposes the official Kotlin documentation to LLM clients — full-text search via Algolia plus page retrieval in markdown through kotlinlang.org's _llms endpoints.

Overview

This sample demonstrates an MCP server that wraps a real external documentation source. It uses the recommended Streamable HTTP transport, supports multiple concurrent client sessions, and caches responses in memory to reduce upstream load. The server is intentionally read-only — it exposes two tools, no prompts, no resources.

Prerequisites

  • JDK 21+
  • Algolia credentials for kotlinlang.org (exported as environment variables, see Configuration)

Build & Run

export ALGOLIA_APP_ID=...
export ALGOLIA_API_KEY=...
export ALGOLIA_INDEX_NAME=...

./gradlew run

The server starts on http://localhost:8080/mcp by default.

Connect with the MCP Inspector:

npx @modelcontextprotocol/inspector

In the Inspector UI, select Streamable HTTP transport and enter http://localhost:8080/mcp.

MCP Capabilities

Tools

Name Description
search_kotlinlang Full-text search across Kotlin documentation. Returns up to 5 results filtered to /docs/ pages. Responses cached for 10 minutes.
get_kotlinlang_page Fetches a documentation page as markdown via kotlinlang.org's _llms endpoint. Accepts a path relative to /docs/. Cached for 1 hour.

Example paths accepted by get_kotlinlang_page: coroutines-overview, multiplatform/compose-multiplatform-and-jetpack-compose. Leading/trailing slashes and an optional .html suffix are normalized before resolution.

Configuration

Variable Required Default Description
ALGOLIA_APP_ID yes — Algolia application ID
ALGOLIA_API_KEY yes — Algolia search API key
ALGOLIA_INDEX_NAME yes — Algolia index name
SERVER_PORT no 8080 HTTP server port
SERVER_HOST no 0.0.0.0 HTTP server bind address

The server does not provide fallback values for ALGOLIA_*. Startup fails if any of those variables are missing.

Docker

Multi-stage build with Alpine-based images. Runs as a non-root user.

docker build -t kotlinlang-mcp-server .

docker run \
  -p 8080:8080 \
  -e ALGOLIA_APP_ID=... \
  -e ALGOLIA_API_KEY=... \
  -e ALGOLIA_INDEX_NAME=... \
  kotlinlang-mcp-server

Connecting an MCP client

Any MCP client that supports Streamable HTTP transport can connect:

{
  "mcpServers": {
    "kotlinlang": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

Limitations

This sample is intended for demonstration only. Before production use, consider:

  • In-memory cache only — cached data is lost on server restart.
  • No authentication or authorization — run behind a trusted proxy or restrict network access.
  • No rate limiting on outgoing requests to Algolia and kotlinlang.org.
  • Permissive CORS (anyHost()) — restrict to specific origins for any non-local deployment.
  • Streamable HTTP only — no STDIO transport for local-only usage.
  • Tools only — no MCP resources or prompts are exposed.