Skip to content

Upgrading to the new MCP Protocol Specification 2026-07-28 #204

Description

@tomncooper

Summary

The new version of the MCP specification (2026-07-28) is being released on July 28th 2026. This is going to be the most significant protocol revision to date, introducing a stateless communication model and deprecating several features we rely on heavily in the MCP server.

I didn't see another Issue/PR covering the protocol changes, so I put this issue together to track the impact on our server implementation and the work we would need to do to stay current with the protocol.

Protocol changes

Below are the headline changes in the new protocol:

Stateless protocol model

The protocol is moving to a stateless request/response model. The initialize/initialized handshake and Mcp-Session-Id header are removed. Each request now carries its protocol version and client capabilities in _meta fields (io.modelcontextprotocol/protocolVersion, io.modelcontextprotocol/clientCapabilities). A new server/discover RPC replaces the initialization handshake for capability advertisement.

Multi Round-Trip Requests (MRTR) replace server-initiated requests

This is probably the most architecturally significant change. Previously, a server could send requests back to the client mid-execution (Sampling, Elicitation, Roots). In the new model, the server returns an InputRequiredResult with resultType: "input_required" containing inputRequests and an opaque requestState. The client processes the requests and re-invokes the original tool with inputResponses and requestState. This turns what was a synchronous mid-execution call into a multi-round-trip exchange.

Deprecated features (12+ month removal window)

  • Sampling (sampling/createMessage): We will need to migrate to MRTR or integrate directly with LLM provider APIs
  • Elicitation (elicitation/create): We will need to migrate to MRTR
  • Roots (roots/list): We will have to pass directories/files via tool parameters or server configuration instead
  • Logging (logging/setLevel): The log level is now per-request via _meta. We will need to migrate to logging via stderr/OpenTelemetry.

The old protocol features will remain fully functional during the deprecation window, but new implementations should not adopt them.

Resource subscriptions are reworked

resources/subscribe and resources/unsubscribe are replaced by subscriptions/listen, a single long-lived POST stream where clients opt in to specific notification types (toolsListChanged, promptsListChanged, resourcesListChanged, resourceSubscriptions).

New required fields on all results

  • resultType (string, required): "complete" for normal results, "input_required" for MRTR interim results
  • ttlMs (integer, required on list/read results): cache freshness hint in milliseconds
  • cacheScope ("public" | "private", required on list/read results): controls intermediary caching

Other changes

  • ping RPC is removed
  • logging/setLevel RPC is removed
  • Deterministic tool ordering is recommended for tools/list responses (improves LLM prompt cache hit rates)
  • New Mcp-Method and Mcp-Name headers are required on Streamable HTTP POST requests
  • Error code renumbering (HeaderMismatch -32001 to -32020, UnsupportedProtocolVersion -32004 to -32022, etc.)
  • inputSchema/outputSchema loosened to allow any JSON Schema 2020-12 keywords
  • Tools, prompts, resources can now carry an icons array

Impact on our MCP Server

What should be handled by Quarkus

The quarkus-mcp-server extension handles transport and protocol-level concerns. The 2.0.0.Beta3 release already supports both stateful (2025-11-25) and stateless (2026-07-28) MCP clients simultaneously on the same endpoint. It looks like the following changes should be absorbed by the framework with no code changes required in this project:

  • initialize/initialized removal and server/discover implementation
  • Session removal and stateless client detection
  • ping removal
  • Per-request _meta for protocol version, capabilities, and client info
  • resultType on all results
  • ttlMs and cacheScope on list/read results
  • Transport-level header changes
  • Error code renumbering

Sampling

Our MCP server uses Sampling extensively in all diagnostic services via BaseDiagnosticService.performSampling(), performTriage(), and performAnalysis(). The pattern is a multi-step workflow where the tool calls the LLM mid-execution to guide investigation:

  1. Gather initial cluster data
  2. Send data to LLM via Sampling for triage (which areas to investigate deeper)
  3. Gather additional data based on triage results
  4. Send all data to LLM via Sampling for root cause analysis

Affected services: KafkaClusterDiagnosticService, KafkaConnectivityDiagnosticService, KafkaMetricsDiagnosticService, KafkaConfigComparisonService, UpgradeReadinessDiagnosticService, KafkaConnectDiagnosticService, KafkaConnectorDiagnosticService, KafkaMirrorMaker2DiagnosticService, KafkaTopicDiagnosticService, OperatorMetricsDiagnosticService

The MRTR replacement fundamentally changes this execution model. Each Sampling call would become a tool return/re-invocation cycle, meaning the diagnostic workflow needs to be resumable across multiple invocations using the requestState continuation token. This is probably going to be the largest piece of migration work.

Note: the quarkus-mcp-server 2.0 beta does not yet implement MRTR for Sampling. Stateless clients simply cannot use Sampling in the current beta. We need to track when MRTR support lands in the framework, as it will determine the API we needs to code against.

Elicitation

Used for namespace disambiguation via NamespaceElicitationHelper and time-window expansion in diagnostic workflows. Same MRTR migration path as Sampling. Affected in the same set of diagnostic services listed above.

McpLog / Logging

McpLog is used throughout diagnostic services and tool classes for real-time user feedback (mcpLog.info("Gathering cluster status...")). The logging/setLevel removal looks to be handled by Quarkus and notifications/message should continue to work during the deprecation window. Long-term we should consider moving user feedback to Progress notifications (not deprecated) and operational logging to OpenTelemetry/stderr.

Resource subscriptions

ResourceSubscriptionManager manages Kubernetes watches and delivers notifications/resources/updated via the framework's ResourceManager API. The migration from resources/subscribe to subscriptions/listen should be handled by Quarkus, but we need to verify the ResourceManager API still works as expected after upgrading.

Action items

Near-term

  • Track quarkus-mcp-server 2.0 releases for GA readiness
  • When 2.0 goes GA, upgrade from 1.13.1. Key breaking changes in the upgrade: mcp-server-api bumped to 1.0.0-Beta4, McpProtocolVersion changed from enum to final class, JSON-RPC batching removed
  • After upgrading, verify ResourceSubscriptionManager works correctly with the new framework internals and subscriptions/listen
  • Verify all existing tools, prompts, and resource templates work for both stateful and stateless clients

Medium-term

  • Track MRTR implementation in quarkus-mcp-server (not yet available in 2.0.0.Beta3)
  • When MRTR lands, evaluate the framework-level API and plan the diagnostic service refactoring
  • Consider migrating McpLog user feedback to Progress notifications where appropriate
  • Evaluate deterministic tool ordering for tools/list responses

Before deprecation window closes (~mid-2027)

  • Migrate all Sampling usage in diagnostic services to MRTR
  • Migrate all Elicitation usage to MRTR
  • Migrate remaining McpLog usage to Progress/OpenTelemetry/stderr
  • Remove any remaining references to deprecated features

References

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status
Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions