Skip to content

Comments

Python: Fix hosted MCP tool approval flow for all session/streaming combinations#4054

Merged
giles17 merged 3 commits intomicrosoft:mainfrom
giles17:hosted_mcp_fixes
Feb 18, 2026
Merged

Python: Fix hosted MCP tool approval flow for all session/streaming combinations#4054
giles17 merged 3 commits intomicrosoft:mainfrom
giles17:hosted_mcp_fixes

Conversation

@giles17
Copy link
Contributor

@giles17 giles17 commented Feb 18, 2026

Motivation and Context

Problem

Hosted MCP tools (e.g., Microsoft Learn MCP) with require_approval set were broken in multiple ways:

  1. Function invocation layer intercepted hosted MCP approvals_collect_approval_responses() in _tools.py treated all function_approval_response
    contents as local tool approvals. For hosted MCP approvals, this caused _replace_approval_contents_with_results() to mutate the messages — replacing
    mcp_approval_request with a bare function_call and mcp_approval_response with a function_result. The API rejected these mutated messages with "No tool output found for function call".

  2. Streaming + session: session.service_session_id was never set — The code that propagates conversation_id to the session only ran inside _post_hook, a
    result hook that requires get_final_response(). Users who just iterate the stream (async for update in agent.run(stream=True)) never triggered it, so the
    follow-up approval call had no previous_response_id — error: "MCP approval requests have approval responses but weren't passed as input".

  3. Sample streaming loop accumulated duplicate approvalshandle_approvals_with_session_streaming in both hosted MCP samples re-appended the original query
    and 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 for server_label in function_call.additional_properties (set by the responses client
when parsing mcp_approval_request events). Modified _collect_approval_responses() to skip hosted tool approvals so they pass through to the API untouched.

_agents.py — Added a _propagate_conversation_id transform hook on the streaming ResponseStream. This eagerly sets session.service_session_id as updates
arrive during iteration, rather than deferring to get_final_response(). The existing _post_hook is kept as a fallback.

Samples — Fixed handle_approvals_with_session_streaming in both OpenAI and Azure hosted MCP samples to reset new_input each loop iteration, sending only
new approval responses.

Description

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

Copilot AI review requested due to automatic review settings February 18, 2026 22:10
@github-actions github-actions bot changed the title Fix hosted MCP tool approval flow for all session/streaming combinations Python: Fix hosted MCP tool approval flow for all session/streaming combinations Feb 18, 2026
@markwallace-microsoft
Copy link
Member

markwallace-microsoft commented Feb 18, 2026

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/core/agent_framework
   _agents.py3314387%425, 429, 481, 846, 882, 898, 974–977, 1038–1040, 1161, 1177, 1179, 1192, 1198, 1234, 1236, 1245–1250, 1255, 1257, 1263–1264, 1271, 1273–1274, 1282–1283, 1286–1288, 1296–1297, 1299, 1304, 1306
   _tools.py8298989%165–166, 303, 305, 323–325, 332, 350, 364, 371, 378, 394, 396, 403, 440, 465, 469, 486–488, 535–537, 600, 622, 685–691, 727, 738–749, 771–773, 778, 782, 796–798, 837, 906, 916, 926, 982, 1013, 1032, 1294, 1351, 1371, 1442–1446, 1568, 1572, 1596, 1622, 1624, 1640, 1642, 1727, 1757, 1814, 1882, 2065–2066, 2093, 2101, 2114, 2124–2125, 2160, 2216
TOTAL21244330384% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
4190 239 💤 0 ❌ 0 🔥 1m 9s ⏱️

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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_id to session.service_session_id during streaming iteration (without requiring get_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.

…s_client_with_hosted_mcp.py

Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
@giles17 giles17 enabled auto-merge February 18, 2026 23:24
@giles17 giles17 added this pull request to the merge queue Feb 18, 2026
Merged via the queue into microsoft:main with commit 21769e2 Feb 18, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants