您现在的位置是:网站首页> AI人工智能

AI模型调用MCP服务

摘要

AI模型调用MCP服务

***Agent让调用模型变得简单***

方便调用AI模型的Agent编程框架

AI入门编程推荐隔壁的程序员老王,点击进入


C# .NET4.5用 IHttpHandler如何编写SSE服务

MCP协议官网

MCP相关视频

MCP服务相关技术收集MCP

MCP协议详细讲解

AI 模型调用 MCP 服务的过程

AI 模型调用 MCP 服务的代码示例

C# 编写 Agent 调用 ollama 及 MCP 的方法



MCP协议详细讲解

Model Context Protocol(MCP)是由 Anthropic 推出的一种开源协议,旨在建立 AI 模型与开发环境之间的统一上下文交互标准。以下是对其的详细讲解:

1.png

背景与起源

在 AI 领域,大语言模型的应用常常面临数据孤岛和工具集成复杂的问题,不同的数据源和工具都有自己独特的 API 和集成方式,导致开发者需要为每个工具单独编写集成代码,开发和维护成本高,工具复用性低。为解决这些问题,Anthropic 于 2024 年 11 月 25 日开源发布了 MCP

核心概念

  • MCP Hosts :如 Claude Desktop、Cursor、 Cline、trae、Cherry Studio、IDE、AI 应用等,是运行 MCP 的主应用程序,负责发起连接并管理多个客户端实例,与用户进行交互并接收用户的问题或指令,再通过 MCP Clients 向 MCP Servers 发送请求以获取所需的数据或执行相应的操作
  • MCP Clients :由 Host 创建,与特定的 MCP Server 建立一对一的连接,负责协议通信和能力协商,充当 MCP Host 和 MCP Server 之间的“连接器”或“总机”,将 Host 的请求转发给 Server,并将 Server 的响应返回给 Host
  • MCP Servers :轻量级程序,通过标准化的模型上下文协议暴露特定功能,如文件读取、API 调用、数据库查询等,为 MCP Host 提供实际的数据和功能支持,每个 Server 提供一个特定的工具或能力

工作原理

  • 通信机制 :MCP 采用客户端 - 服务器架构,基于 JSON-RPC 2.0 消息格式,支持请求、响应和通知三种消息类型,确保通信的标准化和一致性。它主要支持两种通信方式,一种是标准输入输出(Stdio),适用于在同一台机器上运行的客户端和服务器之间的通信,客户端启动服务器程序作为子进程,消息通讯通过 stdin/stdout 进行;另一种是服务器发送事件(SSE),利用 HTTP 协议实现跨网络的实时数据传输,适用于需要访问远程资源的场景
  • 工作流程 :首先,Host 初始化 Client,Client 尝试与 Server 建立连接,并询问 Server 有哪些能力,Server 回应并返回所有支持的功能,从而建立 1:1 的连接。当用户与 LLM 交互提出问题或指令时,LLM 会告诉 Client 需要调用哪些 Tools,Client 收到 Host 的请求后,将请求信息发送给对应的 Server,Server 接收到信息后开始处理,处理完成后返回结果给 Client,Client 再将信息返回给 Host,Host 根据这些信息生成最终的回复返回给用户

主要功能与特性

  • 统一接口 :提供标准化的 API 接口,简化 AI 与各类上下文信息的交互,使得开发者无需为不同的数据源或工具编写复杂的适配代码,降低了开发难度和成本
  • 无缝集成 :能够轻松集成到现有开发工作流程中,无需对现有的系统和工具进行大规模的改造,即可实现 AI 模型与各种数据源和工具的快速连接和集成,提高了开发效率
  • 多源数据支持 :支持从多种来源获取上下文信息,包括代码仓库、文档、文件系统、数据库、远程 API 等,丰富了 AI 模型可以利用的数据资源,为模型的训练和推理提供了更全面、准确的上下文信息
  • 智能上下文管理 :优化上下文信息的传递,根据 AI 模型的需求和任务场景,自动筛选、组织和更新上下文信息,提高 AI 模型理解和生成的质量,使模型能够更准确地理解和处理复杂的任务
  • 扩展性设计 :具有灵活的架构,允许添加新的数据源和功能,开发者可以根据实际需求自由扩展 MCP 的功能,不断增加新的 MCP Servers 来提供新的工具和能力,以满足不断变化的业务需求

