Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
To build a local MCP server in C#, create a .NET console app, install ModelContextProtocol and Microsoft.Extensions.Hosting, then configure stdio transport and register a tool class with attributes. For a server that clients reach over HTTP, use ModelContextProtocol.AspNetCore with ASP.NET Core and Streamable HTTP instead. The transport choice affects how the server is launched, hosted, and secured; it is not just a setting to swap at the end.
The examples below follow the C# SDK v2.0 context announced by the .NET team on July 28, 2026, which implements the 2026-07-28 MCP specification revision. Check the current SDK documentation for package versions and API changes before building, because MCP SDK details can change.
Choose the NuGet package and transport
MCP is an open protocol for connecting AI applications with external tools and data. The C# SDK provides client and server building blocks. For most first projects, the general ModelContextProtocol package is the simplest place to start.
| Use case | Starting point | What it means |
|---|---|---|
| A local integration in which an MCP client launches your server process | ModelContextProtocol with stdio |
The client and server communicate through standard input and output. Keep ordinary logs off stdout so they do not corrupt protocol messages. |
| A remotely hosted service available to clients over HTTP | ModelContextProtocol.AspNetCore with Streamable HTTP |
Host the server as an ASP.NET Core application and deploy it with the security and operational controls your service requires. |
| A client or a server needing lower-level APIs and fewer dependencies | ModelContextProtocol.Core |
Provides core APIs without the higher-level hosting and attribute-based setup of the general package. |
The SDK’s current guidance favors Streamable HTTP for remote servers. Older examples may use Server-Sent Events (SSE); the SDK documentation treats SSE as legacy, so choose it for a compatibility reason rather than as the default for a new remote service. HTTP servers default to stateless operation in v2.0. Choose stateful sessions only when you need session-specific capabilities such as subscriptions, unsolicited server-to-client requests, or client isolation.
#1 Best Overall
Build a local stdio server
1. Create the project and install packages
Install the .NET SDK appropriate for your environment, then run these commands in a terminal:
dotnet new console -n MyMcpServer
cd MyMcpServer
dotnet add package ModelContextProtocol
dotnet add package Microsoft.Extensions.Hosting
The general package is the recommended starting choice for most projects. It supports hosting, dependency injection, and attribute-based tool discovery; the hosting package supplies the generic .NET host used by this example.
2. Add the server and one tool
Replace the generated Program.cs with the following complete example:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #2
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;
using System.ComponentModel;
var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddConsole(options =>
{
options.LogToStandardErrorThreshold = LogLevel.Trace;
});
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
await builder.Build().RunAsync();
[McpServerToolType]
public static class EchoTool
{
[McpServerTool, Description("Echoes the message back to the client.")]
public static string Echo(
[Description("The message to return to the caller.")] string message)
=> $"hello {message}";
}
AddMcpServer() registers MCP server services. WithStdioServerTransport() selects local process communication, and WithToolsFromAssembly() discovers the tool type and its marked method. The SDK turns the method’s input information into a tool schema and deserializes the JSON arguments when a client calls it. The returned string is sent as text content.
Descriptions help clients and models understand a tool’s purpose and arguments. Give each tool a narrow, clear name, describe what its inputs mean, and return a predictable result. An attribute exposes a callable function; it does not authorize the caller or validate permissions to any external system your code might access.
3. Build and connect from a client
Build the project with:
dotnet build
Configure your MCP client to launch the built application as a child process using the runtime and arguments appropriate to that client. The exact configuration file and UI differ between clients, so check the documentation for the client you use. Once connected, the client should discover the Echo tool and be able to call it with a message argument. The example’s result for "world" is hello world.
Do not write diagnostic output to standard output: with stdio, stdout is the protocol channel. This example routes console logs to stderr, preserving stdout for MCP traffic.
Free tools Windows power users keep installed
One-click scans. No signup required.
Expose a tool safely and deliberately
A tool is a function an MCP client can ask the server to run. The sample exposes only an echo operation; it does not fetch web pages, access files, or perform actions on behalf of a user. Add capabilities one at a time and decide what each is allowed to touch.
- Use method descriptions and parameter descriptions to communicate purpose and expected inputs.
- Validate inputs in the handler before using them, especially when they control file paths, URLs, database queries, or external actions.
- Apply authorization at the service boundary for operations that access private data or make changes. Tool registration is not an access-control policy.
- Keep credentials in an appropriate secret store or environment-specific configuration, not in tool descriptions or source code.
- Register services in dependency injection when handlers need shared application services. The SDK also supports context, progress reporting, caller identity, delegate registration, and lower-level handlers; use those when the application needs them rather than adding complexity to a first tool.
Build an ASP.NET Core server over HTTP
Choose this path when clients need to reach a hosted service rather than launch a local child process. Install the ASP.NET Core integration package in an ASP.NET Core project:
Rank #4
dotnet new web -n MyMcpHttpServer
cd MyMcpHttpServer
dotnet add package ModelContextProtocol.AspNetCore
The essential shape is to register the MCP server and its tool discovery with the service collection, configure the HTTP transport, and map the MCP endpoint with app.MapMcp(). Keep the same attributed tool class pattern as the local example. The precise transport registration APIs can change with SDK versions; use the current ASP.NET Core transport guide when filling in the registration for the version you install.
In a local HTTP setup, restrict accepted host names to loopback values to reduce DNS-rebinding exposure, as the SDK getting-started guidance advises. Do not assume that binding an HTTP endpoint or knowing its URL makes a public service safe. Production requirements depend on the deployment, but commonly include appropriate authentication and authorization, input validation, secret handling, rate limiting, and host filtering.
Decide between stdio and Streamable HTTP
Use stdio for a local, client-launched tool
Stdio is a natural fit when one user’s MCP client starts the server on that user’s machine. It avoids deploying a shared network service, but each client integration must be able to launch the process with the right runtime, working directory, and environment. Keep stdout reserved for protocol messages and use stderr for logs.
Best Value
Use Streamable HTTP for a hosted service
HTTP is appropriate when multiple clients need to access a service hosted independently of their local machines. It brings ordinary web deployment concerns: endpoint exposure, authentication, authorization, and operational monitoring. In the v2.0 SDK, stateless operation is the default and avoids in-memory transport session tracking, which can make horizontal scaling easier. Stateful sessions remain an option for features that genuinely require session-specific behavior.
Do not choose transport by habit
First decide where the server runs and how clients reach it. A local child-process integration points toward stdio. A remotely operated service points toward Streamable HTTP. Existing clients that require an older SSE integration may justify the legacy transport, but that is a compatibility decision.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshoot common setup problems
- The client does not discover the tool: confirm the class has
[McpServerToolType], the method has[McpServerTool], and the server callsWithToolsFromAssembly(). Check that the tool type is in the assembly being scanned and that the client is launching the project you built. - The client reports a broken or invalid stdio response: remove direct console writes to stdout. Route logs to stderr, as in the sample, and keep protocol output separate from diagnostics.
- A tool call fails to bind its arguments: compare the JSON argument names and value types with the method’s parameter names and types. Add descriptions to clarify meaning, and validate inputs in the handler rather than assuming the schema alone makes every value safe.
- The process exits as soon as it starts: inspect stderr for startup or package errors, verify the configured executable and working directory in the MCP client, and run
dotnet buildfrom the project directory to surface compile errors. - A local HTTP request is rejected because of its host: check the accepted-host configuration and use a loopback host value for a local-only service. Do not remove host filtering to make a public endpoint work; configure the deployment’s host and security controls deliberately.
- An older tutorial’s HTTP example does not match your SDK: check the package version and current SDK documentation. The v2.0 announcement records a specification revision and transport-default changes; preview, v1, and legacy SSE samples may use different APIs or assumptions.
Or skip the browser setup
If your MCP tool needs website screenshots, you can call ScreenshotNeo’s screenshot API instead of building and maintaining browser automation. One GET request returns an image or PDF; use the API documentation for the full parameter list and response details.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for setup and options. ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are never billed. It also provides an MCP server for AI agents, and the free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Learn about ScreenshotNeo or sign up free.
FAQ
Does the echo sample need a separate MCP client?
Yes. The server exposes a tool, but an MCP client must launch or connect to the server and invoke it.
Can a C# tool return something other than text?
The SDK supports more than the string-returning echo shown here. Choose a result shape and handler approach suited to the capability, and consult the current SDK guidance for supported content types and APIs.
Is v2.0 the same as the MCP specification version?
No. The .NET team’s July 28, 2026 announcement identifies C# SDK v2.0 and says it implements the MCP specification revision dated 2026-07-28; these are distinct version labels.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsQuick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

