Model Context Protocol (MCP) 模型上下文协议,是由claude的发布公司Anthropic,提出的一种开放协议。为给LLM提供上下文(数据)提供了一种标准协议。在官方的描述中,将他形容为一种类似USB-C(Type-C)接口的东西,用相同的接口去连接不同的设备获取/传输数据。

简单来说,对于用户来说,MCP是一种简单的工具,可以帮助我们访问各式各样的数据源。而对于开发者,MCP能让我们更轻松地将数据源/功能,集成到LLM应用中。

对于之前了解过Function Calling(以下简称为FC)的同学来说,可能会发起疑问。FC也能让我们将各种功能插入LLM,这两者有什么区别呢?

FC协议实现了让LLM有能力“调用”程序里的函数,以增强LLM的能力(当然本质LLM输出的还是文本而不是直接的调用动作)

非常简单,觉得像是很正常的,MCP本身也依赖于FC调用各种功能,所以模型需要支持FC能力才可以使用MCP协议。但是我们很难将FC功能轻松的集成到各种应用当中,我们可能需要实现自己的对外开放的接口协议,然后才能让外部应用去调用。

而MCP就是提供了这一标准,让所有开发者可以用统一的协议提供自己的功能。其他的应用自然也能用统一的协议去使用开发者们提供的功能。

在3月24日,DeepSeekV3更新了一个小版本,正式支持了FC。这也意味着我们可以用DS作为我们MCP的LLM。

MCP架构

主机

一个应用(主机)(可能是IDE, Claude Desktop等类型)可以包含多个客户端

客户端

一个客户端只会连接一个服务器,通过mcp协议交互

服务端

服务端可以访问本地/远程数据源,提供工具,或是提示词(采样)给客户端

远程/本地数据源,API

可以被服务器访问的数据源或是API(例如数据库,Webapi等)

官方的架构示意图

图片

另外还有,工具,提示词,资源, 采样,root等概念

简单介绍就是,资源就是能提供给llm的上下文,提示词就是llm的提示,工具是服务器提供的工具,采样是一个特殊的功能用于采样提示词,root则是表明应用的工作的范围。具体的概念定义可以在文档中查看。

MCP通讯方式

MCP使用JSON-RPC2.0作为数据传输格式,以下有两种内置传输模式

标准输入输出(stdio)

stdio 传输支持通过标准输入和输出流进行通信。这对本地集成和命令行工具特别有用。

以下情况下中时候使用 stdio模式:

命令行工具

本地集成

简单的过程通信

使用 shell 脚本

服务器发送事件(SSE)

支持使用 HTTP POST 请求进行服务器到客户端流式处理,以实现客户端到服务器的通信,适合远程的mcp服务器交互方式

另外,通过实现Transport 接口,可以实现自己的传输模式

以下是一些现有MCP服务器

https://github.com/modelcontextprotocol/servers/tree/main

你可以在链接查看这些服务器的使用方法,其中包含各式各样的功能

示例,体现MCP功能的服务器,使用这些服务器的时候,可能需要安装有node.js或是其他环境。Everything是我们演示将会用到的服务器

图片

一些官方集成的mcp服务器

图片

在.NET中使用MCP

由 Peder Holdgaard、Pedersen 和 Microsoft (还有我的神Stephen Toub)开发的McpDotNet,于3月24日正式被官方编入sdk库,这意味着.NET也可以轻松的调用这些服务器,让我们来看看吧。

还有TypeScript,Python,Java,Kotlin也有官方sdk库,大家也可以都试试,模式都差不太多

git clone https://github.com/modelcontextprotocol/csharp-sdk

打开sample文件夹,我们可以看到AspNetCoreSseServer(SSE模式MCP服务器),TestServerWithHosting(stdio模式MCP服务器),以及ChatWithTools(主机/客户端),后续还更新了一些其他示例(目前库还处在预览版,后面可能会有较大变更)

以下是两种客户端定义方式

var mcpClient = await McpClientFactory.CreateAsync(
    new()
    {
        Id = "everything",
        Name = "Everything",
        TransportType = TransportTypes.Sse,
        Location = "http://localhost:3001/sse",
    });
var mcpClient = await McpClientFactory.CreateAsync(
    new()
    {
        Id = "everything",
        Name = "Everything",
        TransportType = TransportTypes.StdIo,
        TransportOptions = new()
        {
            ["command"] = "npx", ["arguments"] = "-y @modelcontextprotocol/server-everything",
        } // 相当于执行了 npx -y @modelcontextprotocol/server-everything
    });

显而易见,第一种方式是连接采用SSE模式的服务器,而第二种则是采用stdio的方式,直接与本地运行的程序交互。其command和arguments相当于是在命令行输入的指令,用于启动一个程序。显然,在使用everything示例的时候,我们需要安装node.js,如果想测试使用,请先下载安装。

如果我们想切换成TestServerWithHosting作为本地mcp服务器,则修改为类似

var mcpClient = await McpClientFactory.CreateAsync(
    new()
    {
        Id = "everything",
        Name = "Everything",
        TransportType = TransportTypes.StdIo,
        TransportOptions = new()
        {
            ["command"] = "xxxx\\csharp-sdk\\artifacts\\bin\\TestServerWithHosting\\Debug\\net9.0\\TestServerWithHosting.exe"
      
        }
    });

记住你需要先编译一次,才可以启用,(当然你可以使用dotnet 的指令去启动它)

.NET程序中调用本地部署Deepseek模型进行对话_net deepseek-CSDN博客

然后你可以填入你的OPENAI的key,如果你想用DeepSeek的话,参考我们之前的内容,就可以轻松的切换到我们想用的模型。

OpenAIChatClient openAIChatClient = new OpenAIChatClient(
    new OpenAI.OpenAIClient(new ApiKeyCredential("sk-xx"),
        new OpenAI.OpenAIClientOptions() { Endpoint = new Uri("https://api.deepseek.com") }), "deepseek-chat");
using IChatClient chatClient =
    openAIChatClient
        .AsBuilder().UseFunctionInvocation().Build();

接下来,我们就可以正常使用了!

如果我们使用官方实例我们Everything服务器

图片

他拥有echo, 计算加法,输出环境变量(printEnv)等功能,读者也可以亲自测一下如何使用。

输出环境变量可能是这其中最直观的展示llm获取本机数据源的方式

如果想编写自己的工具

在EchoTools.cs文件中,修改代码如下,便实现了我们的加法工具,这和之前SK(语义核心)的工具编写方法非常的像,几乎可以无缝使用。

[McpServerToolType]
public static class EchoTool
{
    [McpServerTool, Description("Echoes the input back to the client.")]
    public static string Echo(string message)
    {
        return "hello " + message;
    }

    [McpServerTool, Description("Add two number")]
    public static int Add(int a, int b)
    {
        return a + b;
    }
}

总结

MCP是一个通用,开发的标准协议。意图实现一种标准的方式扩展LLM的能力。开发者们可以实现自己的mcp服务器,并且在任何地方的mcp客户端中连使用。其通用性和标准性都比原来直接使用FC开发有所提升,至于MCP最终会不会成为llm应用的标准协议,还需要时间的检验

学会了吗? 学会了

Bilibili:@无聊的年【OPEN 1+X】模型上下文协议(MCP)简介,配合DeepSeek开发应用_哔哩哔哩_bilibili模型上下文协议(MCP)简介,配合DeepSeek开发应用累死我了... 第一次录DS接口还炸了,心态爆炸.jpg, 视频播放量 233、弹幕量 2、点赞数 9、投硬币枚数 4、收藏人数 8、转发人数 2, 视频作者 无聊的年, 作者简介 今天是学习.NET的好日子,相关视频:【.NET】从 TodoList 开始你的 Avalonia 之旅吧,【.NET】开源、跨平台、纯 .NET、从 net40 到 net8 全支持! FNA 和 Nez 游戏引擎开始最纯粹的 C# 游戏开发吧,gpt4o图片生成国内使用方式:调用api和镜像站无需魔法,已经接入comfyui插件,可以多图参考生图,Java、Go、Rust 实力比拼,程序员们笑出猪叫,ASP.NET Core WebApi结合JWT实现基于SignalR的实时通知【项目演示】,【迟来的更新】.NET9 重点更新内容概要,这个技巧使我的数据库查询速度提高了 400 倍!(光标分页已公开),C# 创建对象与销毁,【.NET开发者独享】仅需几行代码,借助.Net Aspire快速运行本地大语言模型,访谈Anders Hejlsberg,很多个问题探索神在思考什么https://www.bilibili.com/video/BV12UZ6YyEpv/

微信公众号:@scixing的炼丹房

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