Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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:

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.Support on Ko-Fi

Troubleshoot common setup problems

  • The client does not discover the tool: confirm the class has [McpServerToolType], the method has [McpServerTool], and the server calls WithToolsFromAssembly(). 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 build from 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.