-
Notifications
You must be signed in to change notification settings - Fork 1.9k
.NET: Add Foundry Toolbox MCP skills discovery sample #6134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
semenshi
merged 3 commits into
microsoft:main
from
semenshi:fix/step26-foundry-toolbox-mcp-skills
May 28, 2026
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
22 changes: 22 additions & 0 deletions
22
...hFoundry/Agent_Step26_FoundryToolboxMcpSkills/Agent_Step26_FoundryToolboxMcpSkills.csproj
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| <TargetFrameworks>net10.0</TargetFrameworks> | ||
|
|
||
| <Nullable>enable</Nullable> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Azure.AI.Projects" /> | ||
| <PackageReference Include="Azure.Identity" /> | ||
| <PackageReference Include="ModelContextProtocol" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Foundry\Microsoft.Agents.AI.Foundry.csproj" /> | ||
| <ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Mcp\Microsoft.Agents.AI.Mcp.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> | ||
93 changes: 93 additions & 0 deletions
93
dotnet/samples/02-agents/AgentsWithFoundry/Agent_Step26_FoundryToolboxMcpSkills/Program.cs
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| // Copyright (c) Microsoft. All rights reserved. | ||
|
|
||
| // Foundry Toolbox MCP Skills. | ||
| // | ||
| // Uses AgentSkillsProviderBuilder to discover MCP-based skills from a Foundry | ||
| // Toolbox endpoint and inject them as AIContextProviders so the agent can | ||
| // discover and use them at runtime. | ||
|
|
||
| using System.Net.Http.Headers; | ||
| using Azure.AI.Projects; | ||
| using Azure.Core; | ||
| using Azure.Identity; | ||
| using Microsoft.Agents.AI; | ||
| using ModelContextProtocol.Client; | ||
|
|
||
| // --- Configuration --- | ||
| string endpoint = Environment.GetEnvironmentVariable("AZURE_AI_PROJECT_ENDPOINT") | ||
| ?? throw new InvalidOperationException("AZURE_AI_PROJECT_ENDPOINT is not set."); | ||
| string deploymentName = Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME") ?? "gpt-5.4-mini"; | ||
| string toolboxMcpServerUrl = Environment.GetEnvironmentVariable("FOUNDRY_TOOLBOX_MCP_SERVER_URL") | ||
| ?? throw new InvalidOperationException("FOUNDRY_TOOLBOX_MCP_SERVER_URL is not set."); | ||
|
|
||
| // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. | ||
| // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid | ||
| // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. | ||
| TokenCredential credential = new DefaultAzureCredential(); | ||
|
|
||
| using var httpClient = new HttpClient(new BearerTokenHandler(credential, "https://ai.azure.com/.default") | ||
| { | ||
| InnerHandler = new HttpClientHandler(), | ||
| }); | ||
|
|
||
| // --- Connect to the Foundry Toolbox MCP endpoint --- | ||
| await using McpClient mcpClient = await McpClient.CreateAsync( | ||
| new HttpClientTransport( | ||
| new HttpClientTransportOptions | ||
| { | ||
| Endpoint = new Uri(toolboxMcpServerUrl), | ||
| Name = "foundry_toolbox", | ||
| TransportMode = HttpTransportMode.StreamableHttp, | ||
|
semenshi marked this conversation as resolved.
semenshi marked this conversation as resolved.
|
||
| AdditionalHeaders = new Dictionary<string, string> | ||
| { | ||
| ["Foundry-Features"] = "Toolboxes=V1Preview", | ||
| }, | ||
| }, | ||
| httpClient)); | ||
|
semenshi marked this conversation as resolved.
|
||
|
|
||
| // --- Discover MCP-based skills --- | ||
| var skillsProvider = new AgentSkillsProviderBuilder() | ||
| .UseMcpSkills(mcpClient) | ||
| .Build(); | ||
|
|
||
| // --- Create the agent --- | ||
| AIProjectClient aiProjectClient = new(new Uri(endpoint), credential); | ||
|
|
||
| AIAgent agent = aiProjectClient.AsAIAgent( | ||
| options: new ChatClientAgentOptions | ||
| { | ||
| Name = "ToolboxMcpSkillsAgent", | ||
| ChatOptions = new() | ||
| { | ||
| ModelId = deploymentName, | ||
| Instructions = "You are a helpful assistant. Use available skills to answer the user.", | ||
| }, | ||
| AIContextProviders = [skillsProvider], | ||
| }); | ||
|
|
||
| // --- Interactive prompt --- | ||
| Console.Write("User: "); | ||
| string? query = Console.ReadLine(); | ||
|
|
||
| if (string.IsNullOrWhiteSpace(query)) | ||
| { | ||
| Console.WriteLine("No input provided."); | ||
| return; | ||
| } | ||
|
|
||
| Console.WriteLine($"Assistant: {await agent.RunAsync(query)}"); | ||
|
|
||
| // --------------------------------------------------------------------------- | ||
| // DelegatingHandler: attaches a fresh Foundry bearer token to every request | ||
| // --------------------------------------------------------------------------- | ||
| internal sealed class BearerTokenHandler(TokenCredential credential, string scope) : DelegatingHandler | ||
| { | ||
| private readonly TokenRequestContext _tokenContext = new([scope]); | ||
|
|
||
| protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) | ||
| { | ||
| AccessToken token = await credential.GetTokenAsync(this._tokenContext, cancellationToken).ConfigureAwait(false); | ||
| request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.Token); | ||
| return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); | ||
| } | ||
| } | ||
32 changes: 32 additions & 0 deletions
32
...ples/02-agents/AgentsWithFoundry/Agent_Step26_FoundryToolboxMcpSkills/README.md
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # Foundry Toolbox MCP Skills | ||
|
|
||
| This sample uses | ||
| `AgentSkillsProviderBuilder` to discover MCP-based skills from a Foundry Toolbox endpoint | ||
| and inject them as `AIContextProviders` so the agent can discover and use them at runtime. | ||
|
|
||
| ## What this sample demonstrates | ||
|
|
||
| - Connecting to a Foundry toolbox's MCP endpoint via Streamable HTTP transport | ||
| - Injecting a fresh Azure AI bearer token (`https://ai.azure.com/.default`) on every MCP request | ||
| - Using `AgentSkillsProviderBuilder.UseMcpSkills(client)` to discover skills from the toolbox | ||
| - Injecting the discovered skills into `AIProjectClient.AsAIAgent(...)` via `AIContextProviders` | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - A Microsoft Foundry project with a toolbox already configured | ||
|
semenshi marked this conversation as resolved.
|
||
| - The toolbox MCP endpoint must expose `skill://index.json` with `skill-md` entries (SEP-2640). If the resource is absent, the sample runs but the skills provider will be empty. | ||
|
semenshi marked this conversation as resolved.
|
||
| - Azure CLI installed and authenticated (`az login`) | ||
|
|
||
| Set the following environment variables: | ||
|
|
||
| ```powershell | ||
| $env:AZURE_AI_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" | ||
| $env:AZURE_AI_MODEL_DEPLOYMENT_NAME="gpt-5.4-mini" | ||
| $env:FOUNDRY_TOOLBOX_MCP_SERVER_URL="https://your-foundry-service.services.ai.azure.com/api/projects/your-project/toolboxes/your-toolbox/mcp?api-version=v1" | ||
| ``` | ||
|
|
||
| ## Run the sample | ||
|
|
||
| ```powershell | ||
| dotnet run | ||
| ``` | ||
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
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.