How I Created a Handy MCP Server in C# to Retrieve NuGet Package Information
Dmitry Dorogoy

Dmitry Dorogoy @dimonsmart

Location:
Malaga, Spain
Joined:
Dec 26, 2017

How I Created a Handy MCP Server in C# to Retrieve NuGet Package Information

Publish Date: Jun 3
4 3

User: What time is it right now?

LLM: Um... I actually don't know. I have no idea what time it is.

User: Okay, let's give you some tools. (Clock, Compass and a thermometer)

LLM: I think this clock can be useful. Where are the hands pointing?

User: The small hand is at 9. The big hand is at 12. What time is it right now?

LLM: Now I know the time. It is 9:00.

🎉

In this little analogy, the Large Language Model (LLM) couldn’t answer a simple question because it lacked external tools. Only after the user provided a clock (with maybe other tools) the LLM could get the current time and respond correctly. This story illustrates a key idea in modern AI assistants: function calling, or letting an AI to use external functions/tools to get accurate information. In other words - "look out of the box"

Function Calling and why we Need the MCP protocol?

The dialogue above is similar to how new AI assistants can use functions. Instead of guessing or making things up, the AI can call a tool (for example, a clock function) to get the real answer. This method is useful for many types of questions, from checking the time to reading files or calling APIs.

However, to make this work in a consistent way across different tools and platforms, we need a standard protocol. This is where MCP comes in. Model Context Protocol (MCP) is an open standard that lets AI models interact with external tools and services through a unified interface. In simple terms, MCP defines how an AI (or its hosting environment) can discover what tools are available and call those tools with certain parameters, getting back results in a fixed format. Many IDEs and AI platforms (like VS Code’s GitHub Copilot agent mode) support MCP to enable AI-driven development helpers.

How MCP Works (A Quick Example)

MCP messages are typically in JSON. Let’s revisit the clock scenario in technical terms. Suppose the user asks, “What time is it?” The AI, using MCP, would make a tool call request to an MCP server that has a clock tool:

{
  "name": "GetCurrentTime",
  "parameters": {}
}
Enter fullscreen mode Exit fullscreen mode

This JSON request means “call the function named **GetCurrentTime* with no parameters.”* An MCP-compatible server that provides a clock tool would recognize this and return a result:

{
  "result": "2025-06-03T14:42:41Z"
}
Enter fullscreen mode Exit fullscreen mode

Here, the result is the current time in a standard format (ISO 8601 UTC). The AI can then use this result to answer the user’s question accurately.

Now, consider a slightly different query: “What time is it in Madrid?” If our clock tool allowed a location or timezone parameter, the interaction could look like this:

{
  "name": "GetTime",
  "parameters": { "timezone": "Madrid" }
}
Enter fullscreen mode Exit fullscreen mode

And the server might respond:

{
  "result": "2025-06-03T16:42:41+02:00"
}
Enter fullscreen mode Exit fullscreen mode

In this hypothetical response, the time is adjusted for Madrid’s timezone (UTC+2). The key point is that MCP enables passing parameters to tools so the AI can get exactly the info it needs. The protocol handles listing available tools, invoking them, and returning results in a consistent JSON structure.

Hallucinations in Code Generation: A Real Problem

So why did I bother creating a custom MCP server for NuGet packages? Because LLMs hallucinate — especially when writing code. If you’ve ever used an AI coding assistant, you may have seen it confidently call functions that don’t exist or use the wrong parameters for a library. This tends to happen with APIs that the model wasn’t trained on or that have changed over time.

For example, with NuGet packages (which are constantly evolving), an AI might:

  • Suggest outdated methods or interfaces that were removed in newer versions
  • Invent non-existent API calls that “sound” plausible but aren’t real
  • Mix up version differences, using an API from a different version than the one you have
  • Provide incomplete information, missing important parameters or return details

Such hallucinations can lead to code that doesn’t compile or bugs that are hard to trace. It wastes a developer’s time and erodes trust in the AI assistant.

A Solution: An MCP Server for NuGet Package Info

To tackle this, I built DimonSmart.NugetMcpServer – a small MCP server that gives AI assistants accurate, up-to-date information about NuGet package APIs. Instead of relying on the language model’s knowledge (which might be outdated or wrong), the AI can call my MCP server to get the real data straight from the NuGet package. In other words, the AI asks the server about a package’s interfaces, methods or enums, and the server downloads the package (from nuget.org), inspects its assemblies, and returns the actual definitions. This greatly reduces hallucinations by providing precise API details from the source.

