feat!: align model types with MCP 2025-11-25 spec#927
Merged
Conversation
08ff6bb to
e6e923b
Compare
e6e923b to
b36ce69
Compare
alexhancock
previously approved these changes
Jun 24, 2026
294f166 to
271fa02
Compare
Member
Author
|
@alexhancock I pushed one follow-up commit after your approval. I removed the unused, no-spec |
271fa02 to
ae7afa5
Compare
ae7afa5 to
9a6f182
Compare
alexhancock
approved these changes
Jun 24, 2026
9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation and Context
Over time the
rmcpmodel drifted from the MCP Schema Reference. The same content union existed in three slightly different forms (Content/RawContent,PromptMessageContent,SamplingMessageContent), many types sat behind anAnnotated<T>wrapper, several names didn't match the spec (ResourceReference,CreateElicitation*,GetTaskInfo*,PrimitiveSchema, and others), and some spec fields were missing (_metain several places,audioin prompt content). Finding the type that corresponds to a given spec construct, and knowing whether it was complete and correctly named, took real effort for SDK users and maintainers alike.We had deferred this because doing it properly is breaking, and it wasn't worth a major bump on its own. The upcoming 2026-07-28 revision changes that: it requires breaking changes regardless, so realigning the existing model to the current 2025-11-25 schema in the same major (consistent with the versioning approach in #813) avoids an extra bump and a second round of migration. It also gives the 2026-07-28 work a much cleaner baseline to build on. A full migration guide lives in discussion #926, with each type mapped to the 2025-11-25 Schema Reference.
How Has This Been Tested?
test-no-localconfiguration: compute the feature set excludinglocaland runcargo test -p rmcp --features "$FEATURES"(mirrors the CI job that the default--all-featuresrun does not cover)crates/rmcp/tests/test_message_schema/*.jsonsnapshots and cross-checked them againstschema/2025-11-25/schema.tsschema/2025-11-25/schema.ts(names, required/optional,_meta, enum literals, method strings); the fullcargo test -p rmcp --all-featuressuite passesBreaking Changes
Yes. This is a major (2.0) change. The JSON wire format is unchanged (only additive
_meta/ optional fields); the breaks are at the Rust API level: the unifiedContentBlock(flattened, no moreAnnotated<T>/Raw*), prompts usingRole+ContentBlock, spec-name renames (ResourceReferencetoResourceTemplateReference,CreateElicitation*toElicit*,PrimitiveSchematoPrimitiveSchemaDefinition,GetTaskInfo*/GetTaskResult*toGetTask*/GetTaskPayload*), most wire structs becoming#[non_exhaustive],CancelledNotificationParam.request_idbecoming optional, and the removal of the unused, non-specTaskList(useListTasksResult)._metacoverage is now complete across everyResulttype —CreateTaskResultandListRootsResultwere the last gaps. Old names are kept as#[deprecated]aliases where practical.TaskStatusNotificationParamnow modelsNotificationParams & Taskinstead of being aTaskalias; construct it withTaskStatusNotificationParam::new(task)ortask.into(), and use.taskwhere exactTaskidentity matters.ToolResultContent.contentis now required for sampling tool results, so sendcontent: []when there are no content blocks;CallToolResultstill keeps its existing missing-content compatibility behavior.Types of changes
Checklist