{"id":57309,"date":"2025-07-15T13:00:00","date_gmt":"2025-07-15T20:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=57309"},"modified":"2025-07-15T13:20:11","modified_gmt":"2025-07-15T20:20:11","slug":"mcp-server-dotnet-nuget-quickstart","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/mcp-server-dotnet-nuget-quickstart\/","title":{"rendered":"Building Your First MCP Server with .NET and Publishing to NuGet"},"content":{"rendered":"<p>Want to extend AI assistants with custom capabilities? In this post, we&#8217;ll show you how to build a Model Context Protocol (MCP) server using .NET 10 and publish it to NuGet \u2014 making your AI tools discoverable and reusable by the entire .NET community. We&#8217;ll also show you some new features we&#8217;ve added to .NET 10 and NuGet to support this, and a new MCP Server project template that makes it easier to get started!<\/p>\n<h2>Building MCP Servers with .NET 10<\/h2>\n<h3>\u2728 Intro: What&#8217;s the Model Context Protocol?<\/h3>\n<p>The <strong>Model Context Protocol (MCP)<\/strong> is an open standard that enables AI assistants to securely connect to external data sources and tools. Think of it as a bridge between AI models and the real world \u2014 letting assistants access databases, APIs, file systems, and custom business logic.<\/p>\n<p>With .NET 10 and the new MCP templates, you can create powerful servers that extend AI capabilities \u2014 and now publish them to <strong>NuGet<\/strong> for the entire .NET community to discover and use!<\/p>\n<h3>\ud83d\ude80 NuGet: .NET MCP Servers Available on NuGet<\/h3>\n<p>Here&#8217;s the exciting part: <strong>NuGet.org now supports hosting and consuming MCP servers built with the <a href=\"https:\/\/www.nuget.org\/packages\/ModelContextProtocol\">ModelContextProtocol<\/a> C# SDK<\/strong>. This means:<\/p>\n<ul>\n<li><strong>Discoverability<\/strong>: Developers can find your MCP servers through NuGet search<\/li>\n<li><strong>Versioning<\/strong>: Proper semantic versioning and dependency management<\/li>\n<li><strong>Easy Installation<\/strong>: Copy VS Code and Visual Studio MCP configuration<\/li>\n<li><strong>Community<\/strong>: Join a growing ecosystem of .NET AI tools<\/li>\n<\/ul>\n<p>Search for MCP servers on NuGet.org using the <a href=\"https:\/\/www.nuget.org\/packages?packagetype=McpServer\"><code>MCP Server<\/code> package type filter<\/a>, and you&#8217;ll see what the community is building!<\/p>\n<h2>\ud83d\udce6 Creating Your First MCP Server<\/h2>\n<p>Let&#8217;s build a simple MCP server that provides weather information and random numbers. You&#8217;ll see how easy it is to get started with the new .NET 10 MCP templates.<\/p>\n<h3>Prerequisites<\/h3>\n<p>Before we start, make sure you have:<\/p>\n<ul>\n<li><a href=\"https:\/\/dotnet.microsoft.com\/download\/dotnet\/10.0\">.NET 10.0 SDK<\/a> (preview 6 or higher)<\/li>\n<li><a href=\"https:\/\/code.visualstudio.com\/\">Visual Studio Code<\/a><\/li>\n<li><a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=GitHub.copilot\">GitHub Copilot extension<\/a><\/li>\n<li><a href=\"https:\/\/www.nuget.org\/users\/account\/LogOn\">NuGet.org account<\/a><\/li>\n<\/ul>\n<h3>Step 1: Install the MCP Template<\/h3>\n<p>First, install the MCP Server template (version 9.7.0-preview.2.25356.2 or newer):<\/p>\n<pre><code class=\"language-bash\">dotnet new install Microsoft.Extensions.AI.Templates<\/code><\/pre>\n<h3>Step 2: Create Your MCP Server Project<\/h3>\n<p>Create a new MCP server with the template:<\/p>\n<pre><code class=\"language-bash\">dotnet new mcpserver -n SampleMcpServer\r\ncd SampleMcpServer\r\ndotnet build<\/code><\/pre>\n<p>The template gives you a working MCP server with a sample <code>get_random_number<\/code> tool. But let&#8217;s make it more interesting!<\/p>\n<h2>\ud83d\udd27 Adding Custom Tools and Configuration<\/h2>\n<p>Let&#8217;s enhance our MCP server with a weather tool that uses environment variables for configuration. Add a new <code>WeatherTools.cs<\/code> class to the <code>Tools<\/code> directory with the following method:<\/p>\n<pre><code class=\"language-csharp\">[McpServerTool]\r\n[Description(\"Describes random weather in the provided city.\")]\r\npublic string GetCityWeather(\r\n    [Description(\"Name of the city to return weather for\")] string city)\r\n{\r\n    \/\/ Read the environment variable during tool execution.\r\n    \/\/ Alternatively, this could be read during startup and passed via IOptions dependency injection\r\n    var weather = Environment.GetEnvironmentVariable(\"WEATHER_CHOICES\");\r\n    if (string.IsNullOrWhiteSpace(weather))\r\n    {\r\n        weather = \"balmy,rainy,stormy\";\r\n    }\r\n\r\n    var weatherChoices = weather.Split(\",\");\r\n    var selectedWeatherIndex =  Random.Shared.Next(0, weatherChoices.Length);\r\n\r\n    return $\"The weather in {city} is {weatherChoices[selectedWeatherIndex]}.\";\r\n}<\/code><\/pre>\n<p>Next, update your <em>Program.cs<\/em> to include <code>.WithTools&lt;WeatherTools&gt;()<\/code> after the previous <code>WithTools<\/code> call.<\/p>\n<p>This tool demonstrates how to:<\/p>\n<ul>\n<li>Accept parameters from AI assistants<\/li>\n<li>Use environment variables for configuration<\/li>\n<li>Return meaningful responses<\/li>\n<\/ul>\n<h2>\ud83c\udfaf Testing Your MCP Server<\/h2>\n<p>Configure GitHub Copilot to use your MCP server by creating <code>.vscode\/mcp.json<\/code>:<\/p>\n<pre><code class=\"language-json\">{\r\n  \"servers\": {\r\n    \"SampleMcpServer\": {\r\n      \"type\": \"stdio\",\r\n      \"command\": \"dotnet\",\r\n      \"args\": [\r\n        \"run\",\r\n        \"--project\",\r\n        \".\"\r\n      ],\r\n      \"env\": {\r\n        \"WEATHER_CHOICES\": \"sunny,humid,freezing,perfect\"\r\n      }\r\n    }\r\n  }\r\n}<\/code><\/pre>\n<p>Now test it in GitHub Copilot with prompts like:<\/p>\n<ul>\n<li>&#8220;What&#8217;s the weather in Seattle?&#8221;<\/li>\n<li>&#8220;Give me a random number between 1 and 100&#8221;<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2025\/07\/mcp-tools-demo.png\" alt=\"Screenshot showing VS Code with MCP server tools available in GitHub Copilot\" \/><\/p>\n<h2>\ud83d\udccb Configuring for NuGet Publication<\/h2>\n<p>Update your <a href=\"https:\/\/github.com\/modelcontextprotocol\/registry\/blob\/main\/docs\/server-json\/README.md\"><code>.mcp\/server.json<\/code><\/a> file to declare inputs and metadata:<\/p>\n<pre><code class=\"language-json\">{\r\n  \"description\": \"A sample MCP server with weather and random number tools\",\r\n  \"name\": \"io.github.yourusername\/SampleMcpServer\", \r\n  \"packages\": [\r\n    {\r\n      \"registry_name\": \"nuget\",\r\n      \"name\": \"YourUsername.SampleMcpServer\",\r\n      \"version\": \"1.0.0\",\r\n      \"package_arguments\": [],\r\n      \"environment_variables\": [\r\n        {\r\n          \"name\": \"WEATHER_CHOICES\",\r\n          \"description\": \"Comma separated list of weather descriptions\",\r\n          \"is_required\": true,\r\n          \"is_secret\": false\r\n        }\r\n      ]\r\n    }\r\n  ],\r\n  \"repository\": {\r\n    \"url\": \"https:\/\/github.com\/yourusername\/SampleMcpServer\",\r\n    \"source\": \"github\"\r\n  },\r\n  \"version_detail\": {\r\n    \"version\": \"1.0.0\"\r\n  }\r\n}<\/code><\/pre>\n<p>Also update your <code>.csproj<\/code> file with a unique <code>&lt;PackageId&gt;<\/code>:<\/p>\n<pre><code class=\"language-xml\">&lt;PackageId&gt;YourUsername.SampleMcpServer&lt;\/PackageId&gt;<\/code><\/pre>\n<h2>\ud83d\ude80 Publishing to NuGet<\/h2>\n<p>Now for the exciting part \u2014 publishing to NuGet!<\/p>\n<h3>Step 1: Pack Your Project<\/h3>\n<pre><code class=\"language-bash\">dotnet pack -c Release<\/code><\/pre>\n<h3>Step 2: Publish to NuGet<\/h3>\n<pre><code class=\"language-bash\">dotnet nuget push bin\/Release\/*.nupkg --api-key &lt;your-api-key&gt; --source https:\/\/api.nuget.org\/v3\/index.json<\/code><\/pre>\n<blockquote><p>\ud83d\udca1 <strong>Tip<\/strong>: Want to test first? Use the NuGet test environment at <a href=\"https:\/\/int.nugettest.org\">int.nugettest.org<\/a> before publishing to production.<\/p><\/blockquote>\n<h2>\ud83d\udd0d Discovering and Using MCP Servers<\/h2>\n<p>Once published, your MCP server becomes discoverable on NuGet.org:<\/p>\n<ol>\n<li><strong>Search<\/strong>: Visit <a href=\"https:\/\/www.nuget.org\/packages?packagetype=mcpserver\">NuGet.org<\/a> and filter by <code>mcpserver<\/code> package type<\/li>\n<li><strong>Explore<\/strong>: View package details and copy the configuration from the &#8220;MCP Server&#8221; tab<\/li>\n<li><strong>Install<\/strong>: Add the configuration to your <code>.vscode\/mcp.json<\/code> file<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2025\/07\/nuget-mcp-search.png\" alt=\"Screenshot showing MCP server search results on NuGet.org\" \/><\/p>\n<p>The generated configuration looks like this:<\/p>\n<pre><code class=\"language-json\">{\r\n  \"inputs\": [\r\n    {\r\n      \"type\": \"promptString\",\r\n      \"id\": \"weather-choices\",\r\n      \"description\": \"Comma separated list of weather descriptions\",\r\n      \"password\": false\r\n    }\r\n  ],\r\n  \"servers\": {\r\n    \"YourUsername.SampleMcpServer\": {\r\n      \"type\": \"stdio\", \r\n      \"command\": \"dnx\",\r\n      \"args\": [\r\n        \"YourUsername.SampleMcpServer\",\r\n        \"--version\",\r\n        \"1.0.0\",\r\n        \"--yes\"\r\n      ],\r\n      \"env\": {\r\n        \"WEATHER_CHOICES\": \"${input:weather-choices}\"\r\n      }\r\n    }\r\n  }\r\n}<\/code><\/pre>\n<p>VS Code will prompt for input values when you first use the MCP server, making configuration seamless for users.<\/p>\n<h2>\ud83d\udd2e What&#8217;s Next?<\/h2>\n<p>With .NET 10 and NuGet as the official support for .NET MCP you&#8217;re now part of a growing ecosystem that&#8217;s transforming how AI assistants interact with the world. The combination of .NET&#8217;s robust libraries and NuGet&#8217;s package management creates endless possibilities for AI extensibility.<\/p>\n<p>This is our first release of the .NET MCP Server project template, and we&#8217;ve started with a very simple scenario. We&#8217;d love to hear what you&#8217;re building, and what you&#8217;d like to see in future releases of the template. Let us know at <a href=\"https:\/\/aka.ms\/dotnet-mcp-template-survey\">https:\/\/aka.ms\/dotnet-mcp-template-survey<\/a>.<\/p>\n<h3>Real-World MCP Server Ideas<\/h3>\n<p>Here are some powerful MCP servers you could build next:<\/p>\n<ul>\n<li><strong>Enterprise Database Gateway<\/strong>: Safely expose SQL Server, PostgreSQL, or MongoDB queries with role-based access<\/li>\n<li><strong>Cloud API Orchestrator<\/strong>: Wrap Azure, AWS, or Google Cloud services for AI-driven infrastructure management<\/li>\n<li><strong>Document Intelligence Hub<\/strong>: Process PDFs, Word docs, and spreadsheets with OCR and content extraction<\/li>\n<li><strong>DevOps Command Center<\/strong>: Automate Git operations, CI\/CD pipelines, and deployment workflows<\/li>\n<li><strong>Data Analytics Engine<\/strong>: Transform CSV files, generate reports, and create visualizations on demand<\/li>\n<\/ul>\n<p>Each of these represents a unique opportunity to bridge AI capabilities with real business needs \u2014 and share your solutions with the entire .NET community through NuGet.<\/p>\n<p>To go further:<\/p>\n<ul>\n<li>\ud83d\udcd8 <strong>Learn More<\/strong>: Explore the <a href=\"https:\/\/github.com\/microsoft\/mcp-dotnet-samples\">Model Context Protocol .NET samples<\/a><\/li>\n<li>\ud83d\udcfa <strong>Watch &amp; Code<\/strong>: Tune in to the <a href=\"https:\/\/dotnet.microsoft.com\/live\/community-standup\">AI &amp; .NET Community StandUp<\/a><\/li>\n<li>\ud83d\udd27 <strong>Get Started<\/strong>: Check out the <a href=\"https:\/\/learn.microsoft.com\/dotnet\/ai\/quickstarts\/build-mcp-server\">MCP documentation<\/a><\/li>\n<\/ul>\n<blockquote><p>.NET + MCP + NuGet = The future of extensible AI \u2728<\/p><\/blockquote>\n<p>Happy building, and welcome to the growing community of MCP server creators!<\/p>\n<h3>\ud83d\udcc3 Resources<\/h3>\n<ul>\n<li><a href=\"https:\/\/learn.microsoft.com\/dotnet\/ai\/get-started-mcp\">Get started with .NET AI and the Model Context Protocol<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/microsoft\/mcp-dotnet-samples\">Model Context Protocol .NET samples<\/a><\/li>\n<li><a href=\"https:\/\/www.nuget.org\/packages?packagetype=mcpserver\">NuGet.org MCP Server Search<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/modelcontextprotocol\/registry\">MCP Registry Documentation<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/dotnet\/core\/whats-new\/dotnet-10\/overview\">What&#8217;s new in .NET 10<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to create a Model Context Protocol (MCP) server using .NET 10 and publish it to NuGet \u2014 making AI capabilities discoverable and reusable across the ecosystem.<\/p>\n","protected":false},"author":551,"featured_media":57310,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685,7781,756],"tags":[568,58,63,8032,104],"class_list":["post-57309","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-ai","category-csharp","tag-ai","tag-csharp","tag-dotnet","tag-mcp","tag-nuget"],"acf":[],"blog_post_summary":"<p>Learn how to create a Model Context Protocol (MCP) server using .NET 10 and publish it to NuGet \u2014 making AI capabilities discoverable and reusable across the ecosystem.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/57309","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/551"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=57309"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/57309\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/57310"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=57309"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=57309"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=57309"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}