What does the NuGet MCP server do? It currently focuses on interfaces and enums (for now. I'm going to extend). Key features include:

  • Retrieve a specific interface’s definition from a given package (including all its methods, properties, XML docs, etc.).
  • List all interfaces in a package, so you can discover what it offers.
  • Retrieve an enum’s definition from the package.
  • Support specifying a version of the package (or default to the latest) for version-specific info.
  • Properly handle generic types and format everything as valid C# code.
  • Communicate via standard input/output (STDIO) using the MCP JSON protocol, which means it plugs into tools like VS Code easily.

In essence, it’s like a specialized “package inspector” tool that the AI can use whenever it needs authoritative info about a NuGet library’s API. No more guessing what methods FooClient has or what properties interface IBarService includes – the MCP server will tell the AI exactly what’s in the package.

How It’s Built (C# with MCP Library)

I built an MCP server in C# and found it very easy, thanks to the ModelContextProtocol.Server library (v0.2.0 preview). I follow the library’s rules to create tools. I write a C# method and add special attributes so it becomes an MCP tool. Then the server automatically finds these tools when it runs.

For example, here’s a minimal tool that I included for testing – it provides the current time (like our earlier clock analogy):

[McpServerToolType]
public static class TimeTool
{
    [McpServerTool, Description("Returns the current server time in ISO 8601 format (YYYY-MM-DDThh:mm:ssZ).")]
    public static string GetCurrentTime()
    {
        return DateTime.UtcNow.ToString("o");
    }
}
Enter fullscreen mode Exit fullscreen mode

This sample does the following:

  • The [McpServerToolType] attribute marks the class as a container for tool functions.
  • The [McpServerTool] attribute (on the method) exposes that method as an available tool to the MCP client, and the Description provides a human-readable (LLM-Readable 😀) description of what it does.
  • The method itself GetCurrentTime() simply returns the server’s current time as a string. (Notice we format it as string in a standard way "o" for ISO8601 UTC time).

When the MCP server runs, it will automatically find this tool and advertise it to clients. An AI could then invoke GetCurrentTime just like in our earlier JSON example.

Now, the NuGet-focused tools in NugetMcpServer are built with the same pattern. They are just a bit more involved internally: they download the NuGet package, load the .dll, and extract the type info. Here are the main tools provided:

  • ListInterfaces(packageId, version?) – Lists all public interfaces in the specified package (and version). This returns a list of interface names (and some metadata) so you know what’s available.
  • GetInterfaceDefinition(packageId, interfaceName, version?) – Returns the full C# definition of a given interface from the package. You provide the package name and the interface you’re interested in, and it gives you the code (methods, properties, XML comments, etc.) as one big string result.
  • GetEnumDefinition(packageId, enumName, version?) – Similarly, returns the complete definition of an enum type from the package.

Each of these is implemented as an MCP tool with the same attribute approach. For instance, GetInterfaceDefinition is a method decorated with [McpServerTool] and it returns a string containing the interface’s code. Under the hood, it uses a helper service to format the interface nicely (with proper C# syntax) and ensure things like generic type parameters are rendered correctly.

The server uses .NET’s Generic Host with an STDIO transport, meaning it runs as a console app that reads JSON requests from stdin and writes JSON responses to stdout. This makes it easy to plug into VS Code or any other MCP client. The discovery of tools is automatic – thanks to the attributes, the ModelContextProtocol library finds all tools and lists them for the client. So as soon as you run the server, a client can ask it “what tools do you have?” and it will respond with something like “GetInterfaceDefinition, ListInterfaces, GetEnumDefinition, GetCurrentTime,” along with their parameter schemas.

Installation and Usage in VS Code

One of my goals was to make this tool easy to set up and try out. I’m happy to say that NugetMcpServer is available on WinGet, so Windows users can install it with a single command. For example, in a PowerShell or terminal, run:

winget install DimonSmart.NugetMcpServer
Enter fullscreen mode Exit fullscreen mode

This will download and install the latest NugetMcpServer release. DimonSmart.NugetMcpServer alias added automatically, so you can launch it from anywhere (no need to add .exe). By default it uses port-less STDIO, so you don’t have to worry about networking – it just sits and waits for JSON on stdin.

Using it in VS Code (Copilot Agent Mode): If you have GitHub Copilot enabled with the new agent/chat mode, you can add this server as an MCP tool provider. The process is simple (and only needs to be done once): open your VS Code settings, search for “MCP”, and add a new MCP server configuration pointing to NugetMcpServer. (VS Code’s official docs have a section on how to add MCP servers if you need guidance.) Once added, your AI assistant in VS Code can invoke the NuGet tools whenever it gets a related query. For example, if you ask in Copilot chat “Show me what interfaces are in the Foo.Bar package”, Copilot can call ListInterfaces from the server and give you a real answer instead of guessing.

It’s worth noting that to my knowledge this project is one of the first precompiled MCP servers readily available. Many existing MCP tool examples were scripts or needed building from source. By publishing on WinGet, I wanted to ensure anyone can quickly grab a ready-to-run server and immediately enhance their AI dev experience.

Future Plans and Feedback

This project is still in progress. I have a lot of ideas to make AI-assisted development even smoother. For instance, I’m considering adding a feature to search for NuGet packages by description or keywords – imagine asking the AI “Is there a NuGet package for generating QR codes?” and the MCP server could suggest relevant packages by querying NuGet’s catalog. This could help with discovery of libraries, not just usage of known ones.

I’d love to hear feedback, suggestions, or wild ideas from readers like you! Feel free to check out the project’s GitHub repo (linked below) – issues and pull requests are welcome.

Links:

Finally, the project is open-source with a very permissive license. This means you can use it, integrate it, or modify it without worrying about restrictions. I hope this MCP server sparks some ideas and helps make your AI coding sessions more productive and less frustrating. Happy coding!

Comments 3 total

Add comment