-
Notifications
You must be signed in to change notification settings - Fork 178
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the bug
When trying to add progress notifications to a request, setting the RequestOptions.onProgress lambda in the callTool method does not include progressToken in the _meta of the request.
To Reproduce
Steps to reproduce the behavior:
- Add tool to server that can support progress notifications by trying to extract the progress token from
_meta.
RegisteredTool(
Tool(
name = "progressFail",
description = "Fails with null pointer exception",
inputSchema = Tool.Input(),
outputSchema = Tool.Output(),
annotations = null,
),
) { request ->
val progressToken = request._meta["progressToken"]?.let { jsonElement ->
Json.decodeFromJsonElement<ProgressToken>(jsonElement)
}
progressToken!! // throws NPE
}- Connect a client to the server an make a call tool request like so:
client.callTool(
CallToolRequest(
name = "progressFail",
),
RequestOptions(
onProgress = {
progress.progress / progress.total
}
)
)- Server will throw NPE
- Try to set progressToken manually on request:
client.callTool(
CallToolRequest(
name = "progressFail",
_meta = buildJsonObject {
put("progressToken", 1234) // we don't have access to the request id here so it's impossible to associate the onProgress callback with this token
},
),
RequestOptions(
onProgress = {
progress.progress / progress.total // will never be called because it is associated to request id
}
)
)- Receive log messages about a progress notification for an unknown token.
Expected behavior
I expect to be able to both register an onProgress callback on a callTool invocation, and be able to extract that token on the server to send it back with the notification.
Logs
Log of NPE when not manually setting token:
{"timestamp":"2025-08-07T21:30:58.052","level":"INFO","logger.thread_name":"docker-java-stream-1030446516","logger.name":"...","message":"{\"timestamp\":\"2025-08-08T01:30:58.043\",\"level\":\"ERROR\",\"logger.thread_name\":\"DefaultDispatcher-worker-2\",\"logger.name\":\"io.modelcontextprotocol.kotlin.sdk.shared.Protocol\",\"message\":\"Error handling request: tools/call (id: NumberId(value=4))\",\"error.stack\":\"java.lang.NullPointerException: null\\n\\tat
...
kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)\\n\\tat kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)\\n\\tat kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586)\\n\\tat kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:829)\\n\\tat kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717)\\n\\tat kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704)\\n\",\"error.kind\":\"java.lang.NullPointerException\"}"}Logs when attempting to set token manually in _meta on a request:
{"timestamp":"2025-08-07T20:58:26.981","level":"ERROR","logger.thread_name":"DefaultDispatcher-worker-5 @SseMcpClientTransport.connect#385137368#23","logger.name":"io.modelcontextprotocol.kotlin.sdk.shared.Protocol","message":"Received a progress notification for an unknown token: {\"progress\":0,\"progressToken\":12345,\"_meta\":{},\"total\":5.0,\"method\":\"notifications/progress\"}"}
{"timestamp":"2025-08-07T20:58:27.983","level":"ERROR","logger.thread_name":"DefaultDispatcher-worker-5 @SseMcpClientTransport.connect#385137368#23","logger.name":"io.modelcontextprotocol.kotlin.sdk.shared.Protocol","message":"Received a progress notification for an unknown token: {\"progress\":1,\"progressToken\":12345,\"_meta\":{},\"total\":5.0,\"method\":\"notifications/progress\"}"}Additional context
Add any other context about the problem here.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working