.Net: [WIP] Add Foundry Toolbox Support to Hosted Agents#5318
Open
rogerbarreto wants to merge 4 commits intomicrosoft:feature/responses-hostingfrom
Open
.Net: [WIP] Add Foundry Toolbox Support to Hosted Agents#5318rogerbarreto wants to merge 4 commits intomicrosoft:feature/responses-hostingfrom
rogerbarreto wants to merge 4 commits intomicrosoft:feature/responses-hostingfrom
Conversation
01a730b to
e665172
Compare
Adds support for Foundry Toolsets MCP proxy integration in the hosted agent response handler. Toolsets connect at startup via IHostedService, gating the readiness probe per spec §3.1. MCP tools are injected into every request's ChatOptions and OAuth consent errors (-32006) are intercepted and surfaced as mcp_approval_request + incomplete SSE events. New files: - FoundryToolboxOptions.cs: configuration POCO for toolset names and API version - FoundryToolboxBearerTokenHandler.cs: DelegatingHandler with Azure Bearer token auth, Foundry-Features header injection, and 3x exponential backoff on 429/5xx - McpConsentContext.cs: AsyncLocal-based per-request consent state shared between the tool wrapper and the response handler - ConsentAwareMcpClientTool.cs: AIFunction wrapper that catches -32006 errors and signals consent via shared state and linked CancellationTokenSource - FoundryToolboxService.cs: IHostedService that creates McpClient per toolset at startup and exposes cached tools Modified files: - AgentFrameworkResponseHandler.cs: injects toolbox tools into ChatOptions, sets up linked CTS consent interception, emits mcp_approval_request on -32006 - ServiceCollectionExtensions.cs: adds AddFoundryToolboxes(params string[]) extension - Microsoft.Agents.AI.Foundry.csproj: adds ModelContextProtocol and Azure.Identity dependencies under NETCoreApp condition Sample: - Hosted-Toolbox: minimal hosted agent sample using AddFoundryToolboxes
…lientTool to ConsentAwareMcpClientAIFunction
Introduces HostedMcpToolboxAITool, a marker tool subclassing HostedMcpServerTool that rides the OpenAI Responses 'mcp' wire format to let clients request a specific Foundry toolbox per request. - New FoundryAITool.CreateHostedMcpToolbox(name, version?) factory. - FoundryToolboxOptions.StrictMode (default true) rejects unregistered toolboxes; set to false to allow lazy-open on first use. - FoundryToolboxService.GetToolboxToolsAsync(name, version?) resolves cached or lazy-opened MCP tools. - AgentFrameworkResponseHandler parses request.Tools for foundry-toolbox://name[?version=v] markers and injects resolved tools per request, merging with pre-registered ones. - Unit tests for marker parsing and strict-mode resolution.
e665172 to
215a0ad
Compare
…on factory overloads + tests
alliscode
approved these changes
Apr 20, 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.
Summary
Adds Foundry Toolbox (MCP proxy) integration to
AgentFrameworkResponseHandlerinMicrosoft.Agents.AI.Foundry, supporting both host-configured (eager, startup) and client-selectable (per-request, lazy) toolbox injection.What this adds
Phase 1 — Host-configured toolboxes (eager)
IHostedService— MCP clients connect and discover tools at startup, gating the readiness probe (spec §3.1)ChatOptions.Toolson every request-32006returned by the Foundry proxy is caught by a per-toolAIFunctionwrapper, stored inAsyncLocalshared state, and propagated back to the handler which emitsmcp_approval_request+incompleteSSE eventsFoundryToolboxBearerTokenHandlerretries up to 3x with exponential backoff on 429/5xx (spec §7)FOUNDRY_AGENT_TOOLSET_ENDPOINTis absent the container starts healthy with no tools (spec §2)Phase 2 — Client-selectable toolboxes (per-request)
HostedMcpToolboxAITool— new public (experimental) marker type subclassingHostedMcpServerTool. Rides the OpenAI Responsesmcpwire format using a syntheticfoundry-toolbox://<name>?version=<v>URI so toolbox selection survives client → server serialization without a new wire type.FoundryAITool.CreateHostedMcpToolbox(...)— factory overloads so consumers can attach a toolbox marker from (a) a plainname [+ version], (b) aToolboxRecord(usesName+DefaultVersion), or (c) a specificToolboxVersion(usesName+Version) retrieved fromAIProjectClient.FoundryToolboxService, and merges with any host-configured toolbox tools. Markers are deduped by name per request.SemaphoreSlim). Cached toolboxes are reused across requests.StrictModeoption (defaulttrue) — when a client-requested toolbox fails to resolve, the handler emits a failed response with a clear error. SetStrictMode = falseto silently skip unresolvable toolboxes.Files changed
New
HostedMcpToolboxAITool.cs— marker tool,UriScheme = "foundry-toolbox",BuildAddress/TryParseToolboxAddressFoundryToolboxOptions.cs— toolbox name list, API version,StrictModeFoundryToolboxBearerTokenHandler.cs—DelegatingHandler: Bearer token,Foundry-Featuresheader, 3x backoffMcpConsentContext.cs—AsyncLocalper-request consent stateConsentAwareMcpClientAIFunction.cs—AIFunctionwrapper catching-32006, cancels linked CTS to escapeFunctionInvokingChatClienttool loopFoundryToolboxService.cs—IHostedService+IAsyncDisposable: eager MCP client per toolbox at startup, plusGetToolboxToolsAsync(name, version?, ct)for lazy openInputConverter.ReadMcpToolboxMarkers— parsesMCPToolentries with thefoundry-toolbox://schemeHostedMcpToolboxAIToolTests,Hosting/FoundryToolboxServiceTestsHosted-Toolbox/sample — minimal hosted agent usingAddFoundryToolboxesModified
AgentFrameworkResponseHandler.cs— per-request marker parse + merge, linked CTS consent path,mcp_approval_requestemission,EmitFailedon strict-mode resolution failuresFoundryAITool.cs—CreateHostedMcpToolbox(string, string?),CreateHostedMcpToolbox(ToolboxRecord),CreateHostedMcpToolbox(ToolboxVersion)factoriesServiceCollectionExtensions.cs—AddFoundryToolboxes(params string[])andAddFoundryToolboxes(configureOptions, params string[])overloadsMicrosoft.Agents.AI.Foundry.csproj—ModelContextProtocol+Azure.Identityunder.NETCoreAppconditionUsage
Host configured (eager at startup):
Client selected (per request) — discover via
AIProjectClient:Combined — host-configured toolboxes are always injected; client markers additionally lazy-open any toolbox the server hasn't pre-registered.
Environment variables
FOUNDRY_AGENT_TOOLSET_ENDPOINTFOUNDRY_AGENT_TOOLSET_FEATURESFoundry-FeaturesheaderFOUNDRY_AGENT_NAMEhosted-agent)FOUNDRY_AGENT_VERSION1.0.0)