项目文件夹

文件
2026-07-13 13:31:35 +08:00

150 行
4.7 KiB
C#

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using ModelContextProtocol.Client;
using System.Text.Json;
/**
* Complete C# MCP Client Example
*
* This client demonstrates how to:
* 1. Connect to an MCP server using stdio transport
* 2. List available tools and resources
* 3. Call calculator tools
* 4. Handle responses from the server
*/
Console.WriteLine("🚀 Starting MCP C# Client...");
try
{
// Create configuration builder
var builder = Host.CreateApplicationBuilder(args);
builder.Configuration
.AddEnvironmentVariables()
.AddUserSecrets<Program>();
// Create stdio transport to connect to the MCP server
var clientTransport = new StdioClientTransport(new()
{
Name = "Calculator Server",
Command = "dotnet",
Arguments = ["run", "--project", "../01-first-server/solution/csharp/calculator-server.csproj"],
});
Console.WriteLine("📡 Connecting to MCP server...");
// Create and connect the MCP client
await using var mcpClient = await McpClient.CreateAsync(clientTransport);
Console.WriteLine("✅ Connected to MCP server successfully!");
// List available tools
Console.WriteLine("\n📋 Listing available tools:");
var tools = await mcpClient.ListToolsAsync();
foreach (var tool in tools)
{
Console.WriteLine($" - {tool.Name}: {tool.Description}");
}
// Test calculator operations
Console.WriteLine("\n🧮 Testing Calculator Operations:");
// Addition
var addResult = await mcpClient.CallToolAsync(
"Add",
new Dictionary<string, object?>() { ["a"] = 5, ["b"] = 3 },
cancellationToken: CancellationToken.None
);
Console.WriteLine($"Add 5 + 3 = {ExtractTextResult(addResult)}");
// Subtraction
var subtractResult = await mcpClient.CallToolAsync(
"Subtract",
new Dictionary<string, object?>() { ["a"] = 10, ["b"] = 4 },
cancellationToken: CancellationToken.None
);
Console.WriteLine($"Subtract 10 - 4 = {ExtractTextResult(subtractResult)}");
// Multiplication
var multiplyResult = await mcpClient.CallToolAsync(
"Multiply",
new Dictionary<string, object?>() { ["a"] = 6, ["b"] = 7 },
cancellationToken: CancellationToken.None
);
Console.WriteLine($"Multiply 6 × 7 = {ExtractTextResult(multiplyResult)}");
// Division
var divideResult = await mcpClient.CallToolAsync(
"Divide",
new Dictionary<string, object?>() { ["a"] = 20, ["b"] = 4 },
cancellationToken: CancellationToken.None
);
Console.WriteLine($"Divide 20 ÷ 4 = {ExtractTextResult(divideResult)}");
// Help
var helpResult = await mcpClient.CallToolAsync(
"Help",
new Dictionary<string, object?>(),
cancellationToken: CancellationToken.None
);
Console.WriteLine($"\n📖 Help Information:");
Console.WriteLine(ExtractTextResult(helpResult));
// List resources if available
try
{
Console.WriteLine("\n📄 Listing available resources:");
var resources = await mcpClient.ListResourcesAsync();
foreach (var resource in resources)
{
Console.WriteLine($" - {resource.Name}: {resource.Description}");
}
}
catch (Exception ex)
{
Console.WriteLine(" No resources available or error listing resources: " + ex.Message);
}
Console.WriteLine("\n✨ Client operations completed successfully!");
}
catch (Exception ex)
{
Console.WriteLine($"❌ Error running MCP client: {ex.Message}");
Console.WriteLine($"Stack trace: {ex.StackTrace}");
}
/// <summary>
/// Extracts the text result from a tool call response object.
/// </summary>
/// <param name="result">The result object, which may contain text content or other data.</param>
/// <returns>
/// A string containing the extracted text if found, a serialized representation of the result if no text is found,
/// or a fallback string if serialization fails.
/// </returns>
static string ExtractTextResult(object result)
{
try
{
if (result is IEnumerable<object> contentList)
{
foreach (var content in contentList)
{
if (content is IDictionary<string, object> contentDict &&
contentDict.TryGetValue("text", out var text))
{
return text?.ToString() ?? "No text content";
}
}
}
// Fallback: try to serialize the entire result
return JsonSerializer.Serialize(result, new JsonSerializerOptions { WriteIndented = true });
}
catch
{
return result?.ToString() ?? "No result";
}
}