Repository navigation
Python: [BREAKING] Remove deprecated MCP compatibility surfaces in vNext #9452
Copy link
Copy link
Open
Labels
breaking changeUsage: [PRs], Target: all PRs that introduce changes that are not backward compatibleUsage: [PRs], Target: all PRs that introduce changes that are not backward compatiblemcpUsage: [Issues, PRs], Target: MCPUsage: [Issues, PRs], Target: MCPpythonUsage: [Issues, PRs], Target: PythonUsage: [Issues, PRs], Target: PythonvnextUsage: [Issues, PRs], Target: breaking-change features deferred to the next major releaseUsage: [Issues, PRs], Target: breaking-change features deferred to the next major release
Description
Context
The MCP SDK 2.x migration in #9236 retained several deprecated compatibility surfaces so existing applications could move forward without an immediate second breaking change. PR #9237 documents the final high-level Client versus low-level ClientSession ownership boundary and formalizes the remaining low-level paths as deprecated.
This issue tracks removing those compatibility surfaces in the next major release. It is an API cleanup issue, not a request to remove supported legacy MCP peer/protocol behavior. Legacy negotiation and wire compatibility should remain unless separately deprecated.
The current MCP Tasks extension should be designed independently in #9215 rather than reviving the removed pre-2.x task implementation.
Removal checklist
Caller-supplied low-level session path
- Remove the
session: ClientSession | Noneconstructor parameter fromMCPTool,MCPStdioTool, andMCPStreamableHTTPTool. - Remove
_SessionMCPConnectionand all direct-operation routing through caller-suppliedClientSessionobjects. - Remove
MCPTool.sessionand its setter; framework-owned and caller-owned high-levelClientconnections must continue to route operations throughClient. - Remove low-level-session initialization, ownership, reconnect, header-identity, cleanup, and compatibility branches that become unreachable.
- Remove or migrate tests that exercise unnegotiated, caller-owned, caller-replaced, or directly mocked
ClientSessionconnections. - Update skills, Declarative, Foundry Toolbox, security helpers, and other integrations that read or assign
MCPTool.sessionto use the normalized high-level connection/operation seam. - Remove low-level session examples and documentation from API references, docstrings, ADRs, and contributor guidance.
Removed Tasks API compatibility
- Remove the deprecated
MCPTaskOptionscompatibility class. - Remove
MCPTaskOptionsfrom root lazy exports,__all__, andagent_framework/__init__.pyi. - Remove the ignored
task_optionsparameter fromMCPTool,MCPStdioTool,MCPStreamableHTTPTool, and any remaining compatibility constructors. - Remove the associated deprecation warnings, docstrings, typing suppressions, and compatibility tests.
- Confirm the removed
mcp_long_running_task.pyserver/sample and its prerequisites/documentation are not reintroduced by the cleanup. - Keep the new MCP Tasks design scoped to Python: Design MCP 2026 Tasks client support with SDK v2 extensions #9215; do not restore the pre-MCP-2.x polling, cancellation, TTL, or
tasks/get/tasks/resultimplementation as part of this issue.
Removed transport compatibility
- Remove the deprecated
MCPWebsocketToolclass and constructor compatibility surface. - Remove
MCPWebsocketToolfrom root lazy exports,__all__, andagent_framework/__init__.pyi. - Remove WebSocket-specific telemetry attributes, compatibility kwargs, docstrings, and deprecation tests.
- Remove remaining documentation that presents WebSocket as an available MCP transport; direct users to
MCPStreamableHTTPTool.
Deprecated MCP sampling surface
- Remove the deprecated
MCPTool.sampling_callbackimplementation and its deprecation-warning machinery. - Remove
SamplingApprovalCallbackand the wrapper-owned sampling options (client,sampling_approval_callback,sampling_max_tokens, andsampling_max_requests) from MCP tool constructors and root exports where they exist only for MCP sampling. - Remove sampling counters, token-cap helpers, approval gates, callback conversion code, and modern/legacy sampling compatibility tests.
- Remove the dedicated sampling approval sample and its README entry if they have not already been removed by Python: Document MCP v2 client lifecycle and update samples #9237.
- Update remaining docs to state that deprecated MCP sampling is no longer implemented by Agent Framework.
Server/hosting and cross-package cleanup from #9236
- Verify
agent-framework-hosting-mcpadapters expose only the current MCP 2.x server model/error/result APIs; remove any compatibility-only aliases, fallbacks, or tests that exist solely for the deprecated surfaces above. - Remove Tasks-era server fixtures, task-advertisement assumptions, and sample documentation that belonged to the deleted pre-2.x Tasks implementation.
- Complete the hosting sample naming cleanup from
FastMCP/fastmcp_app.pytoMCPServer/mcpserver_app.pyif Python: Document MCP v2 client lifecycle and update samples #9237 has not already merged it. - Update Declarative MCP handling and Foundry Toolbox integrations so they no longer depend on
MCPTool.sessionor a caller-supplied low-level session. - Remove compatibility-only tests across Core, Hosting MCP, Declarative, Foundry Hosting, security, observability, and skills while preserving current high-level Client coverage.
- Verify package metadata, type stubs, public API snapshots, samples, and generated documentation contain no removed symbol or parameter.
Validation and release readiness
- Add a migration note for each removed public symbol/parameter with the supported high-level
mcp.Clientreplacement. - Run repository-wide code search for
MCPTaskOptions,task_options,MCPWebsocketTool,SamplingApprovalCallback,sampling_callback, sampling constructor options, andMCPTool.session. - Run full Python formatting, linting, typing, package tests, sample checks, and public-API validation.
- Confirm legacy MCP peer negotiation and operation coverage still passes; removing these deprecated Python APIs must not accidentally remove supported legacy wire compatibility.
- Update the relevant changelog/release documentation as a next-major breaking change.
Acceptance criteria
- The deprecated compatibility symbols and parameters above are absent from runtime exports, type stubs, docs, and tests.
- Framework-owned and caller-owned high-level MCP connections use
mcp.Clientas the only public connection ownership model. - No pre-MCP-2.x Tasks implementation is restored; future Tasks support follows Python: Design MCP 2026 Tasks client support with SDK v2 extensions #9215.
- Current MCP 2.x server/hosting adapters and supported legacy peer behavior continue to work.
- The next-major migration guidance clearly identifies replacements for removed APIs.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
breaking changeUsage: [PRs], Target: all PRs that introduce changes that are not backward compatibleUsage: [PRs], Target: all PRs that introduce changes that are not backward compatiblemcpUsage: [Issues, PRs], Target: MCPUsage: [Issues, PRs], Target: MCPpythonUsage: [Issues, PRs], Target: PythonUsage: [Issues, PRs], Target: PythonvnextUsage: [Issues, PRs], Target: breaking-change features deferred to the next major releaseUsage: [Issues, PRs], Target: breaking-change features deferred to the next major release
Type
Projects
- StatusShow more project fieldsNo status
Activity
[-]Python: Remove deprecated MCP compatibility surfaces in vNext[/-][+]Python: [BREAKING] Remove deprecated MCP compatibility surfaces in vNext[/+]jpalvarezl commentedon Oct 16, 2026
MCPSkills and Foundry composition follow-ups
These items came out of the MCP v2 lifecycle review. They are intentionally tracked as vNext follow-ups rather than expanding the current PR:
ClientSessionsupport fromMCPSkillsSourceandMCPSkill; accept and document high-levelmcp.Clientas the connection model.session_providerAPI. If a replacement provider API is needed, name it for connections/resource reads and document that returned Clients are borrowed, already entered, and never closed by MCPSkills._session_provider, "session resolver", swappedMCPTool.session) in favor of connection/resource-read terminology.ClientSession; migrate them to high-levelClientorFoundryToolbox.as_skills_provider().MCPTool.session/ClientSessionsolely for skills resource access.ClientSessioncast with a narrowly typed resource-read abstraction if that adapter is still needed after low-level session removal.SkillsSourceAPI for aggregating local and Toolbox skills. Do not introduce anas_skills_source()API as incidental cleanup; require an explicit API proposal, naming review, caching/identity semantics, samples, and tests.jpalvarezl commentedon Oct 16, 2026
Follow-up: connection-owning
MCPSkillsSource(url=...)Related review discussion: #9237 (comment)
The suggestion is to let callers write something like:
instead of constructing and entering an
mcp.Clientthemselves. This is more than a constructor convenience because the source would then own an asynchronous connection lifecycle.Today,
SkillsSourceexposes onlyget_skills(context).SkillsProvidercalls that method frombefore_run, but it does not enter or close the source. An MCP Client also cannot be opened only for the index read and immediately closed: the returnedMCPSkillobjects fetchSKILL.mdbodies and resources later, so the same owned connection must remain available beyond discovery.Design TODOs
url,server, or a broader SDK transport/server input matchingmcp.Client(...).Clientremains caller-owned and already entered.SkillsSourceand haveSkillsProviderenter/close it;SkillsProviderspecifically own managed MCP sources;SKILL.mdloading, sibling resource reads, and archive downloads.MCPStreamableHTTPToolheader/HTTP-client APIs.ClientSessionoperations.CachingSkillsSource, especially cachedMCPSkillobjects retained after discovery.This should be treated as an explicit lifecycle/API feature, not folded into terminology cleanup or the current PR incidentally.
jpalvarezl commentedon Oct 19, 2026
MCP transport-tool ownership cleanup
Follow-up from #9369: the stabilized transport constructors distinguish framework-owned construction parameters from a caller-owned high-level
mcp.Client. The compatibility branches below should be removed in vNext rather than carried into the final API.MCPStreamableHTTPToolsession: ClientSession | Noneparameter, including the temporarily preservedurl + sessionconstructor path.mcp.Client.http_client: httpx2.AsyncClient | Noneconstructor parameter and its borrowed-lifecycle contract._httpx_clienthandling so any HTTP client created inside URL-owned mode is always framework-owned and deterministically closed; remove owned-versus-borrowed HTTP-client cleanup branches and tests.mcp.Clientthemselves and pass it throughmcp_client=.session=or caller-suppliedhttp_client=.MCPStdioToolsession: ClientSession | Noneparameter, including temporarily preservedcommand + sessionand session-only compatibility paths.command,args,env,encoding, and stdio transport kwargs scoped exclusively to framework-owned process construction.MCPStdioTool.Final ownership surface
mcp.Clientand passmcp_client=without transferring ownership.This cleanup must not remove automatic fallback to supported legacy MCP peers; it removes deprecated Python ownership/configuration surfaces only.