{"id":5599,"date":"2026-07-28T02:01:13","date_gmt":"2026-07-28T09:01:13","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/agent-framework\/?p=5599"},"modified":"2026-07-28T02:03:54","modified_gmt":"2026-07-28T09:03:54","slug":"discover-agent-skills-from-mcp-servers-in-net","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/agent-framework\/discover-agent-skills-from-mcp-servers-in-net\/","title":{"rendered":"Discover Agent Skills from MCP servers in .NET"},"content":{"rendered":"<p>Your agents can now discover and load <a href=\"https:\/\/agentskills.io\/\">Agent Skills<\/a> directly from a Model Context Protocol (MCP) server. Instead of shipping every skill inside your application or copying skill folders into each deployment, you point an agent at an MCP server and it pulls the skills it needs on demand. A central team can publish skills once, and every agent across your organization picks them up without a redeploy. This is available today in .NET through the <code>Microsoft.Agents.AI.Mcp<\/code> package.<\/p>\n<p>For makers, this removes a distribution problem: you author a skill in one place and serve it to many agents. For enterprise leaders, it means domain expertise \u2013 expense policies, compliance workflows, data-analysis playbooks \u2013 can be governed centrally, versioned on a server, and rolled out consistently without touching application code.<\/p>\n<h2>What MCP-based skills are<\/h2>\n<p>An <a href=\"https:\/\/agentskills.io\/\">Agent Skill<\/a> is a portable package of instructions, resources, and scripts that gives an agent specialized capability using a progressive-disclosure pattern: the agent sees a short advertisement of each skill up front, then loads the full instructions and resources only when a task matches.<\/p>\n<p>MCP-based skills apply that same pattern, but the skills live on an MCP server rather than on local disk or in code. The server advertises its skills through a discovery document at <code>skill:\/\/index.json<\/code>, and the framework retrieves the referenced skill content through the authenticated MCP connection.<\/p>\n<p>The .NET implementation supports two ways a server can distribute a skill:<\/p>\n<ul>\n<li><strong><code>skill-md<\/code><\/strong> \u2013 The server exposes the skill&#8217;s <code>SKILL.md<\/code> and its sibling resources as MCP resources. The framework fetches them on demand, file by file, as the agent loads the skill and reads its resources.<\/li>\n<li><strong><code>archive<\/code><\/strong> \u2013 The skill is packaged as a single archive (ZIP, TAR, or gzip-compressed TAR). The framework downloads it, unpacks it locally under a controlled directory, and serves the extracted files.<\/li>\n<\/ul>\n<p>Both types are consumed through the same builder API, so your agent code does not change based on how a skill is packaged.<\/p>\n<h2>Why this matters<\/h2>\n<p><strong>Author once, serve everywhere.<\/strong> A platform or domain team publishes skills to an MCP server. Any agent that connects picks them up \u2013 no per-agent packaging, no copying folders, no rebuild.<\/p>\n<p><strong>Update without redeploying agents.<\/strong> When the server&#8217;s skill content changes, connected agents get the new version the next time they discover skills. Policies and playbooks evolve on the server, not in every downstream application.<\/p>\n<p><strong>Consistency across many agents.<\/strong> The same skill, from the same source, reaches every agent. That is the difference between &#8220;each team maintains its own copy of the expense policy&#8221; and &#8220;there is one expense policy, and everyone uses it.&#8221;<\/p>\n<p><strong>Guardrails for remote content.<\/strong> Skills that arrive over MCP keep the same progressive-disclosure discipline as local skills, with explicit controls for archive extraction and script execution (covered below).<\/p>\n<h2>Getting started<\/h2>\n<p>MCP-based skills require the <code>Microsoft.Agents.AI.Mcp<\/code> NuGet package:<\/p>\n<pre><code>dotnet add package Microsoft.Agents.AI.Mcp --prerelease<\/code><\/pre>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Experimental API<\/strong><\/p>The MCP skills API is experimental and may change in future releases. The MCP skills specification is still evolving, and its details may be revised as the specification matures.<\/div><\/p>\n<p>Connect an MCP client to the server that hosts your skills, then use the <code>UseMcpSkills<\/code> extension method on <code>AgentSkillsProviderBuilder<\/code> to add it as a source:<\/p>\n<pre><code class=\"language-csharp\">using Microsoft.Agents.AI;\r\nusing ModelContextProtocol.Client;\r\n\r\n\/\/ Connect to the MCP server that hosts the skills\r\nawait using McpClient client = await McpClient.CreateAsync(\r\n    new StdioClientTransport(new()\r\n    {\r\n        Name = \"skills-server\",\r\n        Command = \"dotnet\",\r\n        Arguments = [skillsServerPath, \"--server\"],\r\n    }));\r\n\r\n\/\/ Build a skills provider that discovers skills over MCP\r\nvar skillsProvider = new AgentSkillsProviderBuilder()\r\n    .UseMcpSkills(client)\r\n    .Build();<\/code><\/pre>\n<p>Add the provider to an agent through its context providers so the framework advertises the server&#8217;s skills to the agent, and the agent can load and read them as it would local skills:<\/p>\n<pre><code class=\"language-csharp\">using Azure.AI.OpenAI;\r\nusing Azure.Identity;\r\nusing OpenAI.Responses;\r\n\r\nAIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())\r\n    .GetResponsesClient()\r\n    .AsAIAgent(new ChatClientAgentOptions\r\n    {\r\n        Name = \"SkillsAgent\",\r\n        ChatOptions = new()\r\n        {\r\n            Instructions = \"You are a helpful assistant. Use available skills to answer the user.\",\r\n        },\r\n        AIContextProviders = [skillsProvider],\r\n    },\r\n    model: deploymentName);\r\n\r\nAgentResponse response = await agent.RunAsync(\r\n    \"Summarize our expense reimbursement limits for international travel.\");\r\nConsole.WriteLine(response.Text);<\/code><\/pre>\n<p>The agent sees the skill advertised in its system prompt and, when the request matches, loads the relevant content. For a <code>skill-md<\/code> skill, the framework fetches <code>SKILL.md<\/code> from the server when the agent loads the skill. For an <code>archive<\/code> skill, it uses the skill archive downloaded from the server and extracted locally. In both cases, referenced resources are read as needed.<\/p>\n<h2>Use case: a central skills server for many agents<\/h2>\n<p>Suppose a platform team owns the company&#8217;s operational knowledge \u2013 expense policy, incident-response runbooks, and a data-classification guide. They host these as <code>skill-md<\/code> skills on an MCP server. A finance assistant, an on-call helper bot, and a data-governance agent all connect to that same server with the same <code>UseMcpSkills(client)<\/code> call shown above.<\/p>\n<p>None of the three agents bundles any of these skills. When the platform team updates the expense policy on the server, all three agents reflect the change on their next discovery \u2013 no coordinated release across teams.<\/p>\n<p>Because <code>UseMcpSkills<\/code> adds a <em>source<\/em> to the builder, you can compose it with local skills in the same provider. An agent can carry its own file-based skills and also pull shared ones from the server:<\/p>\n<pre><code class=\"language-csharp\">var skillsProvider = new AgentSkillsProviderBuilder()\r\n    .UseFileSkill(Path.Combine(AppContext.BaseDirectory, \"local-skills\")) \/\/ team-owned, on disk\r\n    .UseMcpSkills(client)                                                 \/\/ shared, from the server\r\n    .Build();<\/code><\/pre>\n<p>This includes <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/foundry\/agents\/how-to\/tools\/skills?pivots=rest-api\">Microsoft Foundry Toolbox<\/a> \u2013 if your organization manages skills through the Foundry Skills API and attaches them to a toolbox, <code>UseMcpSkills<\/code> connects to that toolbox&#8217;s MCP endpoint the same way it connects to any other MCP server. You author and version skills in Foundry, and your .NET agents discover them over MCP without additional integration work.<\/p>\n<h2>Use case: distributing a skill as an archive, safely<\/h2>\n<p>Some skills bundle several reference files \u2013 templates, lookup tables, checklists. Serving them as a single <code>archive<\/code> entry lets the server ship the whole package in one download. Because archive extraction writes remote content to local disk, it needs guardrails: an archive can be larger than expected, expand dramatically when decompressed, or contain more files than you intend to accept. Without bounds, a malformed or hostile archive could exhaust disk, memory, or CPU on the machine running the agent.<\/p>\n<p>For that reason, <code>AgentMcpSkillsSourceOptions<\/code> exposes a set of options that let you bound exactly how much an archive is allowed to consume before it is extracted and served:<\/p>\n<pre><code class=\"language-csharp\">using Microsoft.Agents.AI;\r\n\r\nvar skillsProvider = new AgentSkillsProviderBuilder()\r\n    .UseMcpSkills(client, new AgentMcpSkillsSourceOptions\r\n    {\r\n        ArchiveSkillsDirectory = Path.Combine(AppContext.BaseDirectory, \"extracted-skills\"),\r\n        ArchiveMaxFileCount = 50,\r\n        ArchiveMaxSizeBytes = 2 * 1024 * 1024,             \/\/ cap the download size\r\n        ArchiveMaxUncompressedSizeBytes = 4 * 1024 * 1024, \/\/ cap the total unpacked size\r\n    })\r\n    .Build();<\/code><\/pre>\n<p>Each option guards against a specific class of abuse:<\/p>\n<ul>\n<li><code>ArchiveMaxSizeBytes<\/code> caps the size of the archive that is downloaded, guarding against oversized payloads.<\/li>\n<li><code>ArchiveMaxUncompressedSizeBytes<\/code> caps the total unpacked size, guarding against decompression-bomb archives that are tiny on the wire but expand to gigabytes on disk.<\/li>\n<li><code>ArchiveMaxFileCount<\/code> caps how many files a single archive may contain, guarding against excessive-file-count archives.<\/li>\n<\/ul>\n<p>The framework downloads the archive, validates it against these limits, unpacks it under <code>ArchiveSkillsDirectory<\/code>, and serves the extracted <code>SKILL.md<\/code> and resources. An archive that exceeds any of these bounds is skipped, so an untrusted server cannot use skill distribution as a way to overwhelm the host.<\/p>\n<p>There is one more trust boundary around remote archive content:<\/p>\n<p><div class=\"alert alert-info\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Archive scripts are never executed<\/strong><\/p>Scripts bundled in archive-type skills are never executed. Executable content downloaded from a remote MCP server is treated as untrusted by design \u2013 the framework serves the skill&#8217;s instructions and resources, but will not run its scripts.<\/div><\/p>\n<p>The rest of the skills governance model still applies. Skill tools such as <code>load_skill<\/code>, <code>read_skill_resource<\/code>, and <code>run_skill_script<\/code> require approval by default, giving you a human-in-the-loop checkpoint before an agent acts.<\/p>\n<h2>Why this matters, restated<\/h2>\n<p>MCP-based skills turn Agent Skills into something you distribute rather than something you embed. Author a skill once, host it on an MCP server, and let every agent discover it on demand \u2013 updated centrally, governed centrally, and consumed the same way whether it arrives as <code>skill-md<\/code> resources or as a packaged <code>archive<\/code>. For teams building many agents against shared domain knowledge, that is the difference between maintaining copies and maintaining a source.<\/p>\n<p>To go deeper:<\/p>\n<ul>\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/agent-framework\/agents\/skills?pivots=programming-language-csharp#mcp-based-skills\">MCP-based skills documentation<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/microsoft\/agent-framework\/tree\/main\/dotnet\/samples\/02-agents\/AgentSkills\/Agent_Step06_McpBasedSkills\">MCP-based skills sample<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/foundry\/agents\/how-to\/tools\/skills?pivots=rest-api\">Skills in Microsoft Foundry<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/agent-framework\/agent-skills-for-net-is-now-released\/\">Agent Skills for .NET Is Now Released<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/agent-framework\/agent-skills-in-net-three-ways-to-author-one-provider-to-run-them\/\">Agent Skills in .NET: three ways to author, one provider to run them<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Your agents can now discover and load Agent Skills directly from a Model Context Protocol (MCP) server. Instead of shipping every skill inside your application or copying skill folders into each deployment, you point an agent at an MCP server and it pulls the skills it needs on demand. A central team can publish skills [&hellip;]<\/p>\n","protected":false},"author":157200,"featured_media":5625,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143,145,137],"tags":[79,146,133,147],"class_list":["post-5599","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-agent-framework","category-agent-skills","category-mcp","tag-net","tag-agent-skills","tag-mcp","tag-microsoft-agent-framework"],"acf":[],"blog_post_summary":"<p>Your agents can now discover and load Agent Skills directly from a Model Context Protocol (MCP) server. Instead of shipping every skill inside your application or copying skill folders into each deployment, you point an agent at an MCP server and it pulls the skills it needs on demand. A central team can publish skills [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5599","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/users\/157200"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/comments?post=5599"}],"version-history":[{"count":1,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5599\/revisions"}],"predecessor-version":[{"id":5766,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/posts\/5599\/revisions\/5766"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media\/5625"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/media?parent=5599"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/categories?post=5599"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/agent-framework\/wp-json\/wp\/v2\/tags?post=5599"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}