Skip to main content

Building our first MCP Resources enabled MCP Server with C#–Advanced

This is a follow-up on an earlier post where I demonstrated how to build your own MCP server in C# and expose one or more MCP resources.

Today we dive a little bit deeper and look at some more advanced features you can add to your MCP server implementation.

Working with complex return types

Resources can return various types. Here are some advanced examples:

Return values from resource methods can be strings (for simple text), ReadResourceResult (for full control), or other types that the SDK automatically marshals into the appropriate format.

Dependency injection

Resources can use dependency injection to access services:

We changed our implementation to use instance methods (not static). Now we need to register the class in Program.cs:

Progress reporting

For long-running operations, you can report progress:

IProgress parameters accepting ProgressNotificationValue values enable progress reporting from resources to clients, with progress notifications propagating to the client if they included a ProgressToken in their request.


Binary resources

You can also return binary content by using a BlobResourceContents type and providing a base64 encoded version of our blob:

Remote Deployment with SSE

For remote deployment, you can use Server-Sent Events (SSE) or HTTP streaming with ASP.NET Core, enabling your MCP server to be accessible over HTTP.

First install an extra NuGet package:

dotnet add package ModelContextProtocol.AspNetCore --prerelease

Then you need to update your Program.cs:

You can now publish the server as a self-contained, ahead-of-time compiled native application, creating small executables that run without requiring the .NET runtime.

More information

If you are looking for an end-2-end example showing all the features I demonstrated, have a look at my GitHub repo:

Popular posts from this blog

Podman– Command execution failed with exit code 125

After updating WSL on one of the developer machines, Podman failed to work. When we took a look through Podman Desktop, we noticed that Podman had stopped running and returned the following error message: Error: Command execution failed with exit code 125 Here are the steps we tried to fix the issue: We started by running podman info to get some extra details on what could be wrong: >podman info OS: windows/amd64 provider: wsl version: 5.3.1 Cannot connect to Podman. Please verify your connection to the Linux system using `podman system connection list`, or try `podman machine init` and `podman machine start` to manage a new Linux VM Error: unable to connect to Podman socket: failed to connect: dial tcp 127.0.0.1:2655: connectex: No connection could be made because the target machine actively refused it. That makes sense as the podman VM was not running. Let’s check the VM: >podman machine list NAME         ...

Azure DevOps/ GitHub emoji

I’m really bad at remembering emoji’s. So here is cheat sheet with all emoji’s that can be used in tools that support the github emoji markdown markup: All credits go to rcaviers who created this list.

Cleaner switch expressions with pattern matching in C#

Ever find yourself mapping multiple string values to the same result? Being a C# developer for a long time, I sometimes forget that the C# has evolved so I still dare to chain case labels or reach for a dictionary. Of course with pattern matching this is no longer necessary. With pattern matching, you can express things inline, declaratively, and with zero repetition. A small example I was working on a small script that should invoke different actions depending on the environment. As our developers were using different variations for the same environment e.g.  "tst" alongside "test" , "prd" alongside "prod" .  We asked to streamline this a long time ago, but as these things happen, we still see variations in the wild. This brought me to the following code that is a perfect example for pattern matching: The or keyword here is a logical pattern combinator , not a boolean operator. It matches if either of the specified pattern...