Introducing MCP 7-28 for AI Application Developers: What Goes Away, and What Might Break The MCP 7-28 specification revision, expected July 28, 2026, deprecates Roots, Sampling, and protocol-level Logging while moving to a stateless, sessionless architecture with explicit state handles. The update strengthens HTTP authorization, standardizes tool contracts on JSON Schema 2020-12, and requires most lookup-style MCP servers to make modest updates, but servers relying on sessions, filesystem Roots, browser state, or remote HTTP deployments need broader migration planning. Junghwan Park 9bow is an AAIF Ambassador, a PyTorch Ambassador, and the lead maintainer of the PyTorch Korea User Group PyTorchKR . A Korean version of this post is available here. TL;DR: MCP 7-28 is less about new features than simplifying and hardening the protocol for production use. The release deprecates Roots, Sampling, and protocol-level Logging, moves MCP to a stateless, sessionless architecture that replaces implicit session state with explicit state handles, strengthens HTTP authorization, and standardizes tool contracts on JSON Schema 2020-12. Most lookup-style MCP servers will require only modest updates, while servers that depend on sessions, filesystem Roots, browser state, long-running workflows, or remote HTTP deployments should plan for a broader architectural review and migration. Disclaimer: ‘MCP 7-28’ is a working name for the MCP specification changes expected to be published around July 28, 2026. The SEPs Specification Enhancement Proposals cited in this post SEP-2577, SEP-2575, SEP-2567, SEP-1613, SEP-2106, and others have already reached Final status, but the official specification revision that incorporates them has not yet been finalized as of this writing. It is currently published as a Release Candidate locked May 21, 2026; see the official RC announcement ; 2025-11-25 remains the latest finalized revision, and 2026-07-28 is scheduled to ship as final on July 28, 2026. Dates, exact wording, and any “planned/incorporated/finalized” phrasing in this post should therefore be re-verified against the official MCP specification, release notes, and SDK changelogs once the revision actually ships. Introduction to MCP and Why It Matters The PyTorch Korea User Group PyTorchKR https://pytorch.kr/ covers not only training and inference with PyTorch, but also everything it takes to put those models to work in real services outside the lab. Curating and sharing the latest news, open-source projects, and notable papers and research trends on the PyTorchKR community forum https://discuss.pytorch.kr/ comes from the same motivation. Training a model well and making that model genuinely useful inside a product are no longer things we can think about separately. Models are increasingly used together with agents and external tools, and MCP Model Context Protocol is one of the standardized touchpoints in that connection layer. For a large language model LLM to be useful in the real world, the model alone is not enough. It needs channels to the real world: reading files, querying databases, searching the documents a user cares about, calling external APIs. MCP is an open protocol that standardizes exactly that channel: instead of building a bespoke integration for every tool, you connect models to external tools, data, and execution environments through one shared contract. This is why tools like Claude Desktop, Cursor, and VS Code all follow the same MCP client specification. How MCP Model Context Protocol Works graph TB subgraph "MCP Host AI application " Client1 "MCP Client 1" Client2 "MCP Client 2" Client3 "MCP Client 3" Client4 "MCP Client 4" end ServerA "MCP Server A local; e.g., filesystem " ServerB "MCP Server B local; e.g., database " ServerC "MCP Server C remote; e.g., Sentry " Client1 ---|"dedicated connection"| ServerA Client2 ---|"dedicated connection"| ServerB Client3 ---|"dedicated connection"| ServerC Client4 ---|"dedicated connection"| ServerC MCP is easiest to understand in terms of three participants: the host, the server, and the client. The LLM application the user directly interacts with, such as Claude Desktop or Cursor, is the host; the connector inside the host that maintains a 1:1 connection with a single server is the client; and the side that actually provides tools and data is the server. These three participants exchange requests and responses as JSON-RPC 2.0 https://www.jsonrpc.org/specification messages. As of this writing, the latest MCP specification is the November 25, 2025 revision https://modelcontextprotocol.io/specification/2025-11-25 . An MCP server exposes what it can do to the client. It advertises three kinds of building blocks: - Tools: functions the model invokes to perform real actions e.g., search, file reads, external API calls . - Resources: data provided to the model as context e.g., files, documents, records . - Prompts: reusable prompt templates. Servers and clients generally connect over one of two transports: 1 For MCP servers run locally, the host launches the server as a subprocess and exchanges messages over standard input and output stdin/stdout , using the stdio transport. sequenceDiagram participant Client participant SP as Server Process Client- +SP: Launch subprocess loop Message Exchange Client- SP: Write to stdin SP- Client: Write to stdout SP-- Client: Optional logs on stderr end Client- SP: Close stdin, terminate subprocess deactivate SP 2 For MCP servers running remotely, messages are exchanged over the HTTP-based Streamable HTTP https://modelcontextprotocol.io/specification/2025-11-25/basic/transports streamable-http transport. Under the currently published spec 2025-11-25 https://modelcontextprotocol.io/specification/2025-11-25 , the client and server exchange versions and capabilities in an initialization initialize step at the start of the connection, then continue subsequent requests and responses on top of the established session. sequenceDiagram participant Client participant Server note over Client, Server: initialization Client- +Server: POST InitializeRequest Server- -Client: InitializeResponse MCP-Session-Id: 1868a90c... Client- +Server: POST InitializedNotification MCP-Session-Id: 1868a90c... Server- -Client: 202 Accepted note over Client, Server: client requests Client- +Server: POST ... request ... MCP-Session-Id: 1868a90c... alt single HTTP response Server- Client: ... response ... else server opens SSE stream loop while connection remains open Server- Client: ... SSE messages from server ... end Server- Client: SSE event: ... response ... end deactivate Server note over Client, Server: client notifications/responses Client- +Server: POST ... notification/response ... MCP-Session-Id: 1868a90c... Server- -Client: 202 Accepted note over Client, Server: server requests Client- +Server: GET MCP-Session-Id: 1868a90c... loop while connection remains open Server- Client: ... SSE messages from server ... end deactivate Server Much of what changes in ‘MCP 7-28’, the subject of this post, is precisely about revisiting the assumptions baked into how these connections are established handshake and maintained session . If you want more background on MCP concepts and architecture, the PyTorchKR community’s Deep Research: Model Context Protocol MCP study material https://discuss.pytorch.kr/t/deep-research-model-context-protocol-mcp/6594 is a good starting point. Introducing the Next MCP Standard: MCP 7-28 ‘MCP 7-28’ is the working name for the next MCP specification revision, expected to land around July 28, 2026. Rather than adding new features, this release is closer to a migration-focused one. The core idea is to keep MCP’s Core Protocol smaller and clearer while cleaning up state management, authorization, schemas, and the lifecycle of several existing features. So the first thing to look at in this revision is ‘what goes away, and what might break’. Anyone who has built and operated MCP servers in production runs into questions like these: - Which tools can the model see? - Against which schema are tool-call arguments validated? - Where is state stored between one tool call and the next? - Who decides access to external resources like files, browsers, databases, and document search? - How does an MCP server exposed over HTTP validate tokens, scopes, and audiences? - Should observability live in protocol-level logging, or in application logs and traces? The major changes in MCP 7-28 map directly onto these questions, and they fall into two broad groups: - What goes away Deprecation : Roots, Sampling, and Logging are marked deprecated in the core protocol SEP-2577 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2577-deprecate-roots-sampling-and-logging.md . These features do not disappear immediately, but new development should stop relying on them. - What might break Breaking Change : the protocol moves stateless-first SEP-2575 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2575-stateless-mcp.md , the protocol-level session is removed in favor of surfacing state as explicit handles SEP-2567 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2567-sessionless-mcp.md , and the authorization baseline for the HTTP transport is hardened. On top of that, tool schemas are aligned with JSON Schema 2020-12, resetting the baseline for tool contracts SEP-1613 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/1613-establish-json-schema-2020-12-as-default-dialect-f.md , SEP-2106 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2106-json-schema-2020-12.md . This post focuses less on the upgrade steps for any particular SDK, and more on what to audit when you operate MCP servers as the tooling infrastructure of an LLM application. For the rest of the post, we walk through each change in the same order: ① what the feature originally was → ② what changes and how → ③ how it lands in your code and configuration → ④ what you gain as a result. We first sort out the concepts, then close with real MCP server case studies and a migration checklist. Operational topics such as routing headers, list caching, trace propagation, and the Tasks extension are out of scope here and will be covered separately in a follow-up series https://discuss.pytorch.kr/ . MCP 7-28 changes covered in this post, at a glance | Checklist item | Direction of change | Question to ask | | Roots | Deprecated | Do you rely on roots/list for workspace/filesystem access boundaries? | | Sampling | Deprecated | Does your MCP server ask the client/host to generate LLM completions? | | Logging | Deprecated | Do you depend on MCP protocol logging for operational logs and observability? | | Stateless/sessionless | Protocol-level session state removed; state becomes explicit handles | Can each request be understood without a prior handshake/session? Is state referenced by explicit IDs? | | HTTP authorization | Hardened security baseline for the HTTP transport | Do you validate bearer tokens, resource indicators, scopes, and audiences? | | JSON Schema 2020-12 | Tool contract baseline cleaned up | Do inputSchema, outputSchema, and structuredContent conform to the new baseline? | What Goes Away Deprecation : Roots, Sampling, Logging SEP-2577 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2577-deprecate-roots-sampling-and-logging.md designates Roots, Sampling, and Logging as deprecated in the core protocol. Deprecation does not mean immediate removal. SEP-2577 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2577-deprecate-roots-sampling-and-logging.md explains that during the deprecation period, wire-level behavior does not change, and neither the types nor capability negotiation are removed. So the accurate reading is not ‘this breaks today’ but ‘stop using these in new MCP implementations’. Roots What it originally was: Roots lets a client tell a server which local directories and file boundaries it may access. For servers that touch the local filesystem, like the filesystem MCP server https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem , access boundaries matter, and a server could query the client-provided boundaries via roots/list. What changes and how: SEP-2577 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2577-deprecate-roots-sampling-and-logging.md views Roots not as an actual access-control mechanism but as informational guidance. From that viewpoint, the MCP protocol does not confine the server to those paths, so assuming ‘this path is inside the client-sent Roots, therefore it is safe’ blurs the security boundary. The proposal instead recommends conveying access scope through more explicit means: tool parameters, resource URIs, server configuration, or environment variables. How it lands in code/configuration: from a migration standpoint, check the following: - Does the MCP server accept its allowed paths as launch arguments? - Can an allowlist be set via a configuration file or environment variables? - Is access scope made explicit in tool parameters or resource URIs? - Is filesystem policy enforced at the host, gateway, or sandbox layer? - Does the server only behave correctly when roots/list results change? What you gain: you move away from the structure where, within each session, the server dynamically trusts whatever Roots the client advertised. Access policy becomes decidable from the request and the server configuration alone. As a result, the security boundary stops being a protocol-level hint and becomes a policy the MCP server itself enforces. Sampling What it originally was: Sampling lets an MCP server request an LLM completion from the client or host. With it, a server could use the model connected to the client even without its own LLM integration or API key. What changes and how: Sampling is powerful, but it blurs the boundary of responsibility. It becomes ambiguous whether the server is a simple tool provider or an orchestrator directing model invocations. Responsibility for choosing which model to call, handling the user-approval UI, managing cost and policy, and defending against prompt injection inside the tool loop can end up in a gray zone between server and client. For these reasons, SEP-2577 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2577-deprecate-roots-sampling-and-logging.md deprecates Sampling and suggests alternatives such as calling an LLM provider API directly when a server genuinely needs completions. How it lands in code/configuration: the direction for reducing a server’s dependence on the model looks like this: - The MCP server returns the necessary context, candidate prompts, and structured results. - Model invocation happens in the MCP host, the agent runtime, or the application layer. - Long-running workflow orchestration is managed by a separate agent runtime or job queue. - If the server truly needs its own LLM, it integrates a provider API directly and surfaces that fact in its tool contract and operational policy. What you gain: the default role of an MCP server shifts from ‘go invoke the model’ toward ‘reliably provide the tools and data the model reasons over’. Responsibility boundaries become clear, and risk surfaces like prompt injection and data exfiltration become easier to manage. Logging What it originally was: Logging lets an MCP server deliver structured logs to the MCP client via protocol messages notifications/message , with the client able to adjust logging verbosity. What changes and how: deprecating Logging does not mean ‘stop logging’. It means: do not entrust operational observability to Logging, a protocol feature. SEP-2577 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2577-deprecate-roots-sampling-and-logging.md itself recommends https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2577-deprecate-roots-sampling-and-logging.md logging leaning on mature, existing logging/observability infrastructure such as standard error stderr or OpenTelemetry https://github.com/open-telemetry . How it lands in code/configuration: in production, apply setups like the following: - Locally run MCP servers use a standard logger and standard error stderr . - Remote, HTTP-based MCP servers keep request logs, audit logs, and trace IDs. - Tool calls, retrieval, external API calls, and model calls are tied together as OpenTelemetry traces. - Responsibilities of protocol messages and application logs are kept separate. What you gain: in an AI application, a single user request mixes retrieval, tool calls, model calls, and external API calls. An end-to-end trace is far more useful than protocol logging alone. How reference MCP servers from the official MCP repository https://github.com/modelcontextprotocol/servers , such as filesystem https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem and memory https://github.com/modelcontextprotocol/servers/tree/main/src/memory , are affected is covered later in this post. What Might Break Breaking Change : Stateless/Sessionless, HTTP Authorization, JSON Schema 2020-12 Stateless/Sessionless What the structure originally was: the current MCP standard https://modelcontextprotocol.io/specification/2025-11-25 depends in places on the initialize handshake and connection/session state. The client and server exchange versions and capabilities at the start of a connection; once the server issues a session ID MCP-Session-Id , every subsequent request must carry it in a header. Managing state on top of a pinned session like this was fine for a single local process, but became an obstacle at scale. What changes and how: first, SEP-2575 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2575-stateless-mcp.md proposes a stateless-first direction. If an HTTP-based remote MCP server sits behind a load balancer or runs across multiple nodes, a given client session gets pinned to the in-memory state of whichever server it first connected to, forcing sticky sessions, session stores, resumption, and failover. To fix this, SEP-2575 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2575-stateless-mcp.md proposes: - Requests should be as self-contained as possible. - The protocol version and client capabilities travel as per-request metadata on every request. - An MCP server can advertise its supported versions and capabilities via server/discover. - Server designs that can only process the current request by remembering a previous one should be avoided. On top of this, SEP-2567 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2567-sessionless-mcp.md pushes further toward a sessionless direction: it removes the protocol-level session concept entirely, and where application state is needed, it is passed around as explicit state handles in tool results and arguments. How it lands in code/configuration: to see what stateless/sessionless means in practice, imagine an MCP server that serves search results. State like a search session is treated as an explicit handle: Create a new search, returning a state handle for it e.g., srch 7f3a 1. create search query="MCP Roots deprecation" - { "search handle": "srch 7f3a" } Request the next page of results, passing the earlier handle srch 7f3a 2. get search page search handle="srch 7f3a", page=2 - { "items": ... } When done, pass the handle srch 7f3a to close the search 3. close search search handle="srch 7f3a" - { "closed": true } Even under the stateless/sessionless assumption, state can still live on the server. What changes is that the state is no longer bound to a prior session; it is expressed as an explicit value, search handle. SEP-2567 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2567-sessionless-mcp.md describes this not as a new protocol primitive but as a tool-design pattern. Each handle is just a string inside a tool result, passed back as an argument on later calls. For good handle design, refer to the SEP’s guidance for servers https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2567-sessionless-mcp.md guidance-for-servers : use opaque values, validate handle, auth context on every call, and make expiry/cleanup policies explicit. What you gain: client requests can be routed to any server node. Horizontal scale-out becomes easy, state no longer vanishes with a failed node, and caching of list results such as tools/list becomes straightforward. This change has significant impact on MCP servers that must manage state across requests, including browser automation, shopping carts, payment flows, long-running jobs, and DB transactions. But lookup-style MCP servers that take search criteria on every call and return results are unlikely to conflict with it. The precise meaning of the stateless core, handle design for search sessions / long-running jobs / browser contexts, session independence of tools/list, and the Tasks Extension of SEP-2663 https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md will be covered in a follow-up post. HTTP Authorization What the structure originally was: for local MCP servers, an MCP host like Claude Desktop or Cursor launches the server directly as a subprocess. In that setting, it is hard for the MCP protocol to determine who is using the server and how far they may reach. The trust boundary is already ‘whoever is using the MCP host’, so MCP had little need for its own authentication or authorization layer. In other words, when MCP servers were used to wire tools inside an LLM application, it was easy to treat authorization as something to bolt on later. What changes and how: the MCP authorization draft https://modelcontextprotocol.io/specification/draft/basic/authorization defines the authorization flow for HTTP-based transports. Authorization remains optional in MCP implementations, but if an HTTP-based transport supports authorization, following this specification is recommended. For local stdio transports, the draft advises using local credential delivery, such as environment variables, instead of this flow. Running legalize-mcp locally inside Claude Desktop or Cursor and exposing an HTTP-based remote MCP server to the internet involve different threat models. sequenceDiagram participant B as User-Agent Browser participant C as Client participant M as MCP Server Resource Server participant A as Authorization Server C- M: MCP request without token M- C: HTTP 401 Unauthorized with WWW-Authenticate header Note over C: Extract resource metadata URL from WWW-Authenticate C- M: Request Protected Resource Metadata M- C: Return metadata Note over C: Parse metadata and extract authorization server s Client determines AS to use C- A: GET Authorization server metadata endpoint Note over C,A: Try OAuth 2.0 and OpenID Connect discovery endpoints in priority order A-- C: Authorization server metadata alt Client ID Metadata Documents Note over C: Client uses HTTPS URL as client id Note over A: Server detects URL-formatted client id A- C: Fetch metadata from client id URL C-- A: JSON metadata document Note over A: Validate metadata and redirect uris else Dynamic client registration C- A: POST /register A- C: Client Credentials else Pre-registered client Note over C: Use existing client id end Note over C: Generate PKCE parameters Include resource parameter Apply scope selection strategy Record expected issuer C- B: Open browser with authorization URL + code challenge + resource B- A: Authorization request with resource parameter Note over A: User authorizes A- B: Redirect to callback with authorization code + iss B- C: Authorization code callback Note over C: Validate iss against recorded issuer RFC 9207 C- A: Token request + code verifier + resource A- C: Access token + refresh token C- M: MCP request with access token M-- C: MCP response Note over C,M: MCP communication continues with valid token How it lands in code/configuration: for HTTP-based remote MCP servers, verify the following: - Does every HTTP request carry an Authorization: Bearer