应用场景

  • 智能开发环境 :将 AI 模型与开发工具集成,如代码编辑器、IDE 等,使 AI 能够实时理解代码上下文,为开发者提供智能代码补全、代码生成、代码解释等功能,提高开发效率和代码质量
  • 智能办公助手 :连接办公软件和在线服务,如日历、邮件、文档管理系统等,帮助用户自动完成日常办公任务,如安排会议、发送邮件、生成报告等,提升办公自动化水平
  • 智能数据分析 :将 AI 模型与数据分析工具和数据源集成,如数据库、数据仓库、BI 工具等,使 AI 能够协助分析师进行数据查询、数据分析、数据可视化等工作,为决策提供更有力的支持
  • 智能客服系统 :集成企业内部的客户信息管理系统、订单管理系统等,使 AI 客服能够快速准确地获取客户相关的信息,为客户提供更精准、高效的咨询服务,提高客户满意度


JSON-RPC 2.0 的请求和响应示例

请求示例

{

  "jsonrpc": "2.0",

  "method": "add",

  "params": [2, 3],

  "id": 1

}

响应示例

{

  "jsonrpc": "2.0",

  "result": 5,

  "id": 1

}

错误响应示例

{

  "jsonrpc": "2.0",

  "error": {

    "code": -32601,

    "message": "Method not found"

  },

  "id": 1

}


批量请求示例

[

  {

    "jsonrpc": "2.0",

    "method": "add",

    "params": [2, 3],

    "id": 1

  },

  {

    "jsonrpc": "2.0",

    "method": "subtract",

    "params": [5, 2],

    "id": 2

  }

]

批量响应示例

[

  {

    "jsonrpc": "2.0",

    "result": 5,

    "id": 1

  },

  {

    "jsonrpc": "2.0",

    "result": 3,

    "id": 2

  }

]

这些示例展示了 JSON-RPC 2.0 请求和响应的基本格式,包括请求、响应以及错误处理等场景。



AI 模型调用 MCP 服务的过程

准备工作

  • 搭建 MCP 服务器 :开发者需先搭建 MCP 服务器,可使用 Anthropic 提供的开源框架如 FastMCP 等。定义好服务器的基本配置,如名称、版本等,并通过装饰器注册工具函数,每个工具函数对应一个具体的功能,如查询天气、发送邮件等
  • 集成 MCP 客户端 :在 AI 模型所在的系统或应用中集成 MCP 客户端,如在 Python 项目中安装相应的客户端库等

调用过程

  1. 用户发起请求 :用户通过与 AI 模型交互的方式,如在聊天界面输入问题或指令,表达其想要实现的需求
  2. AI 模型解析意图 :MCP 客户端将用户请求发送给 AI 模型,AI 模型对用户输入的自然语言进行理解和解析,确定用户的需求,并选择与之匹配的 MCP 函数及相应的参数
  3. 发送调用请求 :MCP 客户端根据 AI 模型返回的函数调用信息,向 MCP 服务器发送请求。请求中包含请求 ID、函数名称及参数等,格式通常为 JSON
  4. 执行服务并返回结果 :MCP 服务器接收到请求后,执行对应的工具函数,在本地或通过调用其他外部服务完成具体的任务处理,然后将执行结果按照规定的格式返回给 MCP 客户端。
  5. 结果整合与反馈 :MCP 客户端将 MCP 服务器返回的结果整合到对话上下文中,再次发送给 AI 模型。AI 模型根据整合后的上下文生成自然语言的回复,由 MCP 客户端将最终结果呈现给用户

通信机制

  • STDIO 方式 :适用于本地服务。MCP 客户端启动 MCP 服务器程序作为子进程,通过 stdin 和 stdout 进行消息传递,消息格式遵循 JSON-RPC 2.0
  • SSE 方式 :用于远程服务。MCP 客户端通过 Server-Sent Events 与 MCP 服务器进行通信,服务器定义特定接口用于推送和接收数据,消息格式同样基于 JSON-RPC 2.0

动态上下文管理

MCP 协议具有动态上下文管理机制,通过上下文窗口存储用户偏好、会话记录和环境数据等。在每次交互过程中,上下文会不断扩展和更新,同时对非关键信息进行压缩,以保证对话的连贯性和减少资源消耗

安全与认证机制

  • API 密钥验证 :MCP 服务通常会要求进行 API 密钥验证,只有拥有正确 API 密钥的客户端才能访问服务。
  • HTTPS 加密 :采用 HTTPS 协议对数据传输进行加密,确保数据在网络传输过程中的安全性。
  • 请求限制 :设置请求频率限制和配额限制等,防止服务被滥用,保护服务的稳定性和可靠性



AI 模型调用 MCP 服务的代码示例

基于 Python 的简单 MCP 服务端

Python

pip install mcp

/*

from mcp.server.fastmcp import FastMCP

import tools


mcp=FastMCP("host info mcp")

mcp.add_tool(tools.get_host_info)


def main()->none:

   print("hello from ai-mcp!")

   mcp.run("stdio")#还有sse

   mcp.run(transport="sse", port=9000)

   


if __name__=="__main__":

   main()


tools.py内容

def get_hosts_info()->str:

...



*/


from mcp import MCP, tool


mcp = MCP()


@mcp.register_tool

class WeatherTool:

    @tool(name="get_weather", description="获取指定城市的天气信息")

    def get_weather(self, city: str):

        # 这里可以添加获取天气信息的逻辑,比如调用天气 API 等

        return f"The weather in {city} is sunny."


    @tool(name="get_weather_forecast", description="获取指定城市未来几天的天气预报")

    def get_weather_forecast(self, city: str, days: int):

        # 添加获取天气预报的逻辑

        return f"The weather forecast for {city} in the next {days} days."


if __name__ == "__main__":

    mcp.start()

基于 Java 的 MCP 服务端

java

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.core.io.ClassPathResource;

import org.springframework.core.io.Resource;

import org.springframework.util.StringUtils;

import org.springframework.web.reactive.function.server.RouterFunctions;

import org.springframework.web.reactive.function.server.ServerResponse;

import reactor.core.publisher.Mono;


import java.util.Collections;

import java.util.Map;


@Configuration

public class MCPConfig {


    @Bean

    public RouterFunctions.Route mcpRoute() {

        return RouterFunctions.route()

                .POST("/mcp/weather", this::getWeather)

                .build();

    }


    private Mono<ServerResponse> getWeather(ServerRequest request) {

        Map<String, String> queryParams = request.queryParams();

        String city = queryParams.get("city");

        if (StringUtils.hasText(city)) {

            String weatherInfo = "The weather in " + city + " is sunny.";

            return ServerResponse.ok().bodyValue(Collections.singletonMap("weather", weatherInfo));

        } else {

            return ServerResponse.badRequest().bodyValue(Collections.singletonMap("error", "City parameter is required"));

        }

    }

}

AI 模型调用 MCP 服务的代码示例

基于 Python 的 OpenAI 模型调用 MCP 服务

Python

import openai

import requests

from mcp import MCPClient


# 初始化 MCP 客户端

mcp_client = MCPClient()

mcp_client.connect("http://localhost:8080/mcp")  # 替换为 MCP 服务的实际地址


# 调用 MCP 服务中的工具

def call_mcp_tool(tool_name, **kwargs):

    return mcp_client.call_tool(tool_name, **kwargs)


# 使用 OpenAI 模型

openai.api_key = "your_openai_api_key"  # 替换为你的 OpenAI API 密钥


