Testing MCP server integration with Claude Desktop
In this post I'm going to experiment with adding a simple Model Context Protocol integration to my PoC project - SavingsOnDapr.
I was planning to play with MCP protocol since the announcement of Dapr Agents last month (CNCF | Dapr Agents) but I just wasn’t sure where to start… And just recently I’ve found this post on Will Velida’s blog and got inspired to test the same approach with SavingsOnDapr Dashboard API which was designed to act as a backend-for-frontend for .NET Blazor web app.
What I was mostly curious about is how robust AI Agent can get with a thin wrapper over API endpoints designed for a different purpose. I must admit I’m still a bit skeptical about AI revolution in its current shape and one thing I deem a must-have for AI adoption is a seamless integration with existing systems.
So, the main thing I want to check in this post is whether AI Agent could do something useful with the currency exchange data that is used to render bar charts on the Currency Exchange Dashboard (example below).
Console app as a local MCP server
Following the steps described by Will I’m going to create a simple console app that would act as a local MCP server. The main dependency in .NET is MCP C# SDK provided in this NuGet package (currently in preview): MCP NuGet.
The code that does most of the magic looks as follows:
In the top part of CurrencyExchangeTools
class definition you can see API description in natural language, similar to what could be found in any technical documentation.
In my initial experiment I focused only on a query endpoint, just to give a read-only access to AI Agent. I also decided to hide some complexity of the Dashboard API which has separate endpoints for initiating the currency-exchange-summary query (POST request) and fetching the results (GET request). In the wrapper there is just one endpoint with a hardcoded delay between POST and GET calls.
Another thing worth mentioning is that Dashboard API returns results in a specific JSON format (columnNames header followed by columnValues arrays to reduce the payload overhead) and that gets transformed by MCP API into a simplified plain text format with entries for each day separated by “———” delimiters. I haven’t tested yet if there is any difference in how these results are processed by the chatbot, I suppose returning the original JSON could work as well.
Apart from the MCP tool implementation we need to add just a couple of lines of code to our console app:
var builder = Host.CreateEmptyApplicationBuilder(settings: null);
// Create the MCP Server with Standard I/O Transport and Tools from the current assembly
builder.Services.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
builder.Logging.AddConsole(options =>
{
options.LogToStandardErrorThreshold = LogLevel.Trace;
});
var app = builder.Build();
Basically, we need to add McpServer with Stdio Transport Protocol and redirect all the standard traces to stderr output.
Testing local MCP server with Claude Desktop
In order to let AI Agent (Claude Desktop in this case) know that there is a tool it could use, we need to add an entry to claude_desktop_config.json:
{
"mcpServers": {
"mcp-sod-server": {
"command": "dotnet",
"args": [
"run",
"--project",
"D:\\dev_src\\savingsondapr-mcp
\\SavingsOnDapr.MCP.Console\\SavingsOnDapr.MCP.Console.csproj",
"--no-build"
]
}
}
}
We are instructing Claude that it should run a dotnet console app from the csproj file. After running Claude Desktop the list of registered MCP tools could be found by clicking the hammer icon. In my case the list looks as follows:
During one of my initial tests with Claude Desktop I forgot to run SavingsOnDapr system which made Claude jump into a “troubleshooting” mode:
That’s an interesting observation because it shows the well known tendency of chatbots to be overly helpful and hyper-creative. I’m not sure if Claude can just ask follow-up questions when the MCP tool specs are not clear enough or the response is unexpected but the suggestions it listed at the end are quite spot on.
Let’s take a look at a “happy path” scenarios when the system is running:
I asked Claude to compare the Currency Exchange statistics for April (to be deduced that I meant April 2025) with the data from Q1 2025. In the attached MCP request box I can see it asked for the full date range in a single request (`endDate`: `2025-04-27`, `startDate`: `2025-01-01`,…) and carried on with the analysis of the retrieved data set. My question was quite vague but it managed to come up with some clever way of interpreting the data (monthly total sum + daily average).
One of the other tests I did was a simpler question that leaves less room for “creativity”:
Once again, that’s a correct and concise answer prepared using the data from MCP endpoint. 💯
To sum up, I must say I was quite impressed with the capabilities unlocked simply by providing 4 short sentences of description to the generic AI agent. The instant effect of chatbot being fully familiarized with the API you’ve built is quite amazing.
That being said, there are at least 3 areas that I would like to explore further:
integrating with a MCP Web API (I saw extensions for Asp.Net Core app builder but haven’t found a getting started tutorial yet)
integrating MCP with Dapr Agents (from what I know the work on MCP support is in progress)
allowing agents to run commands (write access) via the dedicated API.
That’s all for this post - the code of MCP console app can be found here: https://github.com/szymon-bernad/savingsondapr-mcp/