using System.Text;
using System.Text.Json;
namespace MCPDemo.Client
{
public class McpClient
{
private readonly HttpClient _httpClient;
private readonly string _baseUrl;
public McpClient(string baseUrl, string username, string password)
{
_baseUrl = baseUrl;
_httpClient = new HttpClient();
// Set up Basic Authentication
var credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}"));
_httpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", credentials);
}
public async Task<T?> SendMcpMessageAsync<T>(object message)
{
var json = JsonSerializer.Serialize(message, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
});
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync($"{_baseUrl}/api/mcp/message", content);
response.EnsureSuccessStatusCode();
var responseJson = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<T>(responseJson, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
});
}
public async Task<object?> GetToolsAsync()
{
var response = await _httpClient.GetAsync($"{_baseUrl}/api/mcp/tools");
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<object>(json);
}
public void Dispose()
{
_httpClient?.Dispose();
}
}
// Example usage
public class Program
{
public static async Task Main(string[] args)
{
var client = new McpClient("http://localhost:5000", "admin", "password123");
try
{
// Initialize the MCP server
var initMessage = new
{
jsonrpc = "2.0",
id = "1",
method = "initialize",
@params = new
{
protocolVersion = "2024-11-05",
capabilities = new { },
clientInfo = new
{
name = "C# MCP Client",
version = "1.0.0"
}
}
};
Console.WriteLine("Initializing MCP server...");
var initResponse = await client.SendMcpMessageAsync<object>(initMessage);
Console.WriteLine($"Init Response: {JsonSerializer.Serialize(initResponse, new JsonSerializerOptions { WriteIndented = true })}");
// Call the echo tool
var echoMessage = new
{
jsonrpc = "2.0",
id = "2",
method = "tools/call",
@params = new
{
name = "echo",
arguments = new
{
message = "Hello from C# client!"
}
}
};
Console.WriteLine("\nCalling echo tool...");
var echoResponse = await client.SendMcpMessageAsync<object>(echoMessage);
Console.WriteLine($"Echo Response: {JsonSerializer.Serialize(echoResponse, new JsonSerializerOptions { WriteIndented = true })}");
// Call the calculator tool
var calcMessage = new
{
jsonrpc = "2.0",
id = "3",
method = "tools/call",
@params = new
{
name = "calculate",
arguments = new
{
operation = "multiply",
a = 6,
b = 7
}
}
};
Console.WriteLine("\nCalling calculator tool...");
var calcResponse = await client.SendMcpMessageAsync<object>(calcMessage);
Console.WriteLine($"Calculator Response: {JsonSerializer.Serialize(calcResponse, new JsonSerializerOptions { WriteIndented = true })}");
// Get available tools
Console.WriteLine("\nGetting available tools...");
var tools = await client.GetToolsAsync();
Console.WriteLine($"Available Tools: {JsonSerializer.Serialize(tools, new JsonSerializerOptions { WriteIndented = true })}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
client.Dispose();
}
Console.WriteLine("\nPress any key to exit...");
Console.ReadKey();
}
}
}