def get_ai_response(user_query):

    # 构建消息列表

    messages = [

        {"role": "system", "content": "You are a helpful assistant."},

        {"role": "user", "content": user_query}

    ]


    # 调用 OpenAI API

    response = openai.ChatCompletion.create(

        model="gpt-4-turbo-preview",

        messages=messages,

        tools=mcp_client.list_tools(),  # 提供可用的 MCP 工具

        tool_choice="auto"

    )


    # 处理模型返回的结果

    ai_response = ""

    for choice in response.choices:

        message = choice.message

        if message.content:

            ai_response += message.content + "\n"

        if message.tool_calls:

            for tool_call in message.tool_calls:

                tool_name = tool_call.function.name

                tool_args = tool_call.function.arguments

                # 调用 MCP 工具

                tool_result = call_mcp_tool(tool_name, **tool_args)

                ai_response += f"Calling tool {tool_name} with args {tool_args}\n"

                ai_response += tool_result + "\n"

                # 将工具结果添加到消息中,继续与模型对话

                messages.append({"role": "assistant", "content": "", "tool_calls": [tool_call]})

                messages.append({"role": "tool", "tool_call_id": tool_call.id, "content": tool_result})

                # 获取下一个模型响应

                next_response = openai.ChatCompletion.create(

                    model="gpt-4-turbo-preview",

                    messages=messages,

                    tools=mcp_client.list_tools(),

                    tool_choice="auto"

                )

                if next_response.choices[0].message.content:

                    ai_response += next_response.choices[0].message.content + "\n"

    return ai_response


# 示例 usage

user_input = "What's the weather like in Beijing?"

print(get_ai_response(user_input))

基于 Java 的 Spring AI 模型调用 MCP 服务

java

import org.springframework.ai.chat.client.ChatClient;

import org.springframework.ai.chat.client.ChatClientBuilder;

import org.springframework.ai.mcp.client.McpClient;

import org.springframework.ai.mcp.client.McpClientBuilder;

import org.springframework.ai.mcp.client.McpFunctionCallback;

import org.springframework.ai.tool.ToolCallbackProvider;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;


import java.util.List;


@Configuration

public class AIConfig {


    @Bean

    public McpClient mcpClient() {

        // 配置 MCP 服务器参数

        var stdioParams = ServerParameters.builder("java")

                .args("-Dspring.ai.mcp.server.stdio=true",

                        "-Dspring.main.web-application-type=none",

                        "-Dlogging.pattern.console=",

                        "-jar",

                        "target/mcp-server-0.0.1-SNAPSHOT.jar")

                .build();

        // 创建 MCP 客户端

        return McpClient.sync(new StdioClientTransport(stdioParams));

    }


    @Bean

    public ToolCallbackProvider mcpTools(McpClient mcpClient) {

        // 获取 MCP 服务器中的工具列表并转换为 Function Callback

        return mcpClient.listTools(null)

                .tools()

                .stream()

                .map(tool -> new McpFunctionCallback(mcpClient, tool))

                .toList();

    }


    @Bean

    public ChatClient chatClient(ChatClientBuilder chatClientBuilder, ToolCallbackProvider mcpTools) {

        // 初始化聊天客户端并设置默认工具

        return chatClientBuilder.defaultFunctions(mcpTools).build();

    }

}


// 使用示例

public class AIService {

    private final ChatClient chatClient;


    public AIService(ChatClient chatClient) {

        this.chatClient = chatClient;

    }


    public String generateResponse(String userQuery) {

        return chatClient

                .prompt(userQuery)

                .call()

                .content();

    }

}


使用 ASP.NET Core 来创建一个 Web API 服务,并模拟天气查询功能

C# MCP 服务端代码示例

csharp

using Microsoft.AspNetCore.Builder;

using Microsoft.AspNetCore.Hosting;

using Microsoft.AspNetCore.Mvc;

using Microsoft.Extensions.DependencyInjection;

using Microsoft.Extensions.Hosting;


namespace MCPService

{

    public class Startup

    {

        public void ConfigureServices(IServiceCollection services)

        {

            services.AddControllers();

        }


        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

        {

            if (env.IsDevelopment())

            {

                app.UseDeveloperExceptionPage();

            }


            app.UseRouting();


            app.UseEndpoints(endpoints =>

            {

                endpoints.MapControllers();

            });

        }

    }

    /*

这段代码定义了一个名为WeatherController的控制器类。这个类继承自ControllerBase

,并使用了[ApiController]和[Route("mcp")]特性,表明这是用于处理HTTP请求的API控制器,并指定了其基础路由为/mcp。

在控制器类中,定义了一个名为GetWeather的方法,该方法使用了[HttpGet("weather")]特性。这表明这是一个处理HTTP GET请求的方法,其对应的路由是mcp/weather。这个方法接受一个名为city的参数,通过[FromQuery]特性从查询字符串中获取。

当客户端向/mcp/weather发起一个带有查询参数(如city=Paris)的GET请求时,GetWeather方法会处理这个请求,并返回一个IActionResult类型的对象,即一个包含响应内容和状态码的对象。在实际应用中,这个方法可能会根据提供的城市名称来获取和返回相应的天气信息。

*/

    [ApiController]

    [Route("mcp")]

    public class WeatherController : ControllerBase

    {

        [HttpGet("weather")]

        public IActionResult GetWeather([FromQuery] string city)

        {

            if (string.IsNullOrEmpty(city))

            {

                return BadRequest("City parameter is required");

            }


            // 模拟天气查询逻辑

            var weatherInfo = $"The weather in {city} is sunny.";


            return Ok(new { weather = weatherInfo });

        }


        [HttpGet("weather-forecast")]

        public IActionResult GetWeatherForecast([FromQuery] string city, [FromQuery] int days)

        {

            if (string.IsNullOrEmpty(city))

            {

                return BadRequest("City parameter is required");

            }


            // 模拟天气预报逻辑

            var weatherForecast = $"The weather forecast for {city} in the next {days} days.";


            return Ok(new { forecast = weatherForecast });

        }

   

[HttpPost("weather")]

    public IActionResult PostWeather([FromBody] WeatherRequest weatherRequest)

    {

        // 处理POST请求的逻辑

        return Ok($"Received weather data for {weatherRequest.City}: {weatherRequest.Temperature}°C");

    }


// 新增的可以GET和POST调用的方法

    [HttpGet("data")]

    [HttpPost("data")]

    public IActionResult GetAndPostData([FromQuery] string name, [FromBody] string postData = null)

    {

        if (HttpContext.Request.Method == HttpMethods.Get)

        {

            return Ok($"Received GET request with name: {name}");

        }

        else if (HttpContext.Request.Method == HttpMethods.Post)

 {

                   return Ok($"Received POST request with name: {name} and post data: {postData}");

        }


        return BadRequest("Invalid request method");

    }



}


public class WeatherRequest

{

    public string City { get; set; }

    public double Temperature { get; set; }

}



    public class Program

    {

        public static void Main(string[] args)

        {

            var host = CreateHostBuilder(args).Build();

            host.Run();

        }


        public static IHostBuilder CreateHostBuilder(string[] args) =>

            Host.CreateDefaultBuilder(args)

                .ConfigureWebHostDefaults(webBuilder =>

                {

                    webBuilder.UseStartup<Startup>();

                });

    }

}

说明

项目结构:

Startup 类配置了服务和中间件。

WeatherController 是一个 ASP.NET Core 控制器,提供了两个端点 /mcp/weather 和 /mcp/weather-forecast。

功能:

/mcp/weather 接受一个 city 参数,返回该城市的天气信息。

/mcp/weather-forecast 接受 city 和 days 参数,返回该城市未来几天的天气预报。

运行服务:

创建一个 ASP.NET Core 项目并复制上述代码。

使用 dotnet run 命令启动服务,服务默认运行在 https://localhost:5001 和 http://localhost:5000。

测试服务:

使用工具如 Postman 或 curl 测试 API:

获取天气信息:GET http://localhost:5000/mcp/weather?city=Beijing

获取天气预报:GET http://localhost:5000/mcp/weather-forecast?city=Beijing&days=3


C# 用OpenAI模型调用

public class WeatherRequestFunction : IRequestFunction

{

    public string Name => "weather";


    public async Task<IDictionary<string, object>> InvokeAsync(IDictionary<string, object> parameters)

