Files
Roger Barreto dc4bafbc1e .NET: Add Hosted-AgentSkills sample with Foundry Skills integration (#6013)
* .NET: Add Hosted-AgentSkills sample for Foundry Skills integration

Add a new hosted agent sample that demonstrates how to load behavioral
guidelines from Foundry Skills at startup using AgentSkillsProvider and
the progressive disclosure pattern (advertise -> load on demand).

The sample:
- Downloads SKILL.md files from Foundry via ProjectAgentSkills SDK
- Extracts ZIP archives with zip-slip protection
- Wires skills into AgentSkillsProvider as an AIContextProvider
- Hosts the agent via the Responses protocol

Ships two Contoso Outdoors skills matching the Python sample (PR #5822):
- support-style: tone, formatting, signature guidelines
- escalation-policy: when and how to escalate tickets

Includes convenience provisioning gated behind PROVISION_SAMPLE_SKILLS
env var, clearly documented as NOT a production pattern.

Closes #5776

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* .NET: Add unit tests and integration test for Hosted-AgentSkills

Unit tests (14 tests, all passing):
- ZIP extraction with zip-slip guard (valid archive, traversal attack,
  sibling-prefix attack, directory entries)
- Skill name validation (rejects dots, separators, traversal patterns)
- AgentSkillsProvider with downloaded skills (advertises both skills,
  load_skill returns canary tokens, unknown skill returns error)

Container integration test:
- New 'agent-skills' scenario in the test container that creates
  Contoso Outdoors skills on disk and wires AgentSkillsProvider
- AgentSkillsHostedAgentFixture + 4 integration tests verifying:
  - Routine questions load support-style skill (STYLE-CANARY-3318)
  - Escalation triggers load escalation-policy (ESC-CANARY-7742)
  - Skills are advertised in system prompt
  - load_skill tool is invoked via FunctionCallContent

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* .NET: Add smoke test, bootstrap, and docs for agent-skills integration

- Add scripts/smoke.ps1 for local Docker smoke testing: builds the
  contributor image, runs the container, verifies both skills are loaded
  via canary tokens (STYLE-CANARY-3318, ESC-CANARY-7742)
- Add 'agent-skills' to the bootstrap script scenario list
- Add agent-skills row to the integration test README scenarios table
- Exclude HostedAgentSkillsPatternTests from net472 (uses net8.0+ APIs)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* .NET: Update commented-out package versions to latest across all hosted samples

Update the end-user PackageReference versions (in the commented-out
sections) from 1.0.0 to the current latest NuGet versions:

- Microsoft.Agents.AI: 1.6.1
- Microsoft.Agents.AI.Foundry: 1.6.1-preview.260514.1
- Microsoft.Agents.AI.Foundry.Hosting: 1.6.1-preview.260514.1
- Microsoft.Agents.AI.Hosting: 1.6.1-preview.260514.1
- Microsoft.Agents.AI.OpenAI: 1.6.1
- Microsoft.Agents.AI.Workflows: 1.6.1

Also adds explicit versions to Hosted-Workflow-Handoff which had bare
PackageReference entries without Version attributes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* .NET: Fix broken markdown links in Hosted-AgentSkills README

Remove references to non-existent ../../README.md. Replace with
inline instructions matching other hosted samples that don't have
a parent README.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* .NET: Use OS-appropriate string comparison in zip-slip guard

Use Ordinal on Unix (case-sensitive FS) and OrdinalIgnoreCase on
Windows to prevent case-based path bypass on Linux containers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
dc4bafbc1e · 2026-05-25 09:32:04 +00:00
History
..

Hosted-McpTools

A hosted agent demonstrating two layers of MCP (Model Context Protocol) tool integration:

  1. Client-side MCP (Microsoft Learn) — The agent connects directly to the Microsoft Learn MCP server via McpClient, discovers tools, and handles tool invocations locally within the agent process.

  2. Server-side MCP (Microsoft Learn) — The agent declares a HostedMcpServerTool which delegates tool discovery and invocation to the LLM provider (Azure OpenAI Responses API). The provider calls the MCP server on behalf of the agent with no local connection needed.

How the two MCP patterns differ

Client-side MCP Server-side MCP
Connection Agent connects to MCP server directly LLM provider connects to MCP server
Tool invocation Handled by the agent process Handled by the Responses API
Auth Agent manages credentials Provider manages credentials
Use case Custom/private MCP servers, fine-grained control Public MCP servers, simpler setup
Example Microsoft Learn (McpClient + HttpClientTransport) Microsoft Learn (HostedMcpServerTool)

Prerequisites

  • .NET 10 SDK
  • An Azure AI Foundry project with a deployed model (e.g., gpt-4o)
  • Azure CLI logged in (az login)

Configuration

Copy the template and fill in your values:

cp .env.example .env

Edit .env:

AZURE_AI_PROJECT_ENDPOINT=https://<your-account>.services.ai.azure.com/api/projects/<your-project>
AZURE_AI_MODEL_DEPLOYMENT_NAME=gpt-4o

Running directly (contributors)

cd dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-McpTools
dotnet run

Test it

Using the Azure Developer CLI:

# Uses GitHub MCP (client-side)
azd ai agent invoke --local "Search for the agent-framework repository on GitHub"

# Uses Microsoft Learn MCP (server-side)
azd ai agent invoke --local "How do I create an Azure storage account using az cli?"

Running with Docker

1. Publish for the container runtime

dotnet publish -c Debug -f net10.0 -r linux-musl-x64 --self-contained false -o out

2. Build and run

docker build -f Dockerfile.contributor -t hosted-mcp-tools .

export AZURE_BEARER_TOKEN=$(az account get-access-token --resource https://ai.azure.com --query accessToken -o tsv)

docker run --rm -p 8088:8088 \
  -e AGENT_NAME=mcp-tools \
  -e AZURE_BEARER_TOKEN=$AZURE_BEARER_TOKEN \
  --env-file .env \
  hosted-mcp-tools

NuGet package users

Use the standard Dockerfile instead of Dockerfile.contributor. See the commented section in HostedMcpTools.csproj for the PackageReference alternative.