Skip to content

Refactor JSON processing to exclude "method" in serialization #157

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 21, 2025

Conversation

devcrocod
Copy link
Contributor

#56

Motivation and Context

fix bug

How Has This Been Tested?

unit tests and manual testing

Breaking Changes

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

@devcrocod devcrocod requested review from e5l and Copilot July 18, 2025 00:49
Copy link
Contributor

@Copilot 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 refactors JSON processing to ensure the "method" field is excluded during serialization and properly handled during deserialization for both Request and Notification objects. This addresses a bug where the method field was being incorrectly included in the serialized JSON parameters.

  • Modifies JSON serialization to exclude "method" field from parameters during encoding
  • Updates deserialization logic to reconstruct the method field from the JSON-RPC method property
  • Consolidates notification serialization to use the standardized toJSON() function

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
types.kt Updates Request and Notification serialization/deserialization to properly handle method field exclusion and reconstruction
Protocol.kt Refactors notification sending to use the standardized toJSON() method instead of inline serialization
Comments suppressed due to low confidence (3)

src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types.kt:128

  • [nitpick] The variable name encoded is misleading since it represents a modified JSON object with the method field removed, not the full encoded representation. Consider renaming to paramsWithoutMethod or filteredParams for clarity.
    val encoded = JsonObject(McpJson.encodeToJsonElement(this).jsonObject.minus("method"))

src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types.kt:142

  • [nitpick] The variable name requestData could be more descriptive. Consider renaming to paramsWithMethod or reconstructedParams to clearly indicate what this variable represents.
    val requestData = JsonObject(params.jsonObject.plus("method" to JsonPrimitive(method)))

src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types.kt:183

  • [nitpick] The variable name data is too generic. Consider using a more descriptive name like paramsWithMethod to match the pattern used in the Request deserialization function.
    val data = JsonObject(params.jsonObject.plus("method" to JsonPrimitive(method)))

Comment on lines +141 to +145
internal fun JSONRPCRequest.fromJSON(): Request {
val requestData = JsonObject(params.jsonObject.plus("method" to JsonPrimitive(method)))

val deserializer = selectRequestDeserializer(method)
return McpJson.decodeFromJsonElement(deserializer, requestData)
Copy link
Preview

Copilot AI Jul 18, 2025

Choose a reason for hiding this comment

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

The function signature changed from returning Request? to Request, removing null safety. This is a breaking change that could cause issues if callers were handling null returns. Consider maintaining the nullable return type or ensuring all call sites are updated to handle potential exceptions.

Suggested change
internal fun JSONRPCRequest.fromJSON(): Request {
val requestData = JsonObject(params.jsonObject.plus("method" to JsonPrimitive(method)))
val deserializer = selectRequestDeserializer(method)
return McpJson.decodeFromJsonElement(deserializer, requestData)
internal fun JSONRPCRequest.fromJSON(): Request? {
val requestData = JsonObject(params.jsonObject.plus("method" to JsonPrimitive(method)))
val deserializer = selectRequestDeserializer(method)
return try {
McpJson.decodeFromJsonElement(deserializer, requestData)
} catch (e: Exception) {
null
}

Copilot uses AI. Check for mistakes.

Copy link
Contributor

@e5l e5l left a comment

Choose a reason for hiding this comment

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

lgtm

@@ -176,7 +180,8 @@ internal fun Notification.toJSON(): JSONRPCNotification {
* @return The decoded [Notification].
*/
internal fun JSONRPCNotification.fromJSON(): Notification {
return McpJson.decodeFromJsonElement<Notification>(params)
val data = JsonObject(params.jsonObject.plus("method" to JsonPrimitive(method)))
Copy link
Contributor

Choose a reason for hiding this comment

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

should we refactor schema instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, because the scheme is correct

@devcrocod devcrocod enabled auto-merge (squash) July 21, 2025 10:33
@devcrocod devcrocod merged commit ad31693 into main Jul 21, 2025
2 of 3 checks passed
@devcrocod devcrocod deleted the devcrocod/fix-56 branch July 21, 2025 10:40
svc-squareup-copybara pushed a commit to cashapp/misk that referenced this pull request Aug 18, 2025
| Package | Type | Package file | Manager | Update | Change |
|---|---|---|---|---|---|
|
[io.modelcontextprotocol:kotlin-sdk](https://github.com/modelcontextprotocol/kotlin-sdk)
| dependencies | misk/gradle/libs.versions.toml | gradle | minor |
`0.5.0` -> `0.6.0` |
|
[org.jetbrains.kotlinx:kotlinx-serialization-json](https://github.com/Kotlin/kotlinx.serialization)
| dependencies | misk/gradle/libs.versions.toml | gradle | minor |
`1.7.3` -> `1.9.0` |
|
[org.jetbrains.kotlinx:kotlinx-serialization-core](https://github.com/Kotlin/kotlinx.serialization)
| dependencies | misk/gradle/libs.versions.toml | gradle | minor |
`1.7.3` -> `1.9.0` |
|
[com.google.apis:google-api-services-storage](http://nexus.sonatype.org/oss-repository-hosting.html)
([source](http://svn.sonatype.org/spice/tags/oss-parent-7)) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`v1-rev20250718-2.0.0` -> `v1-rev20250814-2.0.0` |
| [software.amazon.awssdk:sdk-core](https://aws.amazon.com/sdkforjava) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.23` -> `2.32.24` |
| [software.amazon.awssdk:sqs](https://aws.amazon.com/sdkforjava) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.23` -> `2.32.24` |
| [software.amazon.awssdk:regions](https://aws.amazon.com/sdkforjava) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.23` -> `2.32.24` |
|
[software.amazon.awssdk:dynamodb-enhanced](https://aws.amazon.com/sdkforjava)
| dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.23` -> `2.32.24` |
| [software.amazon.awssdk:dynamodb](https://aws.amazon.com/sdkforjava) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.23` -> `2.32.24` |
| [software.amazon.awssdk:aws-core](https://aws.amazon.com/sdkforjava) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.23` -> `2.32.24` |
| [software.amazon.awssdk:bom](https://aws.amazon.com/sdkforjava) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.23` -> `2.32.24` |
| [software.amazon.awssdk:auth](https://aws.amazon.com/sdkforjava) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.23` -> `2.32.24` |

---

### Release Notes

<details>
<summary>modelcontextprotocol/kotlin-sdk
(io.modelcontextprotocol:kotlin-sdk)</summary>

###
[`v0.6.0`](https://github.com/modelcontextprotocol/kotlin-sdk/releases/tag/0.6.0)

[Compare
Source](modelcontextprotocol/kotlin-sdk@0.5.0...0.6.0)

#### What's Changed

- Update jreleaser to fix publication issue by
[@&#8203;e5l](https://github.com/e5l) in
modelcontextprotocol/kotlin-sdk#91
- Disable configuration cache to fix jreleaser issue by
[@&#8203;e5l](https://github.com/e5l) in
modelcontextprotocol/kotlin-sdk#92
- feat: Add audio type according to 2025-03-26 spec by
[@&#8203;SeanChinJunKai](https://github.com/SeanChinJunKai) in
modelcontextprotocol/kotlin-sdk#68
- fix(client): serialize inputSchema as input\_schema by
[@&#8203;shiqicao](https://github.com/shiqicao) in
modelcontextprotocol/kotlin-sdk#97
- fix(client) add encodeDefault for field with non spec default value by
[@&#8203;shiqicao](https://github.com/shiqicao) in
modelcontextprotocol/kotlin-sdk#99
- Make McpJson public to allow flexible protocol development by
[@&#8203;parnurzeal](https://github.com/parnurzeal) in
modelcontextprotocol/kotlin-sdk#103
- fix: apply `requestBuilder` headers when sending rpc messages by
[@&#8203;dead8309](https://github.com/dead8309) in
modelcontextprotocol/kotlin-sdk#96
- fix: Remove [@&#8203;SerialName](https://github.com/SerialName)
annotation for inputSchema by
[@&#8203;adamglin0](https://github.com/adamglin0) in
modelcontextprotocol/kotlin-sdk#105
- add ios and wasm targets by
[@&#8203;devcrocod](https://github.com/devcrocod) in
modelcontextprotocol/kotlin-sdk#81
- Add dependabot by [@&#8203;StefMa](https://github.com/StefMa) in
modelcontextprotocol/kotlin-sdk#121
- Bump org.jetbrains.kotlinx:kotlinx-serialization-json from 1.7.3 to
1.8.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in
modelcontextprotocol/kotlin-sdk#127
- Bump io.github.oshai:kotlin-logging from 7.0.0 to 7.0.7 by
[@&#8203;dependabot](https://github.com/dependabot)\[bot] in
modelcontextprotocol/kotlin-sdk#126
- Bump org.jetbrains.kotlinx.binary-compatibility-validator from 0.17.0
to 0.18.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot]
in modelcontextprotocol/kotlin-sdk#125
- update kotlin to 2.2.0 and ktor to 3.1.3 by
[@&#8203;devcrocod](https://github.com/devcrocod) in
modelcontextprotocol/kotlin-sdk#120
- Add client roots addition/removal API and listRoots handler by
[@&#8203;ptitjes](https://github.com/ptitjes) in
modelcontextprotocol/kotlin-sdk#118
- Bump org.slf4j:slf4j-simple from 2.0.16 to 2.0.17 by
[@&#8203;dependabot](https://github.com/dependabot)\[bot] in
modelcontextprotocol/kotlin-sdk#131
- Bump org.jetbrains.kotlinx:kotlinx-serialization-json from 1.8.1 to
1.9.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in
modelcontextprotocol/kotlin-sdk#132
- Bump io.mockk:mockk from 1.13.13 to 1.14.4 by
[@&#8203;dependabot](https://github.com/dependabot)\[bot] in
modelcontextprotocol/kotlin-sdk#133
- Remove fixed suffix /sse by
[@&#8203;adamglin0](https://github.com/adamglin0) in
modelcontextprotocol/kotlin-sdk#108
- sse server does not process endpoint correctly when sse path is not a
directory by [@&#8203;shendaxia-sm](https://github.com/shendaxia-sm) in
modelcontextprotocol/kotlin-sdk#43
- Add labels to dependabot configuration for Kotlin and GitHub Actions
by [@&#8203;devcrocod](https://github.com/devcrocod) in
modelcontextprotocol/kotlin-sdk#135
- feat: add tool annotations according to 2025-03-26 spec by
[@&#8203;SeanChinJunKai](https://github.com/SeanChinJunKai) in
modelcontextprotocol/kotlin-sdk#71
- Bump ktor from 3.1.3 to 3.2.1 by
[@&#8203;dependabot](https://github.com/dependabot)\[bot] in
modelcontextprotocol/kotlin-sdk#140
- Bump gradle/actions from 4.0.0 to 4.4.1 by
[@&#8203;dependabot](https://github.com/dependabot)\[bot] in
modelcontextprotocol/kotlin-sdk#122
- Bump org.jreleaser from 1.17.0 to 1.19.0 by
[@&#8203;dependabot](https://github.com/dependabot)\[bot] in
modelcontextprotocol/kotlin-sdk#141
- refactor `SseClientTransport` by
[@&#8203;devcrocod](https://github.com/devcrocod) in
modelcontextprotocol/kotlin-sdk#142
- atomic and persistent collections for thread safety by
[@&#8203;devcrocod](https://github.com/devcrocod) in
modelcontextprotocol/kotlin-sdk#143
- Bump org.gradle.toolchains.foojay-resolver-convention from 0.8.0 to
1.0.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in
modelcontextprotocol/kotlin-sdk#130
- Add support for elicitation by
[@&#8203;ptitjes](https://github.com/ptitjes) in
modelcontextprotocol/kotlin-sdk#138
- Add support for tool structured content and output schema by
[@&#8203;ptitjes](https://github.com/ptitjes) in
modelcontextprotocol/kotlin-sdk#146
- Add streamable http client transport by
[@&#8203;devcrocod](https://github.com/devcrocod) in
modelcontextprotocol/kotlin-sdk#147
- Refactor JSON processing to exclude "method" in serialization by
[@&#8203;devcrocod](https://github.com/devcrocod) in
[#&#8203;157](modelcontextprotocol/kotlin-sdk#157)
- Release 0.6.0 by [@&#8203;devcrocod](https://github.com/devcrocod) in
modelcontextprotocol/kotlin-sdk#149

#### New Contributors

- [@&#8203;shiqicao](https://github.com/shiqicao) made their first
contribution in
modelcontextprotocol/kotlin-sdk#97
- [@&#8203;parnurzeal](https://github.com/parnurzeal) made their first
contribution in
modelcontextprotocol/kotlin-sdk#103
- [@&#8203;dead8309](https://github.com/dead8309) made their first
contribution in
modelcontextprotocol/kotlin-sdk#96
- [@&#8203;adamglin0](https://github.com/adamglin0) made their first
contribution in
modelcontextprotocol/kotlin-sdk#105
- [@&#8203;StefMa](https://github.com/StefMa) made their first
contribution in
modelcontextprotocol/kotlin-sdk#121
- [@&#8203;dependabot](https://github.com/dependabot)\[bot] made their
first contribution in
modelcontextprotocol/kotlin-sdk#127
- [@&#8203;ptitjes](https://github.com/ptitjes) made their first
contribution in
modelcontextprotocol/kotlin-sdk#118
- [@&#8203;shendaxia-sm](https://github.com/shendaxia-sm) made their
first contribution in
modelcontextprotocol/kotlin-sdk#43

**Full Changelog**:
modelcontextprotocol/kotlin-sdk@0.5.0...0.6.0

</details>

<details>
<summary>Kotlin/kotlinx.serialization
(org.jetbrains.kotlinx:kotlinx-serialization-json)</summary>

###
[`v1.9.0`](https://github.com/Kotlin/kotlinx.serialization/blob/HEAD/CHANGELOG.md#190--2025-06-27)

\==================

This release updates Kotlin version to 2.2.0, includes several bugfixes
and provides serializers for kotlin.time.Instant.

#### Add kotlin.time.Instant serializers

Instant class was moved from kotlinx-datetime library to Kotlin standard
library.
As a result, kotlinx-datetime 0.7.0 no longer has serializers for the
Instant class.
To use new kotlin.time.Instant class in your
[@&#8203;Serializable](https://github.com/Serializable) classes,
you can use this 1.9.0 kotlinx-serialization version (Kotlin 2.2 is
required).
You can choose between default `InstantSerializer` which uses its string
representation,
or specify `InstantComponentSerializer` that represents instant as its
components.
See details in the
[PR](Kotlin/kotlinx.serialization#2945).

#### Other bugfixes

- Fix resize in JsonPath
([#&#8203;2995](Kotlin/kotlinx.serialization#2995))
- Fixed proguard rules for obfuscation to work correctly
([#&#8203;2983](Kotlin/kotlinx.serialization#2983))

###
[`v1.8.1`](https://github.com/Kotlin/kotlinx.serialization/blob/HEAD/CHANGELOG.md#181--2025-03-31)

\==================

This release updates Kotlin version to 2.1.20, while also providing
several important improvements
and bugfixes.

#### Improvements

- Implemented encoding null in key and value of a map in Protobuf
([#&#8203;2910](Kotlin/kotlinx.serialization#2910))
- Make type argument in JsonTransformingSerializer nullable
([#&#8203;2911](Kotlin/kotlinx.serialization#2911))
- Use SPDX identifier in POMs
([#&#8203;2936](Kotlin/kotlinx.serialization#2936))
(thanks to [Leon Linhart](https://github.com/TheMrMilchmann))
- Add watchosDeviceArm64 to Okio integration module
([#&#8203;2920](Kotlin/kotlinx.serialization#2920))
(thanks to [Daniel Santiago](https://github.com/danysantiago))
- Update kotlinx-io version to 0.6.0
([#&#8203;2933](Kotlin/kotlinx.serialization#2933))
(thanks to [Piotr Krzemiński](https://github.com/krzema12))

#### Bugfixes

- Fix incorrect enum coercion during deserialization from JsonElement
([#&#8203;2962](Kotlin/kotlinx.serialization#2962))
- Supply proper equals(), hashCode(), and toString() for
SerialDescriptor() wrapper
([#&#8203;2942](Kotlin/kotlinx.serialization#2942))
- Do not encode empty packed collections in protobuf
([#&#8203;2907](Kotlin/kotlinx.serialization#2907))

###
[`v1.8.0`](https://github.com/Kotlin/kotlinx.serialization/blob/HEAD/CHANGELOG.md#180--2025-01-06)

\==================

This release contains all of the changes from 1.8.0-RC. Kotlin 2.1.0 is
used as a default, while upcoming 2.1.10 is also supported.
Also added small bugfixes, including speedup of ProtoWireType.from
([#&#8203;2879](Kotlin/kotlinx.serialization#2879)).

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "after 6pm every weekday,before 2am
every weekday" in timezone Australia/Melbourne, Automerge - At any time
(no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Never, or you tick the rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://github.com/renovatebot/renovate).

GitOrigin-RevId: 40e2f07ecd958e92e64c571d1351e91f96e71ce7
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.

2 participants