    {

        using var httpClient = new HttpClient();

        var city = parameters["city"].ToString();

        var response = await httpClient.GetAsync($"http://localhost:5000/mcp/weather?city={city}");

        response.EnsureSuccessStatusCode();

        var content = await response.Content.ReadAsStringAsync();

        return new Dictionary<string, object> { { "result", content } };

    }


    public string Serialize(IRequestFunction function)

    {

        return $"Calling tool {function.Name} with parameters {function}";

    }


    public Task SerializeAsync(IRequestFunction function)

    {

        // 实现序列化逻辑

        return Task.CompletedTask;

    }

}

代码说明

OpenAI 客户端:创建 OpenAI 客户端实例,并配置 API 密钥和日志记录器。

MCP 工具:定义一个 WeatherRequestFunction 类实现 IRequestFunction 接口,用于调用 MCP 服务中的天气查询工具。

ChatClient:创建 ChatClient 实例,传入 OpenAI 客户端和日志记录器。

聊天历史:初始化聊天历史记录。

交互式聊天:在循环中读取用户输入,将其添加到聊天历史中,并调用 OpenAI API 获取响应。打印助手的响应并将其添加到聊天历史中。

其他信息

确保你的 MCP 服务正在运行,并且可以通过 http://localhost:5000/mcp/weather 访问。

替换成您的实际 OpenAI API 密钥。

如果您没有 MCP 服务,可以参考前面的示例代码实现一个简单的 MCP 服务。



C# 编写 Agent 调用 ollama 及 MCP 的方法

调用 ollama

安装 Ollama SDK :可以使用如下命令安装 Ollama 的 C# SDK,“dotnet add package Ollama --version 1.9.0”。

简单对话 :设置模型名称和 ollama 的 API 地址,利用 OllamaApiClient 进行对话生成,示例代码如下:

**```csharp

string modelName = "qwen2:7b";

using var ollama = new OllamaApiClient(baseUri: new Uri("http://127.0.0.1:11434/api"));

Console.WriteLine("开始对话!!!");

string userInput = "";

do

{

Console.WriteLine("User:");

userInput = Console.ReadLine()!;

var enumerable = ollama.Completions.GenerateCompletionAsync(modelName, userInput);

Console.WriteLine("Agent:");

await foreach (var response in enumerable)

{

Console.Write($"{response.Response}");

}

Console.WriteLine();

} while (!string.Equals(userInput, "exit", StringComparison.OrdinalIgnoreCase));

Console.WriteLine("对话结束!!!");



**[^2^]


  * **多轮对话** :使用 Chat 对象进行分角色的多轮对话,通过 List 消息存储之前的对话记录,以便模型捕获上下文,代码示例:

**```csharp

string modelName = "glm4:9b";

using var ollama = new OllamaApiClient(baseUri: new Uri("http://127.0.0.1:11434/api"));

Console.WriteLine("开始对话!!!");

string userInput = "";

List messages = [];

do

{

    messages = messages.TakeLast(5).ToList();

    Console.WriteLine("User:");

    userInput = Console.ReadLine()!;

    messages.Add(new Message(MessageRole.User, userInput));

    var enumerable = ollama.Chat.GenerateChatCompletionAsync(modelName, messages, stream: true);

    Console.WriteLine("Agent:");

    StringBuilder builder = new();

    await foreach (var response in enumerable)

    {

        string content = response.Message.Content;

        builder.AppendLine(content);

        Console.Write(content);

    }

    messages.Add(new Message(MessageRole.Assistant, builder.ToString()));

    Console.WriteLine();

} while (!string.Equals(userInput, "exit", StringComparison.OrdinalIgnoreCase));

Console.WriteLine("对话结束!!!");



```**[^2^]


  * **Function call** :若要使用 function call 功能,需设置 autoCallTools 为 true,并给 Ollama 注册相应的工具类,代码如下:

**```csharp

string modelName = "llama3.1:8b";

using var ollama = new OllamaApiClient(baseUri: new Uri("http://127.0.0.1:11434/api"));

var chat = ollama.Chat(

    model: modelName,

    systemMessage: "You are a helpful assistant.",

    autoCallTools: true);

var mathService = new MathService();

chat.AddToolService(mathService.AsTools(), mathService.AsCalls());

while (true)

{

    try

    {

        Console.WriteLine("User>");

        var newMessage = Console.ReadLine();

        var msg = await chat.SendAsync(newMessage);

        Console.WriteLine("Agent> " + msg.Content);

    }

    finally

    {

        Console.WriteLine(chat.PrintMessages());

    }

}

```**[^2^]


### 调用 MCP

目前未查到有成熟的 C# 调用 MCP 的官方 SDK 或常用库,但可以尝试以下思路:

  * **通过 HTTP 请求调用** :如果 MCP 提供了 HTTP API 接口,可以使用 C# 中的 HttpClient 类来发送 HTTP 请求进行调用。基本步骤如下:

    1. 创建 HttpClient 对象,并设置相关请求头等信息。

    2. 构造请求内容,根据 MCP API 的要求,将请求参数进行序列化。

    3. 发送 POST 或 GET 等请求到 MCP 的 API 地址。

    4. 处理返回的响应,对响应内容进行反序列化等操作,获取所需数据。


例如,假设 MCP 的 API 地址为<http://localhost:8000/mcp/api>,需要发送一个获取数据的请求,代码可能如下:

**```csharp

using (var client = new HttpClient())

{

    client.BaseAddress = new Uri("http://localhost:8000/");

    var response = await client.GetAsync("mcp/api?param1=value1");

    if (response.IsSuccessStatusCode)

    {

        var result = await response.Content.ReadAsStringAsync();

        // 处理结果

    }

    else

    {

        // 处理错误

    }

}

```**

  * **参考 Python 实现进行移植** :上述提到的 Python 调用 MCP 的代码示例中,展示了如何创建 MCP Server、获取工具列表以及创建 Agent 等过程。可以参考其逻辑和交互方式,在 C# 中进行相应的实现。例如,对于 MCP Server 的连接,可以考虑在 C# 中使用类似的网络通信方式;对于工具的调用,可以解析 MCP 返回的工具信息,并根据用户输入的问题,选择合适的工具进行调用等[^4^]。


MathService代码:

using System;

using System.Collections.Generic;

using System.Linq;


// 定义工具接口

public interface IToolsService

{

    public string Name { get; }

    public List<ToolDefinition> DefineTools();

}


// 定义工具函数

public class MathService : IToolsService

{

    public string Name => "math";

    

    // 定义工具

    public List<ToolDefinition> DefineTools()

    {

        return new List<ToolDefinition>

        {

            new ToolDefinition("add", "Add two numbers", "a: number, b: number", Add),

            new ToolDefinition("subtract", "Subtract two numbers", "a: number, b: number", Subtract),

            new ToolDefinition("multiply", "Multiply two numbers", "a: number, b: number", Multiply),

            new ToolDefinition("divide", "Divide two numbers", "a: number, b: number", Divide)

        };

    }


    // 加法

    public double Add(double a, double b)

    {

        return a + b;

    }


    // 减法

    public double Subtract(double a, double b)

    {

        return a - b;

    }


    // 乘法

    public double Multiply(double a, double b)

    {

        return a * b;

    }


    // 除法

    public double Divide(double a, double b)

    {

        if (b == 0)

        {

            throw new DivideByZeroException("Division by zero is not allowed.");

        }

        return a / b;

    }

}


ToolDefinition类通常不是.NET标准库或框架的一部分,也不是Ollama或其他主流库的内置类。因此,您需要自己定义它,或者参考您所使用的特定库或框架的实现

using System;


public class ToolDefinition

{

    // 工具名称

    public string Name { get; set; }

    // 工具描述

    public string Description { get; set; }

    // 工具参数列表

    public string Parameters { get; set; }

    // 工具处理函数的委托类型

    public Func<object[], object> Function { get; set; }


    public ToolDefinition(string name, string description, string parameters, Func<object[], object> function)

    {

        Name = name;

        Description = description;

        Parameters = parameters;

        Function = function;

    }

}



































Top