Skip to content

docs: update client and server samples#598

Merged
devcrocod merged 5 commits into
mainfrom
devcrocod/update-client-and-server-samples
Mar 13, 2026
Merged

docs: update client and server samples#598
devcrocod merged 5 commits into
mainfrom
devcrocod/update-client-and-server-samples

Conversation

@devcrocod
Copy link
Copy Markdown
Contributor

Updated the client and server examples for further use in the following guides: https://modelcontextprotocol.io/docs/develop/build-server and https://modelcontextprotocol.io/docs/develop/build-client

How Has This Been Tested?

claude desktop, cli

Breaking Changes

NaN

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Example, Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Kotlin client and weather STDIO server samples to align with current MCP Kotlin SDK usage and to support the “build client/server” guides on modelcontextprotocol.io.

Changes:

  • Updated the weather server sample to use a CIO-backed Ktor client, improved tool schemas/annotations, and added basic input validation plus Result-based API wrappers.
  • Refined the Kotlin CLI client sample to require ANTHROPIC_API_KEY, improve subprocess handling, and implement proper Anthropic tool-result message flow.
  • Bumped sample dependency versions (notably mcp-kotlin to 0.9.0 and Anthropic SDK to 2.15.0) and adjusted docs/example invocation paths.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
samples/weather-stdio-server/src/test/kotlin/io/modelcontextprotocol/sample/client/ClientStdio.kt Updates jar path + stderr handling; aligns tool name with server (get_alerts).
samples/weather-stdio-server/src/main/kotlin/io/modelcontextprotocol/sample/server/WeatherApi.kt Refactors Weather.gov API wrappers to return Result and updates response models.
samples/weather-stdio-server/src/main/kotlin/io/modelcontextprotocol/sample/server/McpWeatherServer.kt Restructures server startup, adds CIO client creation, tool annotations, and improved tool behavior.
samples/weather-stdio-server/gradle/libs.versions.toml Removes unused libs; bumps MCP Kotlin version.
samples/weather-stdio-server/build.gradle.kts Cleans up dependencies (removes unused server/collections libs).
samples/weather-stdio-server/README.md Minor table/order update for tool docs.
samples/kotlin-mcp-client/src/main/kotlin/io/modelcontextprotocol/sample/client/main.kt Requires ANTHROPIC_API_KEY and simplifies CLI usage.
samples/kotlin-mcp-client/src/main/kotlin/io/modelcontextprotocol/sample/client/MCPClient.kt Updates Anthropic/tool-calling flow and improves subprocess lifecycle handling.
samples/kotlin-mcp-client/gradle/libs.versions.toml Bumps Anthropic + MCP Kotlin versions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +173 to +181
onFailure = { _ ->
CallToolResult(
content = listOf(
TextContent(
"Failed to retrieve grid point data for coordinates: $latitude, $longitude. " +
"This location may not be supported by the NWS API (only US locations are supported).",
),
),
isError = true,
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The forecast failure path discards the exception and always returns a message implying the location is unsupported. This can mislead users when the real issue is e.g. network failure or an API outage; consider including the underlying error message (or at least differentiating HTTP 404 from other failures).

Copilot uses AI. Check for mistakes.
Comment on lines +14 to 21
alerts.features.map { feature ->
"""
${period.name}:
Temperature: ${period.temperature} ${period.temperatureUnit}
Wind: ${period.windSpeed} ${period.windDirection}
Forecast: ${period.detailedForecast}
Event: ${feature.properties.event}
Area: ${feature.properties.areaDesc}
Severity: ${feature.properties.severity}
Status: ${feature.properties.status}
Headline: ${feature.properties.headline}
""".trimIndent()
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These properties are nullable in AlertProperties, but the tool output interpolates them directly. If any field is absent, the user will see "null" in the response. Consider making these fields non-null with defaults, or using ?: fallbacks when formatting the output.

Copilot uses AI. Check for mistakes.
Comment on lines +36 to 42
forecast.properties.periods.map { period ->
"""
Event: ${feature.properties.event}
Area: ${feature.properties.areaDesc}
Severity: ${feature.properties.severity}
Description: ${feature.properties.description}
Instruction: ${feature.properties.instruction}
${period.name}:
Temperature: ${period.temperature}°${period.temperatureUnit}
Wind: ${period.windSpeed} ${period.windDirection}
${period.shortForecast}
""".trimIndent()
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ForecastPeriod fields are nullable, but the formatted output uses them directly (e.g., temperature/unit/name). This can produce strings like "Temperature: null°null" if the API omits a field. Either make the fields non-null with sensible defaults or format with fallbacks / omit missing fields.

Copilot uses AI. Check for mistakes.
Comment on lines 13 to +17
val process = ProcessBuilder(
"java",
"-jar",
"${System.getProperty("user.dir")}/build/libs/weather-stdio-server-0.1.0-all.jar",
).redirectErrorStream(true)
"${System.getProperty("user.dir")}/samples/weather-stdio-server/build/libs/weather-stdio-server-0.1.0-all.jar",
).redirectError(ProcessBuilder.Redirect.INHERIT)
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The jar path is hard-coded relative to user.dir as if the working directory is the repo root. If this example is run with the working directory set to samples/weather-stdio-server, the resulting path will be incorrect. Consider resolving the jar path relative to the module directory (or accept it as an argument/env var) to make the example robust.

Copilot uses AI. Check for mistakes.
)
val state = request.arguments?.get("state")?.jsonPrimitive?.content
?: return@addTool CallToolResult(
content = listOf(TextContent("The 'state' parameter is required.")),
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The missing required "state" argument returns a normal CallToolResult without isError=true, while other validation failures in this tool do set isError. Marking this as an error will let clients reliably detect invalid requests.

Suggested change
content = listOf(TextContent("The 'state' parameter is required.")),
content = listOf(TextContent("The 'state' parameter is required.")),
isError = true,

Copilot uses AI. Check for mistakes.
Comment on lines 112 to +114

CallToolResult(content = alerts.map { TextContent(it) })
val stateCode = state.uppercase()

Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

state.uppercase() is locale-sensitive and can produce unexpected results in some locales (e.g., Turkish), which could send an invalid state code to the NWS API. Prefer an explicit locale (e.g., uppercase(Locale.US)) for US state codes.

Copilot uses AI. Check for mistakes.
Comment on lines 158 to 162
if (latitude == null || longitude == null) {
return@addTool CallToolResult(
content = listOf(TextContent("The 'latitude' and 'longitude' parameters are required.")),
)
}
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The missing required latitude/longitude case returns a success-shaped CallToolResult without isError=true. Consider setting isError=true here so clients can distinguish invalid input from a valid tool response.

Copilot uses AI. Check for mistakes.
content = listOf(TextContent("The 'latitude' and 'longitude' parameters are required.")),
)
}

Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though the tool schema includes min/max for latitude/longitude, the handler doesn't enforce those bounds (or reject NaN/Infinity). Adding runtime validation (range + finite check) will prevent unnecessary calls to the NWS API with invalid coordinates.

Suggested change
if (!latitude.isFinite() || !longitude.isFinite() ||
latitude !in -90.0..90.0 || longitude !in -180.0..180.0
) {
return@addTool CallToolResult(
content = listOf(
TextContent(
"Invalid coordinates. Latitude must be between -90 and 90, and longitude between -180 and 180.",
),
),
isError = true,
)
}

Copilot uses AI. Check for mistakes.
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@devcrocod devcrocod merged commit 921b1fd into main Mar 13, 2026
24 checks passed
@devcrocod devcrocod deleted the devcrocod/update-client-and-server-samples branch March 13, 2026 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants