Python: Fix hosted MCP tool approval flow for all session/streaming combinations#4054
Merged
giles17 merged 3 commits intomicrosoft:mainfrom Feb 18, 2026
Merged
Python: Fix hosted MCP tool approval flow for all session/streaming combinations#4054giles17 merged 3 commits intomicrosoft:mainfrom
giles17 merged 3 commits intomicrosoft:mainfrom
Conversation
Member
Python Test Coverage Report •
Python Unit Test Overview
|
|||||||||||||||||||||||||||||||||||
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes hosted MCP tool approval flows across session + streaming combinations by preventing local tool-invocation logic from mutating hosted MCP approval messages, eagerly propagating conversation_id into sessions during streaming iteration, and correcting sample input accumulation logic.
Changes:
- Core: Add hosted-tool approval detection and skip local interception of hosted MCP approvals.
- Core: Propagate
conversation_idtosession.service_session_idduring streaming iteration (without requiringget_final_response()). - Samples/tests: Fix streaming approval loops to only send newly collected approval responses; add regression tests for hosted MCP passthrough and streaming session id propagation.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| python/packages/core/agent_framework/_tools.py | Add _is_hosted_tool_approval and exclude hosted approvals from local approval-response collection. |
| python/packages/core/agent_framework/_agents.py | Add streaming transform hook to eagerly set session.service_session_id from conversation_id. |
| python/packages/core/tests/core/test_function_invocation_logic.py | Add tests ensuring hosted MCP approvals pass through without mutation. |
| python/packages/core/tests/core/test_agents.py | Add test ensuring streaming sets session.service_session_id without get_final_response(). |
| python/samples/02-agents/providers/openai/openai_responses_client_with_hosted_mcp.py | Load .env and fix streaming approval loop to avoid duplicate inputs. |
| python/samples/02-agents/providers/azure_openai/azure_responses_client_with_hosted_mcp.py | Fix streaming approval loop to avoid duplicate inputs; update agent instructions text. |
TaoChenOSU
approved these changes
Feb 18, 2026
dmytrostruk
approved these changes
Feb 18, 2026
python/samples/02-agents/providers/azure_openai/azure_responses_client_with_hosted_mcp.py
Outdated
Show resolved
Hide resolved
…s_client_with_hosted_mcp.py Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
TaoChenOSU
approved these changes
Feb 18, 2026
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
Problem
Hosted MCP tools (e.g., Microsoft Learn MCP) with
require_approvalset were broken in multiple ways:Function invocation layer intercepted hosted MCP approvals —
_collect_approval_responses()in_tools.pytreated allfunction_approval_responsecontents as local tool approvals. For hosted MCP approvals, this caused
_replace_approval_contents_with_results()to mutate the messages — replacingmcp_approval_requestwith a barefunction_callandmcp_approval_responsewith afunction_result. The API rejected these mutated messages with"No tool output found for function call".Streaming + session:
session.service_session_idwas never set — The code that propagatesconversation_idto the session only ran inside_post_hook, aresult hook that requires
get_final_response(). Users who just iterate the stream (async for update in agent.run(stream=True)) never triggered it, so thefollow-up approval call had no
previous_response_id— error:"MCP approval requests have approval responses but weren't passed as input".Sample streaming loop accumulated duplicate approvals —
handle_approvals_with_session_streamingin both hosted MCP samples re-appended the original queryand all previous approval responses on each loop iteration, causing
"Duplicate MCP approval response"errors when multiple approvals occurred.Fix
_tools.py— Added_is_hosted_tool_approval()helper that checks forserver_labelinfunction_call.additional_properties(set by the responses clientwhen parsing
mcp_approval_requestevents). Modified_collect_approval_responses()to skip hosted tool approvals so they pass through to the API untouched._agents.py— Added a_propagate_conversation_idtransform hook on the streamingResponseStream. This eagerly setssession.service_session_idas updatesarrive during iteration, rather than deferring to
get_final_response(). The existing_post_hookis kept as a fallback.Samples — Fixed
handle_approvals_with_session_streamingin both OpenAI and Azure hosted MCP samples to resetnew_inputeach loop iteration, sending onlynew approval responses.
Description
Contribution Checklist