149 lines
5.7 KiB
C#
Raw Normal View History

2025-10-11 18:25:59 +08:00
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Nodes;
using XiaoZhiSharp_ConsoleApp.McpTools;
namespace XiaoZhiSharp_ConsoleApp.Services
{
public class McpService
{
private static IHost? _host;
private static IMcpClient _mcpClient;
public McpService()
{
var builder = Host.CreateApplicationBuilder();
var mcpBuilder = builder.Services
.AddMcpServer()
.WithStreamServerTransport(Global.McpClientToServerPipe.Reader.AsStream(), Global.McpServerToClientPipe.Writer.AsStream())
.WithTools<IotThings_Tool>();
_host = builder.Build();
_host.StartAsync();
}
public async Task<string> McpMessageHandle(string message)
{
try
{
if (_mcpClient == null)
{
var clientTransport = new StreamClientTransport(
serverInput: Global.McpClientToServerPipe.Writer.AsStream(),
serverOutput: Global.McpServerToClientPipe.Reader.AsStream());
_mcpClient = await McpClientFactory.CreateAsync(clientTransport);
}
dynamic? mcp = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(message);
if (mcp == null)
return string.Empty;
JsonNode? root = JsonNode.Parse(message);
if (mcp.method == "initialize")
{
Global.McpVisionUrl = root?["params"]?["capabilities"]?["vision"]?["url"]?.GetValue<string>();
Global.McpVisionToken = root?["params"]?["capabilities"]?["vision"]?["token"]?.GetValue<string>();
// 处理初始化请求,构造 Result 数据(非匿名类型,需确保属性名匹配)
var resultData = new
{
protocolVersion = "2024-11-05",
capabilities = _mcpClient.ServerCapabilities,
serverInfo = new
{
name = "XiaoZhiSharp", // 设备名称 (BOARD_NAME)
version = Global.CurrentVersion, // 设备固件版本
}
};
// 直接序列化为 JsonNode关键步骤
JsonNode resultNode = JsonSerializer.SerializeToNode(resultData);
JsonRpcResponse? response = new JsonRpcResponse()
{
Id = new RequestId((long)mcp.id),
JsonRpc = "2.0",
Result = resultNode
};
return JsonSerializer.Serialize(response);
}
if (mcp.method == "tools/list")
{
// 处理工具列表请求
var tools = await _mcpClient.ListToolsAsync();
List<Tool> toolsList = new List<Tool>();
foreach (var item in tools)
{
toolsList.Add(item.ProtocolTool);
}
var resultData = new
{
tools = toolsList
};
JsonNode resultNode = JsonSerializer.SerializeToNode(resultData);
JsonRpcResponse? response = new JsonRpcResponse()
{
Id = new RequestId((long)mcp.id),
JsonRpc = "2.0",
Result = resultNode
};
var options = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping // 关键配置
};
return JsonSerializer.Serialize(response, options);
}
if (mcp.method == "tools/call")
{
// 处理工具调用请求
//JsonNode? root = JsonNode.Parse(message);
// 安全提取 name 和 arguments
string? name = root?["params"]?["name"]?.GetValue<string>();
JsonNode? argumentsNode = root?["params"]?["arguments"];
// 将 arguments 转换为 Dictionary<string, object>
Dictionary<string, object>? arguments = null;
if (argumentsNode != null)
{
arguments = argumentsNode.Deserialize<Dictionary<string, object>>();
}
ModelContextProtocol.Protocol.CallToolResult? callToolResponse = await _mcpClient.CallToolAsync(name, arguments);
JsonNode jsonNode = JsonSerializer.SerializeToNode(callToolResponse);
JsonRpcResponse? response = new JsonRpcResponse()
{
Id = new RequestId((long)mcp.id),
JsonRpc = "2.0",
Result = jsonNode
};
var options = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
return JsonSerializer.Serialize(response, options);
}
}
catch (Exception ex)
{
string errorMessage = $"MCP处理异常: {ex.Message}";
}
return string.Empty;
}
}
}