SubhojeetNeogy/Dotnet-MCP-with-McpSharp
If you are the rightful owner of Dotnet-MCP-with-McpSharp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
This document provides a comprehensive overview of a .NET solution implementing the Model Context Protocol (MCP) using the MCPSharp library.
🚀 .NET MCP with MCPSharp
A complete .NET solution demonstrating the Model Context Protocol (MCP) implementation using the MCPSharp library. This project showcases how to create both MCP servers and clients in .NET, enabling seamless communication between AI models and external tools.
📋 Table of Contents
- 🎯 Overview
- 🏗️ Architecture
- 📁 Project Structure
- 🛠️ Prerequisites
- ⚡ Quick Start
- 🔧 Configuration
- 📚 Usage Examples
- 🔍 API Reference
- 🧪 Testing
- 📦 Dependencies
- 🤝 Contributing
- 📄 License
🎯 Overview
This solution demonstrates a complete MCP implementation with:
- 🔧 MCP Server: A calculator service that exposes mathematical operations as MCP tools
- 📱 MCP Client: A client application that discovers and consumes MCP tools
- 🔄 Communication: JSON-RPC based communication between client and server
- ⚡ Real-time: Asynchronous operations with proper error handling
Key Features
- ✅ Tool Discovery: Automatic discovery of available MCP tools
- ✅ Type Safety: Strongly typed parameters and return values
- ✅ Async Operations: Full async/await support
- ✅ Error Handling: Comprehensive error handling and validation
- ✅ Extensible: Easy to add new tools and functionality
🏗️ Architecture
graph TB
A[MCP Client] -->|JSON-RPC| B[MCP Server]
B --> C[Calculator Tool]
C --> D[Addition Function]
subgraph "Client Side"
A1[Tool Discovery]
A2[Tool Invocation]
A3[Result Processing]
end
subgraph "Server Side"
B1[Tool Registration]
B2[Request Handling]
B3[Response Generation]
end
A --> A1
A --> A2
A --> A3
B --> B1
B --> B2
B --> B3
📁 Project Structure
📦 Dotnet MCP with McpSharp/
├── 📁 McpClient/ # MCP Client Application
│ ├── 📄 Program.cs # Client entry point
│ ├── 📄 McpClient.csproj # Client project file
│ └── 📁 bin/ # Build output
├── 📁 McpServer/ # MCP Server Application
│ ├── 📄 Program.cs # Server entry point with tool registration
│ ├── 📄 McpServer.csproj # Server project file
│ └── 📁 bin/ # Build output
└── 📄 Dotnet_MCP_with_McpSharp.sln # Solution file
🛠️ Prerequisites
Before running this solution, ensure you have:
- .NET 9.0 SDK or later
- Visual Studio 2022 or Visual Studio Code with C# extension
- Windows 10/11 (tested on Windows 10.0.22631)
Installation
-
Install .NET 9.0 SDK:
# Download from: https://dotnet.microsoft.com/download/dotnet/9.0 -
Verify Installation:
dotnet --version # Should output: 9.0.x or later
⚡ Quick Start
1. Clone and Build
# Clone the repository
git clone <repository-url>
cd "Dotnet MCP with McpSharp"
# Restore packages
dotnet restore
# Build the solution
dotnet build
2. Run the MCP Server
# Navigate to server directory
cd McpServer
# Run the server
dotnet run
The server will start and register the calculator tool. You should see output indicating the server is running.
3. Run the MCP Client
# In a new terminal, navigate to client directory
cd McpClient
# Run the client
dotnet run
The client will:
- 🔍 Discover available tools from the server
- 📊 Display tool information
- 🧮 Execute the addition tool with sample parameters
- 📋 Display the result
🔧 Configuration
Server Configuration
The MCP server is configured in McpServer/Program.cs:
MCPServer.Register<CalculatorTool>();
await MCPServer.StartAsync(
serverName: "SimpleMcp.Server",
version: "v1.0.0"
);
Client Configuration
The MCP client is configured in McpClient/Program.cs:
var client = new MCPClient(
name: "McpClient",
version: "v1.0.0",
server: "path/to/McpServer.exe"
);
⚠️ Important: Update the server path in the client configuration to match your system.
📚 Usage Examples
Creating a New MCP Tool
To add a new tool to the server, create a new class with the McpTool attribute:
public class MathTool
{
[McpTool(name: "multiply", Description = "Multiply two numbers")]
public static int Multiply(
[McpParameter(required: true, Description = "First number")] int a,
[McpParameter(required: true, Description = "Second number")] int b)
{
return a * b;
}
}
Then register it in Program.cs:
MCPServer.Register<MathTool>();
Calling Tools from Client
// Discover available tools
List<Tool> tools = await client.GetToolsAsync();
// Call a specific tool
var result = await client.CallToolAsync(
name: "addition",
parameters: new Dictionary<string, object>
{
{ "firstNumber", 15 },
{ "secondNumber", 25 }
}
);
Console.WriteLine($"Result: {result.Content[0].Text}");
🔍 API Reference
MCPClient Class
| Method | Description | Parameters |
|---|---|---|
GetToolsAsync() | Retrieves all available tools | None |
CallToolAsync() | Executes a specific tool | name, parameters |
MCPServer Class
| Method | Description | Parameters |
|---|---|---|
Register<T>() | Registers a tool class | Tool class type |
StartAsync() | Starts the MCP server | serverName, version |
Attributes
| Attribute | Description | Properties |
|---|---|---|
McpTool | Marks a method as an MCP tool | name, Description |
McpParameter | Defines tool parameters | required, Description |
🧪 Testing
Manual Testing
- Start the server and verify it's running
- Run the client and check the output
- Verify tool discovery shows the correct number of tools
- Test tool execution with different parameters
Expected Output
Server Output:
MCP Server started successfully
Tool registered: addition
Client Output:
Available Tools: 1
Name: addition
Description: This tool will add two numbers.
Result: 15
📦 Dependencies
Core Dependencies
| Package | Version | Description |
|---|---|---|
MCPSharp | 1.0.11 | MCP implementation for .NET |
System.Formats.Asn1 | 9.0.9 | ASN.1 format support |
Target Framework
- .NET 9.0 - Latest LTS version with modern C# features
🚀 Advanced Usage
Custom Tool Implementation
public class WeatherTool
{
[McpTool(name: "get_weather", Description = "Get current weather for a city")]
public static async Task<string> GetWeather(
[McpParameter(required: true, Description = "City name")] string city)
{
// Implementation here
return $"Weather in {city}: Sunny, 25°C";
}
}
Error Handling
try
{
var result = await client.CallToolAsync("addition", parameters);
Console.WriteLine($"Success: {result.Content[0].Text}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
🤝 Contributing
We welcome contributions! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Guidelines
- ✅ Follow C# coding conventions
- ✅ Add XML documentation for public APIs
- ✅ Include unit tests for new features
- ✅ Update README.md for significant changes
📄 License
This project is licensed under the MIT License - see the file for details.
🆘 Support
If you encounter any issues or have questions:
- Check the Issues page
- Create a new issue with detailed information
- Include system information and error messages