Skip to content

Conversation

@devcrocod
Copy link
Contributor

Motivation and Context

fix #220

How Has This Been Tested?

locally

Breaking Changes

None

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)
  • 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
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

This PR fixes a bug where progress tokens were not being properly attached to request parameters when a progress handler is provided. The fix ensures that when onProgress is specified in RequestOptions, the request's _meta field is correctly updated with the progressToken.

Key Changes:

  • Modified request handling to inject progressToken into request metadata when progress handling is enabled
  • Added comprehensive test coverage for progress token scenarios
  • Improved variable naming and error handling in the Protocol class

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/Protocol.kt Core fix: adds logic to inject progressToken into request params when onProgress is provided; improves variable naming (messageId → jsonRpcRequestId) and error handling (Error → IllegalStateException)
kotlin-sdk-core/src/commonTest/kotlin/io/modelcontextprotocol/kotlin/sdk/shared/ProtocolTest.kt Adds comprehensive test coverage for progress token handling including cases for preserving existing meta, creating meta when absent, and handling null params
kotlin-sdk-core/build.gradle.kts Adds kotlinx-coroutines-test dependency required for the new test infrastructure

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

Copy link
Contributor

@kpavlov kpavlov left a comment

Choose a reason for hiding this comment

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

Thank you for the fix.

I have a couple of comments, but it can be addressed later

override fun assertRequestHandlerCapability(method: Method) {}
}

private class RecordingTransport : Transport {
Copy link
Contributor

Choose a reason for hiding this comment

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

good stuff, let's extract it

private var onMessageCallback: (suspend (JSONRPCMessage) -> Unit)? = null
private var onCloseCallback: (() -> Unit)? = null

override suspend fun start() {}
Copy link
Contributor

Choose a reason for hiding this comment

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

it make sense to add debug logging here

}
}

private class TestProtocol : Protocol(null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

good stuff, let's extract it

Comment on lines +58 to +65
val sent = transport.awaitRequest()
val params = requireNotNull(sent.params).jsonObject
val meta = params["_meta"]!!.jsonObject

assertEquals("test://resource", params["uri"]!!.jsonPrimitive.content)
assertEquals("customValue", meta["customField"]!!.jsonPrimitive.content)
assertEquals(123, meta["anotherField"]!!.jsonPrimitive.int)
assertEquals(McpJson.encodeToJsonElement(sent.id), meta["progressToken"])
Copy link
Contributor

Choose a reason for hiding this comment

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

with kotest it might be a bit more readable:

Suggested change
val sent = transport.awaitRequest()
val params = requireNotNull(sent.params).jsonObject
val meta = params["_meta"]!!.jsonObject
assertEquals("test://resource", params["uri"]!!.jsonPrimitive.content)
assertEquals("customValue", meta["customField"]!!.jsonPrimitive.content)
assertEquals(123, meta["anotherField"]!!.jsonPrimitive.int)
assertEquals(McpJson.encodeToJsonElement(sent.id), meta["progressToken"])
val sent = transport.awaitRequest()
val params = sent.params?.jsonObject.shouldNotBeNull()
params["uri"] shouldBe JsonPrimitive("test://resource")
val meta = params["_meta"]?.jsonObject.shouldNotBeNull()
meta["customField"] shouldBe JsonPrimitive("customValue")
meta["anotherField"] shouldBe JsonPrimitive(123)
meta["progressToken"] shouldBe McpJson.encodeToJsonElement(sent.id)

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.

Impossible to add progressToken and use onProgress callback

3 participants