diff --git a/LinkToolAddin.csproj b/LinkToolAddin.csproj index 6bd5b78..f683eae 100644 --- a/LinkToolAddin.csproj +++ b/LinkToolAddin.csproj @@ -98,7 +98,6 @@ - diff --git a/client/McpClient.cs b/client/McpClient.cs new file mode 100644 index 0000000..c03734b --- /dev/null +++ b/client/McpClient.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using ModelContextProtocol.Client; +using ModelContextProtocol.Protocol.Types; + +namespace LinkToolAddin.client; + +public interface McpClient +{ + public Task> GetToolListAsync(); + + public Task CallToolAsync(string toolName, Dictionary parameters = null); +} \ No newline at end of file diff --git a/client/PythonMcpClient.cs b/client/PythonMcpClient.cs index e25e7d8..caad4b7 100644 --- a/client/PythonMcpClient.cs +++ b/client/PythonMcpClient.cs @@ -1,6 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.Windows.Documents; +using ModelContextProtocol.Protocol.Types; +using Newtonsoft.Json; + namespace LinkToolAddin.client; -public class PythonMcpClient +using ModelContextProtocol.Client; +using ModelContextProtocol.Protocol.Transport; + +public class StdioMcpClient : McpClient { + private List arguments; + private StdioClientTransportOptions transportOptions; + public StdioMcpClient(string command,List arguments) + { + this.arguments = arguments; + transportOptions = new StdioClientTransportOptions() + { + Command = command, + Arguments = this.arguments + }; + } + + public static async Task StdioMcpTest() + { + List arguments = new List(); + arguments.Add("mcp-server-time"); + arguments.Add("--local-timezone=America/New_York"); + StdioClientTransportOptions transportOptions = new StdioClientTransportOptions() + { + Command = "uvx", // 运行服务器的命令 + Arguments = arguments + }; + var client = await McpClientFactory.CreateAsync(new StdioClientTransport(transportOptions)); + var tools = await client.ListToolsAsync(); + Console.WriteLine("Available Tools:"); + foreach (var tool in tools) + { + Console.WriteLine($"- {tool.Name}"); + } + + var result = await client.CallToolAsync("get_current_time", + new Dictionary { { "timezone", "America/New_York" } }); + Console.WriteLine(JsonConvert.SerializeObject(result)); + return tools[0].Name; + } + + public async Task> GetToolListAsync() + { + IMcpClient client = await McpClientFactory.CreateAsync(new StdioClientTransport(transportOptions)); + IList tools = await client.ListToolsAsync(); + return tools; + } + + public async Task CallToolAsync(string toolName, Dictionary parameters = null) + { + IMcpClient client = await McpClientFactory.CreateAsync(new StdioClientTransport(transportOptions)); + CallToolResponse result = await client.CallToolAsync(toolName,parameters); + return result; + } } \ No newline at end of file diff --git a/client/SseMcpClient.cs b/client/SseMcpClient.cs index 471af60..6af5c55 100644 --- a/client/SseMcpClient.cs +++ b/client/SseMcpClient.cs @@ -3,54 +3,35 @@ using System.Collections.Generic; using System.Threading.Tasks; using ModelContextProtocol.Client; using ModelContextProtocol.Protocol.Transport; +using ModelContextProtocol.Protocol.Types; using Newtonsoft.Json; namespace LinkToolAddin.client; -public class SseMcpClient +public class SseMcpClient : McpClient { - public static async Task testGaodeMcp() + private SseClientTransportOptions options; + private IClientTransport transport; + public SseMcpClient(string url) { - Console.WriteLine("Connecting to 高德 MCP Server via SSE..."); - - // 创建 MCP Server 配置 - SseClientTransportOptions options = new SseClientTransportOptions + options = new SseClientTransportOptions { - Endpoint = new Uri("https://mcp.amap.com/sse?key=ed418512c94ade8f83d42c37b77d2bb2"), + Endpoint = new Uri(url), }; - - IClientTransport transport = new SseClientTransport(options);; - + transport = new SseClientTransport(options); + } + public async Task> GetToolListAsync() + { // 创建 MCP Client - var client = await McpClientFactory.CreateAsync(transport); - Console.WriteLine("Connected to 高德 MCP Server"); + IMcpClient client = await McpClientFactory.CreateAsync(transport); + var tools = await client.ListToolsAsync(); + return tools; + } - try - { - // 获取可用工具列表 - var tools = await client.ListToolsAsync(); - Console.WriteLine("\nAvailable Tools:"); - foreach (var tool in tools) - { - Console.WriteLine($"- {tool.Name}: {tool.Description}"); - } - - // 示例调用:获取当前定位 - var result = await client.CallToolAsync("amap.maps_weather", new Dictionary{{"city","北京"}}); - Console.WriteLine("\n[amap.get_location] Result:"); - Console.WriteLine(result); - return JsonConvert.SerializeObject(result); - } - catch (Exception ex) - { - Console.WriteLine($"Error occurred: {ex.Message}"); - } - finally - { - await client.DisposeAsync(); - } - - Console.WriteLine("Client closed."); - return "failed"; + public async Task CallToolAsync(string toolName,Dictionary parameters = null) + { + IMcpClient client = await McpClientFactory.CreateAsync(transport); + CallToolResponse result = await client.CallToolAsync(toolName,parameters); + return result; } } \ No newline at end of file diff --git a/ui/dockpane/DialogDockpane.xaml.cs b/ui/dockpane/DialogDockpane.xaml.cs index a939189..3487472 100644 --- a/ui/dockpane/DialogDockpane.xaml.cs +++ b/ui/dockpane/DialogDockpane.xaml.cs @@ -11,6 +11,7 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System.Text.Json; using System.Threading; +using System.Windows.Documents; using ArcGIS.Desktop.Core.Geoprocessing; using LinkToolAddin.client; using LinkToolAddin.host.llm; @@ -20,6 +21,8 @@ using log4net; using log4net.Appender; using log4net.Config; using log4net.Layout; +using ModelContextProtocol.Client; +using ModelContextProtocol.Protocol.Types; using ModelContextProtocol.Server; using Newtonsoft.Json; @@ -46,8 +49,28 @@ namespace LinkToolAddin.ui.dockpane private async void TestServer_OnClick(object sender, RoutedEventArgs e) { log.Info("TestServer Clicked"); - string res = await SseMcpClient.testGaodeMcp(); - log.Info(res); + List args = new List(); + args.Add("mcp-server-time"); + args.Add("--local-timezone=America/New_York"); + McpClient stdioMcpClient = new StdioMcpClient("uvx",args); + IList tools = await stdioMcpClient.GetToolListAsync(); + foreach (McpClientTool tool in tools) + { + log.Info(tool.JsonSchema.ToString()); + } + CallToolResponse response = await stdioMcpClient.CallToolAsync("get_current_time", + new Dictionary { { "timezone", "America/New_York" } }); + log.Info(JsonConvert.SerializeObject(response)); + } + + private async void SseMcp_test() + { + SseMcpClient client = new SseMcpClient("https://mcp.amap.com/sse?key=ed418512c94ade8f83d42c37b77d2bb2"); + IList tools = await client.GetToolListAsync(); + foreach (McpClientTool tool in tools) + { + log.Info(tool.JsonSchema.ToString()); + } } private async void Retrieve_Test()