{"id":"a92e5378-909d-4435-8ce5-e22d4f48c3dc","shortId":"V92CAn","kind":"skill","title":"dotnet-mcp-builder","tagline":"Build Model Context Protocol (MCP) servers in C#/.NET against the current ModelContextProtocol 1.x NuGet packages. Especially helps with cases the model often gets wrong without guidance — stale preview versions (it tends to pick 0.3 or 0.4 preview), MCP Apps (interactive UI rend","description":"# Building MCP servers in .NET\n\nThis skill helps you write production-quality MCP servers and basic clients in C#/.NET against the **official** [`ModelContextProtocol`](https://www.nuget.org/profiles/ModelContextProtocol) NuGet packages, maintained by Microsoft and the MCP project. It targets the **stable 1.x** line and the current spec (2025-11-25).\n\n## When this skill earns its keep\n\nThe .NET MCP SDK had years of preview packages (`0.x-preview`) before reaching `1.0`. Without help, the model tends to:\n- Pin a stale preview version that won't compile against current samples.\n- Miss recent spec features (elicitation URL mode, MCP Apps, structured content blocks).\n- Get HTTP transport details wrong (stateful/stateless, proxy buffering, OAuth wiring).\n- Forget the STDIO stdout/stderr trap.\n\nIf the task is one of those, *load the matching reference* and follow it. If it's truly trivial (e.g. \"rename this tool method\"), you don't need to read everything — the cardinal rules below are the minimum.\n\n## Mental model in 30 seconds\n\nA .NET MCP server is an ordinary `Microsoft.Extensions.Hosting` (or `WebApplication`) app that wires an MCP server through DI:\n\n```csharp\nbuilder.Services\n    .AddMcpServer()\n    .WithStdioServerTransport()      // OR .WithHttpTransport(...)\n    .WithToolsFromAssembly()         // discover [McpServerToolType] classes\n    .WithPrompts<MyPrompts>()        // optional\n    .WithResources<MyResources>();   // optional\n```\n\nPrimitives are plain C# methods on classes marked with attributes (`[McpServerToolType]` + `[McpServerTool]`, `[McpServerPromptType]` + `[McpServerPrompt]`, `[McpServerResourceType]` + `[McpServerResource]`). Parameters bind from JSON-RPC; the SDK builds the JSON Schema from the signature plus `[Description]` attributes.\n\nServer-to-client features (sampling, elicitation, roots, log/progress notifications) are methods on the injected `IMcpServer`.\n\n## Decision tree → which references to load\n\nAlways load `references/packages.md` if you're creating a new project or unsure of the current package version.\n\n| Task | Load |\n|---|---|\n| New STDIO server | `references/transport-stdio.md` |\n| New HTTP (Streamable) server | `references/transport-http.md` |\n| Add/modify a tool | `references/tool-primitive.md` |\n| Add/modify a prompt | `references/prompt-primitive.md` |\n| Add/modify a resource | `references/resource-primitive.md` |\n| Ask the user a question mid-tool | `references/elicitation.md` |\n| Call the client's LLM from a tool | `references/sampling.md` |\n| Read the user's project roots | `references/roots.md` |\n| Return an interactive UI | `references/mcp-apps.md` |\n| Argument completions, log/progress notifications, filters, server instructions | `references/server-features.md` |\n| Write a .NET program that **consumes** an MCP server | `references/client.md` |\n| MCP Inspector, in-memory tests, mocks, CI | `references/testing.md` |\n\nFor multi-primitive tasks, load several at once. For trivial edits in an existing file, you usually don't need any.\n\n## Cardinal rules (apply always; these prevent the highest-frequency breakages)\n\n1. **Pin the current stable package, not a preview.** Use `ModelContextProtocol` / `ModelContextProtocol.AspNetCore` / `ModelContextProtocol.Core` at the latest **1.x**. If you find yourself writing `0.3-preview` or `0.4-preview`, stop and check NuGet — preview APIs have breaking differences.\n2. **STDIO servers must not write to stdout.** Stdout is the JSON-RPC channel. Configure `LogToStandardErrorThreshold = LogLevel.Trace` before anything else and never `Console.WriteLine` from a tool.\n3. **HTTP defaults to stateful.** For horizontally-scaled deployments without server-initiated traffic, set `options.Stateless = true`. Server-to-client features (sampling, elicitation, roots, unsolicited notifications) require stateful HTTP **or** STDIO — `Stateless = true` will break them at runtime.\n4. **SSE-only is deprecated.** Use Streamable HTTP. Only enable legacy SSE (`EnableLegacySse = true`) for an old client you must support, and call it out.\n5. **Always `[Description]` tools and parameters.** This is what the LLM sees when picking and shaping calls. Vague descriptions are the #1 reason tools don't get used.\n6. **Show the registration line every time you add a primitive.** A new `[McpServerPromptType]` class without `.WithPrompts<...>()` (or `.WithPromptsFromAssembly()`) is invisible.\n7. **Don't invent APIs.** If you're unsure a method exists, say so and check the [API reference](https://csharp.sdk.modelcontextprotocol.io/api/ModelContextProtocol.html) — wrong method names cause silent failures.\n\n## Working style\n\n- **Make minimal, additive changes.** Add a method to the existing tool class rather than restructuring the project.\n- **For non-trivial setups, run `dotnet build`.** Catches missing usings, attribute typos, and TFM mismatches before the user sees them.\n- **Confirm transport + .NET version + primitives before scaffolding** if context doesn't already make them obvious. Default to **.NET 10** for new projects.\n\n## When the user is stuck\n\nWalk this checklist before guessing:\n1. **STDIO:** something is writing to stdout (logger sink, `Console.WriteLine`, library banner).\n2. **HTTP 404:** path mismatch — `app.MapMcp()` is root, `app.MapMcp(\"/mcp\")` puts it under `/mcp`.\n3. **Tool not appearing:** missing `[McpServerToolType]` on the class, or no `.WithToolsFromAssembly()` / `.WithTools<T>()` registered.\n4. **Args not bound:** parameter names must match the JSON-RPC `arguments` keys; complex types bind via `System.Text.Json`.\n5. **Sampling/elicitation/roots failing:** transport is stateless HTTP, or the client doesn't advertise the capability.\n\nStill stuck? Point the user at the [`EverythingServer`](https://github.com/modelcontextprotocol/csharp-sdk/tree/main/samples/EverythingServer) sample — it exercises every feature.","tags":["dotnet","mcp","builder","awesome","copilot","github","agent-skills","agents","custom-agents","github-copilot","hacktoberfest","prompt-engineering"],"capabilities":["skill","source-github","skill-dotnet-mcp-builder","topic-agent-skills","topic-agents","topic-awesome","topic-custom-agents","topic-github-copilot","topic-hacktoberfest","topic-prompt-engineering"],"categories":["awesome-copilot"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/github/awesome-copilot/dotnet-mcp-builder","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add github/awesome-copilot","source_repo":"https://github.com/github/awesome-copilot","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 33270 github stars · SKILL.md body (5,882 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:52:10.274Z","embedding":null,"createdAt":"2026-05-11T00:52:22.273Z","updatedAt":"2026-05-18T18:52:10.274Z","lastSeenAt":"2026-05-18T18:52:10.274Z","tsv":"'-11':98 '-25':99 '/.net':13,69 '/api/modelcontextprotocol.html)':628 '/mcp':728,732 '/modelcontextprotocol/csharp-sdk/tree/main/samples/everythingserver)':791 '/profiles/modelcontextprotocol)':76 '0':115 '0.3':40,451 '0.4':42,454 '1':18,90,428,444,579,707 '1.0':121 '10':693 '2':465,719 '2025':97 '3':492,733 '30':208 '4':532,747 '404':721 '5':558,766 '6':586 '7':607 'add':594,641 'add/modify':326,330,334 'addit':639 'addmcpserv':230 'advertis':778 'alreadi':686 'alway':298,420,559 'anyth':484 'api':461,611,624 'app':45,148,220 'app.mapmcp':724,727 'appear':736 'appli':419 'arg':748 'argument':368,759 'ask':338 'attribut':251,275,665 'banner':718 'basic':65 'bind':259,763 'block':151 'bound':750 'break':463,528 'breakag':427 'buffer':159 'build':5,49,266,661 'builder':4 'builder.services':229 'c':12,68,245 'call':347,555,574 'capabl':780 'cardin':199,417 'case':25 'catch':662 'caus':632 'chang':640 'channel':479 'check':458,622 'checklist':704 'ci':393 'class':237,248,600,648,741 'client':66,279,349,513,550,775 'compil':136 'complet':369 'complex':761 'configur':480 'confirm':675 'console.writeline':488,716 'consum':381 'content':150 'context':7,683 'creat':304 'csharp':228 'csharp.sdk.modelcontextprotocol.io':627 'csharp.sdk.modelcontextprotocol.io/api/modelcontextprotocol.html)':626 'current':16,95,138,312,431 'decis':292 'default':494,690 'deploy':501 'deprec':537 'descript':274,560,576 'detail':155 'di':227 'differ':464 'discov':235 'doesn':684,776 'dotnet':2,660 'dotnet-mcp-build':1 'e.g':186 'earn':103 'edit':406 'elicit':144,282,516 'els':485 'enabl':542 'enablelegacyss':545 'especi':22 'everi':591,795 'everyth':197 'everythingserv':788 'exercis':794 'exist':409,618,646 'fail':768 'failur':634 'featur':143,280,514,796 'file':410 'filter':372 'find':448 'follow':179 'forget':162 'frequenc':426 'get':29,152,584 'github.com':790 'github.com/modelcontextprotocol/csharp-sdk/tree/main/samples/everythingserver)':789 'guess':706 'guidanc':32 'help':23,56,123 'highest':425 'highest-frequ':424 'horizont':499 'horizontally-sc':498 'http':153,322,493,522,540,720,772 'imcpserv':291 'in-memori':388 'initi':505 'inject':290 'inspector':387 'instruct':374 'interact':46,365 'invent':610 'invis':606 'json':262,268,477,757 'json-rpc':261,476,756 'keep':105 'key':760 'latest':443 'legaci':543 'librari':717 'line':92,590 'llm':351,568 'load':174,297,299,316,400 'log/progress':284,370 'logger':714 'loglevel.trace':482 'logtostandarderrorthreshold':481 'maintain':79 'make':637,687 'mark':249 'match':176,754 'mcp':3,9,44,50,62,84,108,147,212,224,383,386 'mcpserverprompt':255 'mcpserverprompttyp':254,599 'mcpserverresourc':257 'mcpserverresourcetyp':256 'mcpservertool':253 'mcpservertooltyp':236,252,738 'memori':390 'mental':205 'method':190,246,287,617,630,643 'microsoft':81 'microsoft.extensions.hosting':217 'mid':344 'mid-tool':343 'minim':638 'minimum':204 'mismatch':669,723 'miss':140,663,737 'mock':392 'mode':146 'model':6,27,125,206 'modelcontextprotocol':17,73,438 'modelcontextprotocol.aspnetcore':439 'modelcontextprotocol.core':440 'multi':397 'multi-primit':396 'must':468,552,753 'name':631,752 'need':194,415 'net':53,107,211,378,677,692 'never':487 'new':306,317,321,598,695 'non':656 'non-trivi':655 'notif':285,371,519 'nuget':20,77,459 'oauth':160 'obvious':689 'offici':72 'often':28 'old':549 'one':171 'option':239,241 'options.stateless':508 'ordinari':216 'packag':21,78,114,313,433 'paramet':258,563,751 'path':722 'pick':39,571 'pin':128,429 'plain':244 'plus':273 'point':783 'prevent':422 'preview':34,43,113,118,131,436,452,455,460 'primit':242,398,596,679 'product':60 'production-qu':59 'program':379 'project':85,307,360,653,696 'prompt':332 'protocol':8 'proxi':158 'put':729 'qualiti':61 'question':342 'rather':649 're':303,614 'reach':120 'read':196,356 'reason':580 'recent':141 'refer':177,295,625 'references/client.md':385 'references/elicitation.md':346 'references/mcp-apps.md':367 'references/packages.md':300 'references/prompt-primitive.md':333 'references/resource-primitive.md':337 'references/roots.md':362 'references/sampling.md':355 'references/server-features.md':375 'references/testing.md':394 'references/tool-primitive.md':329 'references/transport-http.md':325 'references/transport-stdio.md':320 'regist':746 'registr':589 'renam':187 'rend':48 'requir':520 'resourc':336 'restructur':651 'return':363 'root':283,361,517,726 'rpc':263,478,758 'rule':200,418 'run':659 'runtim':531 'sampl':139,281,515,792 'sampling/elicitation/roots':767 'say':619 'scaffold':681 'scale':500 'schema':269 'sdk':109,265 'second':209 'see':569,673 'server':10,51,63,213,225,277,319,324,373,384,467,504,511 'server-initi':503 'server-to-cli':276,510 'set':507 'setup':658 'sever':401 'shape':573 'show':587 'signatur':272 'silent':633 'sink':715 'skill':55,102 'skill-dotnet-mcp-builder' 'someth':709 'source-github' 'spec':96,142 'sse':534,544 'sse-on':533 'stabl':89,432 'stale':33,130 'state':496,521 'stateful/stateless':157 'stateless':525,771 'stdio':164,318,466,524,708 'stdout':472,473,713 'stdout/stderr':165 'still':781 'stop':456 'streamabl':323,539 'structur':149 'stuck':701,782 'style':636 'support':553 'system.text.json':765 'target':87 'task':169,315,399 'tend':37,126 'test':391 'tfm':668 'time':592 'tool':189,328,345,354,491,561,581,647,734 'topic-agent-skills' 'topic-agents' 'topic-awesome' 'topic-custom-agents' 'topic-github-copilot' 'topic-hacktoberfest' 'topic-prompt-engineering' 'traffic':506 'transport':154,676,769 'trap':166 'tree':293 'trivial':185,405,657 'true':509,526,546 'truli':184 'type':762 'typo':666 'ui':47,366 'unsolicit':518 'unsur':309,615 'url':145 'use':437,538,585,664 'user':340,358,672,699,785 'usual':412 'vagu':575 'version':35,132,314,678 'via':764 'walk':702 'webappl':219 'wire':161,222 'withhttptransport':233 'without':31,122,502,601 'withprompt':238,602 'withpromptsfromassembl':604 'withresourc':240 'withstdioservertransport':231 'withtool':745 'withtoolsfromassembl':234,744 'won':134 'work':635 'write':58,376,450,470,711 'wrong':30,156,629 'www.nuget.org':75 'www.nuget.org/profiles/modelcontextprotocol)':74 'x':19,91,117,445 'x-preview':116 'year':111","prices":[{"id":"1d02501b-5d8e-4467-bd60-9da647f146f2","listingId":"a92e5378-909d-4435-8ce5-e22d4f48c3dc","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"github","category":"awesome-copilot","install_from":"skills.sh"},"createdAt":"2026-05-11T00:52:22.273Z"}],"sources":[{"listingId":"a92e5378-909d-4435-8ce5-e22d4f48c3dc","source":"github","sourceId":"github/awesome-copilot/dotnet-mcp-builder","sourceUrl":"https://github.com/github/awesome-copilot/tree/main/skills/dotnet-mcp-builder","isPrimary":false,"firstSeenAt":"2026-05-11T00:52:22.273Z","lastSeenAt":"2026-05-18T18:52:10.274Z"}],"details":{"listingId":"a92e5378-909d-4435-8ce5-e22d4f48c3dc","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"github","slug":"dotnet-mcp-builder","github":{"repo":"github/awesome-copilot","stars":33270,"topics":["agent-skills","agents","ai","awesome","custom-agents","github-copilot","hacktoberfest","prompt-engineering"],"license":"mit","html_url":"https://github.com/github/awesome-copilot","pushed_at":"2026-05-18T01:26:59Z","description":"Community-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.","skill_md_sha":"300277af51525eed9a1fab94b4698f01a197f478","skill_md_path":"skills/dotnet-mcp-builder/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/github/awesome-copilot/tree/main/skills/dotnet-mcp-builder"},"layout":"multi","source":"github","category":"awesome-copilot","frontmatter":{"name":"dotnet-mcp-builder","description":"Build Model Context Protocol (MCP) servers in C#/.NET against the current ModelContextProtocol 1.x NuGet packages. Especially helps with cases the model often gets wrong without guidance — stale preview versions (it tends to pick 0.3 or 0.4 preview), MCP Apps (interactive UI rendered in the host), elicitation URL mode, per-session HTTP wiring, OAuth and reverse-proxy deploy specifics, and debugging concrete MapMcp / STDIO / Streamable-HTTP errors. Also covers the routine work — STDIO and Streamable HTTP transports (SSE is deprecated), tools, prompts, resources, sampling, roots, completions, logging — and a basic .NET MCP client. Trigger when the user says or implies any .NET MCP server work: ModelContextProtocol, McpServerTool, MapMcp, WithStdioServerTransport, \"MCP server in C#\", \"MCP tool in dotnet\", \"expose this as MCP\", or names a primitive (prompt/resource/elicitation/MCP App) in a .NET context. Skip for MCP work in other languages."},"skills_sh_url":"https://skills.sh/github/awesome-copilot/dotnet-mcp-builder"},"updatedAt":"2026-05-18T18:52:10.274Z"}}