Skip to content

.NET: [BREAKING] Scope provider-backed MCP sessions per invocation - #8425

Merged
Jose Alvarez (jpalvarezl) merged 3 commits into
microsoft:mainfrom
jpalvarezl:jpalvarezl-mcp-session-cache
Sep 17, 2026
Merged

Jose Alvarez (jpalvarezl) merged 3 commits into
microsoft:mainfrom
jpalvarezl:jpalvarezl-mcp-session-cache

Conversation

@jpalvarezl

@jpalvarezl Jose Alvarez (jpalvarezl) commented Sep 16, 2026

Copy link
Copy Markdown
Member

Motivation & Context

Make MCP session ownership explicit for declarative workflow handlers that use custom HTTP client providers. Provider-selected authentication is not represented in the existing session cache key, so that key alone cannot establish whether a previous session is appropriate for each invocation.

Description & Review Guide

  • What are the major changes? Both .NET and Python create an invocation-scoped MCP session whenever a custom client provider is configured, including for tools/list and when the provider returns the same HTTP client or null/None. Sessions and owned fallback transports are cleaned up after use, active provider-backed invocations are tracked during shutdown, and caller-owned HTTP clients remain open. Existing no-provider session caching is preserved. Documentation and in-memory functional regression tests cover the ownership and lifecycle contract.
  • What is the impact of these changes? This is an intentional behavioral breaking change for custom-provider users: each invocation now incurs MCP session setup and does not retain server-side session state across calls. Public method signatures are unchanged. Applications requiring session continuity must supply a custom MCP handler with an explicit authentication ownership and lifetime contract. HTTP client reuse remains supported.
  • What do you want reviewers to focus on? Session and transport ownership across success, failure, cancellation, concurrent calls, and shutdown; preservation of no-provider caching; and the documented compatibility trade-off for provider-backed workflows.

Related Issue

N/A

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

Create and clean up separate MCP sessions for custom client-provider calls in .NET and Python. Preserve default session caching and caller-owned HTTP clients, and add lifecycle coverage and compatibility guidance.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings September 16, 2026 11:10
@agent-framework-automation agent-framework-automation Bot added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python .NET Usage: [Issues, PRs], Target: .Net workflows Usage: [Issues, PRs], Target: Workflows breaking change Usage: [PRs], Target: all PRs that introduce changes that are not backward compatible labels Sep 16, 2026
@github-actions github-actions Bot changed the title [BREAKING] Scope provider-backed MCP sessions per invocation Python: [BREAKING] Scope provider-backed MCP sessions per invocation Sep 16, 2026
@github-actions github-actions Bot changed the title Python: [BREAKING] Scope provider-backed MCP sessions per invocation .NET: [BREAKING] Scope provider-backed MCP sessions per invocation Sep 16, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Cross-runtime ownership, cancellation, and concurrent-shutdown behavior remains lifecycle-sensitive despite broad regression coverage.

Pull request overview

Scopes provider-backed MCP sessions per invocation across Python and .NET while preserving no-provider caching.

Changes:

  • Adds per-invocation session creation and cleanup for custom providers.
  • Coordinates cancellation and shutdown with active invocations.
  • Documents and tests ownership and lifecycle behavior.
File summaries
File Description
python/packages/declarative/tests/test_default_mcp_tool_handler.py Expands lifecycle and concurrency coverage.
python/packages/declarative/README.md Documents Python session lifetimes.
python/packages/declarative/AGENTS.md Records package lifecycle guidance.
python/packages/declarative/agent_framework_declarative/_workflows/_mcp_handler.py Implements invocation-scoped provider sessions.
dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.Mcp.UnitTests/DefaultMcpToolHandlerLifetimeTests.cs Adds .NET lifecycle regression tests.
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/README.md Documents .NET session lifetimes.
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/DefaultMcpToolHandler.cs Implements provider session ownership and shutdown tracking.
Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 0
  • Review effort level: Balanced

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Assert cancellation and resource cleanup without depending on a cancellation message that older asyncio task implementations may consume.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAF Automated Review — Iteration 1

Result: Findings reported
Scope: full PR (1 commit(s)): a8f0aca843f9
Model: gpt-5.6-sol-fast

Overview

The change consistently isolates provider-backed MCP sessions per invocation while preserving no-provider caching, caller-owned HTTP clients, and cleanup across ordinary failure and cancellation paths. The new tests provide strong coverage for concurrent calls, shutdown draining, and transport ownership. Two reentrant shutdown paths can nevertheless deadlock when a provider disposes its own handler, and the .NET disposal path can replace a completed tool result with a cleanup exception.

Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
3 verified findings remained after source verification (3 medium) across 2 files. Details are attached to the affected lines below.

Affected areas: dotnet/src/Microsoft.Agents.AI.Workflows.Declarative.Mcp/DefaultMcpToolHandler.cs, python/packages/declarative/agent_framework_declarative/_workflows/_mcp_handler.py

Reject self-draining shutdown across inherited invocation contexts. Preserve invocation outcomes when session or transport cleanup fails, report non-cancellation cleanup failures separately, and add lifecycle regression coverage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAF Automated Review — Iteration 2

Result: No findings
Scope: 2 net-new commit(s): 43694526cf15, 24b1029b1adc
Model: gpt-5.6-sol-fast

Overview

This incremental update adds execution-context ancestry guards in .NET and Python so provider callbacks, nested invocations, and inherited child tasks cannot deadlock by shutting down their own handler. It also preserves .NET invocation outcomes across non-cancellation cleanup failures, with focused tests covering provider, connect, call, list, close, nested, cancellation, and external-shutdown paths. The remaining candidates were either already covered by prior feedback, pre-existing relative to this review range, or unsupported as a concrete shared-boundary failure.

Reviewed the supplied incremental change set across correctness, security/reliability, architecture, and failure behavior.
No publishable findings remained after source verification for this scope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approved for python side

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Usage: [PRs], Target: all PRs that introduce changes that are not backward compatible documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs .NET Usage: [Issues, PRs], Target: .Net python Usage: [Issues, PRs], Target: Python workflows Usage: [Issues, PRs], Target: Workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants