microsoft / microsoft/agent-framework
Python: FoundryToolbox forwards a stale x-agent-foundry-call-id after the first request
@TaoChenOSU is already working on this.
Since Aug 18, 2026.
- Dominant language
- Python
- Stars
- 13.6k
- Forks
- 2.3k
- Avg merge
- 2d 45m
- Merged PRs (30d)
- 358
Description
### Describe the bug
`FoundryToolbox` connects its MCP session lazily on the **first** agent run and reuses that
connection for the lifetime of the toolbox. Because of how the MCP streamable-HTTP client is
structured, every subsequent POST is issued from the *connect-time* task context — so
`get_request_context()` inside `httpx.Auth.auth_flow` resolves to the **first** request's context,
and later requests forward a stale `x-agent-foundry-call-id`.
### To Reproduce
1. Build a `FoundryToolbox` and attach it to a hosted agent.
2. Bind a request context with call id `CALL-1` and run the agent (this connects the session).
3. Bind a request context with call id `CALL-2` and run the agent again.
4. Inspect the outbound headers on the second run's toolbox POSTs.
**Observed:** the second run still sends `x-agent-foundry-call-id: CALL-1`.
**Expected:** it sends `CALL-2`.
### Root cause
`mcp/client/streamable_http.py` creates a task group at connect time and starts `post_writer` via
`tg.start_soon` (~lines 647/659), so all POSTs run in the task context captured at connect. The
call id is carried by a plain `ContextVar` in
`azure/ai/agentserver/core/_request_context.py` that is re-`set` per request, and a `ContextVar`
set in one task is not visible to a task started earlier from a different context. So the value
cannot cross that boundary no matter where it is read.
This also means the natural fix (reading the context inside `auth_flow`) does not work — I verified
that empirically; the auth flow observes only the connect-time value.
### Impact
Scoped, but real. The service currently accepts the stale id — I confirmed that reading both
`skill://index.json` and a skill's `SKILL.md` succeeds even with a deliberately **bogus** call id —
so this does not break toolbox calls today. It does mean that any server-side use of the call id
(request correlation, tracing, per-call policy) attributes every toolbox call after the first to
the first request of the process.
The same pattern is present in the official sample
`python/samples/04-hosting/foundry-hosted-agents/responses/foundry_toolbox_mcp_skills`, so it is
not specific to a caller's wiring.
### Expected behavior
Toolbox requests should carry the call id of the request that triggered them. That likely requires
either establishing the MCP session per request, or propagating the per-request context across the
connect-time task boundary explicitly rather than relying on `ContextVar` inheritance.
### Platform
- Language: Python
- Package: `agent-framework-foundry-hosting`
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.