Title: Consistent JSON forward/backward compatibility (2.0 foundation) by chemicL · Pull Request #927 · modelcontextprotocol/java-sdk · GitHub
Open Graph Title: Consistent JSON forward/backward compatibility (2.0 foundation) by chemicL · Pull Request #927 · modelcontextprotocol/java-sdk
X Title: Consistent JSON forward/backward compatibility (2.0 foundation) by chemicL · Pull Request #927 · modelcontextprotocol/java-sdk
Description: Motivation and Context The MCP specification evolves continuously; domain types must absorb new fields and subtypes without breaking existing clients or servers. On the 1.x line this is structurally prevented by sealed interfaces, which make it impossible to add a permitted subtype without breaking exhaustive pattern-match switch expressions in caller code. This commit opens the 2.0 release line, where those constraints are lifted and serialization is made self-contained — independent of any global ObjectMapper configuration. Breaking Changes Breaking changes for users migrating from 1.x Sealed interfaces removed from JSONRPCMessage, Request, Result, Notification, ResourceContents, CompleteReference and Content. Exhaustive switch expressions over these types must add a default branch. Prompt(name, description, null) no longer silently coerces null arguments to an empty list. Use Prompt.withDefaults() to preserve the previous behaviour. CompleteCompletion.total and .hasMore are now absent from the wire when not set, rather than being emitted as null. ServerParameters no longer carries Jackson annotations; it is an internal configuration class, not a wire type. What now works that did not before CompleteReference polymorphic dispatch (PromptReference vs ResourceReference) works through a plain readValue or convertValue call — no hand-rolled map inspection required. LoggingLevel deserialization is lenient: unknown level strings produce null instead of throwing. All domain records now tolerate unknown JSON fields, so a client built against an older SDK version will not fail when a newer server sends fields it does not yet recognise. Null optional fields are consistently absent from serialized output regardless of ObjectMapper configuration. Documentation CONTRIBUTING adds an "Evolving wire-serialized records" section: a 9-rule recipe and example for adding a field safely. MIGRATION-2.0 documents all breaking changes listed above. Follow-up coming next Several spec-required fields (e.g. JSONRPCError.code/message, ProgressNotification.progress, CreateMessageRequest.maxTokens, CallToolResult.content) are stored as nullable Java types without a null guard. If constructed with null, the NON_ABSENT rule silently omits them, producing invalid wire JSON without throwing. Fix: compact canonical constructors with Assert.notNull, following the pattern already in JSONRPCRequest. 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
Open Graph Description: Motivation and Context The MCP specification evolves continuously; domain types must absorb new fields and subtypes without breaking existing clients or servers. On the 1.x line this is structurall...
X Description: Motivation and Context The MCP specification evolves continuously; domain types must absorb new fields and subtypes without breaking existing clients or servers. On the 1.x line this is structurall...
Opengraph URL: https://github.com/modelcontextprotocol/java-sdk/pull/927
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:0e7c3050-ed31-40de-290e-85b6502ce376 |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | EAB4:1C23F8:18E6EE6:2165CB8:6A5D390D |
| html-safe-nonce | 039ea6f5b51c8528f823749a4f89cb6ecab86e0a1e12a26046b6ac153cd39a65 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFQUI0OjFDMjNGODoxOEU2RUU2OjIxNjVDQjg6NkE1RDM5MEQiLCJ2aXNpdG9yX2lkIjoiNjgzOTQ4MTYzOTYzNjkwODMwMSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | f28c955922f40eca1ee1687614869ad08099bad50861344fbc19d3816f3063eb |
| hovercard-subject-tag | pull_request:3557214739 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/modelcontextprotocol/java-sdk/pull/927/files |
| twitter:image | https://avatars.githubusercontent.com/u/2554306?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/2554306?s=400&v=4 |
| og:image:alt | Motivation and Context The MCP specification evolves continuously; domain types must absorb new fields and subtypes without breaking existing clients or servers. On the 1.x line this is structurall... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 5290d7e14309ad1e76106a9c4237bd1041517e83ea182c8ab756752cb0c6940b |
| turbo-cache-control | no-preview |
| diff-view | unified |
| go-import | github.com/modelcontextprotocol/java-sdk git https://github.com/modelcontextprotocol/java-sdk.git |
| octolytics-dimension-user_id | 182288589 |
| octolytics-dimension-user_login | modelcontextprotocol |
| octolytics-dimension-repository_id | 919609219 |
| octolytics-dimension-repository_nwo | modelcontextprotocol/java-sdk |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 919609219 |
| octolytics-dimension-repository_network_root_nwo | modelcontextprotocol/java-sdk |
| turbo-body-classes | logged-out env-production page-responsive full-width |
| disable-turbo | true |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 9c975978430e9ad293956f2bbdaf153b1bd84a99 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width