模型上下文协议(Model Context Protocol,简称MCP)正在经历爆炸性增长,成为AI代理标准领域的主导力量。Google和OpenAI已经宣布全面支持MCP,昨天,国内阿里云也加入战局,宣布全面支持MCP相关能力。这标志着MCP已成为AI Agent标准之争的事实赢家。
更值得注意的是,今天早晨,Google还发布了一个与MCP互补的协议,名为Agent2Agent(A2A),进一步扩展了AI代理之间的交互能力。这一系列发展表明,业界正在快速接受MCP作为连接AI应用的标准化方式。
然而,很多人对MCP的来龙去脉还不是那么了解。在听完Anthropic两位核心工程师的播客后,我才知道MCP实际上是这两位工程师的杰作,而非一个大型战略计划的产物。
要了解MCP,最好是听听它的创始人是如何思考这个协议的。通过这期播客,你不仅能理解MCP的出发点,还能一窥Anthropic公司的协作文化,以及他们试图解决的根本问题。在当前AI应用快速发展的背景下,MCP提供了一种解决互操作性和扩展性挑战的方法,这也解释了为什么它能在如此短的时间内获得广泛采用。
MCP是什么?
模型上下文协议(Model Context Protocol,简称MCP)是一种标准化协议,旨在帮助AI应用扩展自身功能或与插件生态系统集成。MCP使用客户端-服务器术语,本质上是一种让AI应用增强功能的方式,可以被视为AI应用的通用连接器(类似于USB-C接口)。
MCP的起源
MCP由Anthropic的两位工程师David和Justin创建,起源于2024年7月。当时David刚加入Anthropic几个月,主要负责内部开发工具。他发现在使用Cloud Desktop(具有出色的工具功能)和IDE(能够处理文件系统等)之间来回切换非常麻烦,需要不断复制内容。
这促使他思考如何解决这个"M×N"问题——多个应用程序需要与多个集成连接。受到语言服务器协议(LSP)的启发,他与Justin讨论了创建一个新协议的想法,两人在一个半月内共同开发了MCP。
MCP的快速发展
自发布以来,MCP已经获得了惊人的增长和认可:
1. OpenAI和Google已宣布支持MCP
2. MCP在GitHub上的星标数量已超过OpenAPI(曾是最直接的替代方案)
3. MCP规范于2025年3月26日更新,增加了对无状态/可恢复/可流式HTTP传输的支持,以及基于OAuth 2.1的全面授权功能
MCP的优势
MCP相比其他选项的主要优势包括:
- 双向通信:不仅模型可以调用工具,工具也可以修改模型的内容
- 模型独立性:不依赖于特定的模型,可以与任何模型一起工作
- 开放标准:作为开源项目,已有多家公司(如Microsoft、JetBrains等)参与开发
MCP的未来
MCP团队希望维持开放社区的本质,同时避免过度形式化的标准化过程,以便在快速发展的AI领域保持灵活性。团队欢迎更多开发者参与构建各种MCP客户端和服务器,特别是支持全部规范功能的采样客户端。
播客链接:https://www.latent.space/p/mcp
以上是播客完整对话翻译
模型上下文协议(MCP)的创造者
MCP的共同作者讲述协议的起源、挑战和未来。
Alessio [00:00:02]: 大家好,欢迎回到Latent Space。我是Alessio,Decibel的合伙人兼CTO,和我一起主持的是Swyx,Small AI的创始人。
swyx [00:00:10]: 嘿,早上好。今天我们通过远程连线与来自伦敦的Anthropic的David和Justin进行录音。欢迎你们。你们因为MCP引起了一阵炒作浪潮,我很高兴你们能抽出时间。让我们先从马嘴中听到一个简洁的定义,什么是MCP?然后我们会深入了解起源故事。但首先,MCP到底是什么?
Justin/David [00:00:43]: 是的,当然。Model Context Protocol,简称MCP,基本上是我们设计用来帮助AI应用扩展自身或与插件生态系统集成的工具。术语有些不同,我们使用客户端-服务器术语,待会儿可以讨论为什么这样命名以及它的来源。但归根结底,它确实是这样的功能——扩展和增强AI应用的功能。
swyx [00:01:05]: David,你有什么要补充的吗?
Justin/David [00:01:07]: 我认为这是个很好的描述。有很多不同的方式来解释它,但核心就像Justin所说的那样,是关于扩展AI应用。我想在这里强调一点,这里关注的是AI应用而不是模型本身,这是一个常见的误解,我们稍后可以讨论。另一个我们使用并且比较喜欢的比喻是:MCP就像是AI应用的USB-C接口,它旨在成为连接整个生态系统的通用连接器。
swyx [00:01:44]: 是的,特别有趣的特征是,就像你说的,客户端和服务器,它是双向的,对吧?就像USB-C是双向的一样,这可能非常有趣。让我们深入了解一下起源故事。有很多人尝试制定标准,有很多人尝试构建开源项目。我的感觉是,Anthropic正在大力吸引开发者,这是其他实验室不做的方式。所以我也很好奇,是否有任何外部影响,还是就是你们两个人在某个房间里交流想法?
Justin/David [00:02:18]: 实际上主要就是我们两个人在房间里交流想法。这不是某个大战略的一部分。如果回溯到2024年7月,我当时刚加入Anthropic大约三个月或两个月。我主要从事内部开发工具工作,这也是我之前多年来一直在做的。作为其中的一部分,我想我们在努力让更多Anthropic员工更深入地使用和集成我们拥有的模型。因为我们已经看到了它有多好,将来会变得更加惊人。当然,尽可能多地使用自己的模型是很重要的。作为我的开发工具背景的一部分,我很快对这样的想法感到沮丧:一方面,我有Cloud Desktop,这是一个带有很棒功能的惊人工具,我真的很喜欢。但它仅限于那些确切的功能集,没有办法扩展它。另一方面,我喜欢在IDE中工作,它可以在文件系统和其他很多方面发挥作用。但它们没有像Cloud Desktop那样的功能。所以我一直在Cloud Desktop和IDE之间来回复制东西,这很快让我感到非常沮丧。这种沮丧的一部分使我思考:我该如何解决这个问题?我们需要什么?回到我的开发者关注点,我真的在考虑:我知道如何构建所有这些集成,但我需要做什么才能让这些应用程序让我这样做?很快你就会发现这显然是一个M乘以N的问题,你有多个应用程序和多个你想构建的集成,而解决这个问题最好的方法莫过于使用一个协议。同时,我当时正在内部研究一个与LSP相关的项目,虽然那个项目没有进展,但把这些想法放在一个人的脑子里,让它们酝酿几周,于是产生了构建某种协议的想法。所以回到这个小房间,它真的就是我走进一个房间,和Justin说,我认为我们应该构建这样的东西,这是个好主意。而Justin,幸运的是,对这个想法产生了兴趣,从那时起就一起与我建立了它,这就是起源故事,就是我们两个从那时起开始,在大约一个半月的时间里构建了这个协议。
Justin/David[00:04:18]: 是的,我要稍微补充一下。所以大卫一开始说,"嘿,我们应该以某种方式连接这些应用程序。"这在很多层面上都是有意义的。因为我们已经有了这些,就像大卫说的,这些已有的内部应用程序,但我们也很清楚,我们希望构建更多的应用程序,这些应用都能与彼此协同工作。你知道,大多数人都意识到,一旦你整合了AI...我说"一旦",但这已经很明显了...AI应用程序的功能会呈指数级扩展。我们也很清楚,世界上会有许多不同的专业应用程序,比如医疗应用、法律应用、游戏开发应用等等。如果我们能够建立一种方式,让所有这些应用程序都可以扩展和增强彼此,这将是相当强大的。所以大卫提出这个想法时,我想,是的,让我们尝试一下。我们的最初想法是希望建立一些像谷歌文档那样的东西,就是说你打开一个网页应用程序,有一个像Claude这样的AI应用程序,然后当它处理文档时,能够理解文档的状态,并能够对文档进行修改。你可以想象这样一个场景,就像当今许多AI产品做的那样。然后我们意识到,"天哪,你知道什么已经在做这些事情了吗?LSP,语言服务器协议。"如果你不熟悉LSP,它是Visual Studio Code背后的协议,实际上它使用的是这样的协议:一个VSCode实例可以与另一个LSP服务器通信,这个服务器可能具备Python、Ruby或Java专业知识,然后发送"嘿,我在这个位置看到一个错误,我需要重构这段代码"等消息,服务器再发回更新。所以我们对其进行了一些调整,使其更适合AI的上下文,但这确实是我们的起点——受Web和LSP的启发。
swyx [00:05:18]: 是的,让我们深入谈谈技术细节。在这个协议中有哪些关键部分?它的工作原理是什么?你已经提到了客户端和服务器,我知道你们创建了这个双向流,其中客户端可以发送请求到服务器,然后服务器可以发送回一个请求。还有哪些细节?
Justin/David [00:05:42]: 我认为我应该从基础概念开始谈起。关于LSP,我是通过与David交谈才了解到的,而且我从来没有直接使用过它,所以我不希望给人留下我是LSP专家的印象。但从广义上讲,我认为那是David和我的想法来源。然后我们就开始设计这个协议。我想说的是,如果你看一下规范,你会发现本质上有三种消息类型。有请求和响应,这是典型的RPC样式的通信,就像HTTP的GET和POST请求一样。然后还有通知,从一端发送到另一端,不需要响应。最后是取消,这基本上就是一个通知,说明不再需要响应了。这是消息类型的三个主要类别。关于协议实际做什么,核心思想是客户端(AI应用程序)可以将请求发送到服务器。从概念上讲,服务器拥有你告诉它的"能力"。所以作为一个服务器,你可以告诉客户端:"嘿,我可以做这个和那个",客户端可以请求做这些事情。同样,服务器可以请求客户端做事情。服务器可以对客户端说:"嘿,我想让你完成这个提示",或者"我想在这段文本后面添加这段内容"。此外,客户端还可以对服务器说:"嘿,这是我目前正在生成和处理的内容;这是我将要生成的内容。"所以还有这种通知,通过服务器向客户端流式传输这些通知。所有这些都是我们如何实现从服务器到客户端的信息流动。我们还有一种方式,让服务器可以将"差异"发送回客户端。所以客户端可以说:"嘿,这是一些内容。"服务器可以返回并说:"我认为我应该在这个位置添加这段内容。"与此同时,我们有一种更简单的方法,客户端可以对服务器说:"嘿,你有什么能力?"或者"让我告诉你一些关于我的事情。"这样,整个协议基本上围绕着这些能力和请求构建,这些请求可能是关于工具输入和输出的,也可能是关于"我是谁"的。
swyx [00:07:39]: 太棒了。David,你想补充什么吗?
Justin/David [00:07:42]: 是的,我想补充些细节。首先是,如果我们用简单的话解释整个协议,就是我们有三个基本构建块。首先,是从客户端到服务器的工具调用,工具调用是有请求和响应的。第二,是从服务器到客户端的修改请求,同样是有请求和响应的。第三,是客户端将内容流式传输给服务器,这些都是简单的通知。有了这三个构建块,你可以构建几乎所有我们在MCP协议规范中描述的内容,通过结合这些元素。
swyx [00:08:14]: 那么让我澄清一下,客户端是模型,服务器是文件系统、浏览器或者其他工具,对吗?
Justin/David [00:08:26]: 实际上,我们正好相反。客户端是消费者,可能是嵌入AI模型的东西。所以它可能是Cloud Desktop,或者像Cursor这样的IDE。服务器是你所说的工具。这有点让人困惑,在我解释为什么之前,其实它是非常有道理的。在我解释之前,我必须说,这是我们收到的最常见的问题,"为什么服务器不是模型?为什么模型不是服务器?"我认为为什么我们选择这种方式有很好的理由。最明显的是,我们希望能有多个服务器,但只有一个客户端。我们想让客户端能够调度、连接和与不同的服务器通信,这是你用传统的客户端-服务器架构做的事情。我们希望服务器是无状态的,能够很容易地启动多个服务器,所以我们希望将它们视为一个无状态的服务。另一个是,我们希望能够有一个统一的方式来发现服务器。我们想确保在发现服务器时,收集所有信息,了解服务器能做什么,这在传统的客户端-服务器架构中是很自然的。所以我认为这种方式很有意义,尽管它可能与人们最初的直觉相反。
Justin/David [00:09:41]: 我还要补充一点,我们这样做的另一个原因是,一般来说,我们遵循的思路是,消费者应该是客户端,生产者应该是服务器。所以在我们的情况下,模型正在消费这些能力,所以它是客户端。也许我们还可以补充,工具正在产生这些能力,所以它们是服务器。我认为另一个常见的误解是把模型看作是协议的一部分。客户端是一种应用程序,是一种应用程序,它消耗了模型的能力,正如大卫在开始时所指出的。所以在Cloud Desktop的例子中,Cloud Desktop是客户端,而不是Cloud本身。
swyx [00:10:23]: 是的,这很有价值。所以现在实际上是用户体验应用程序和开发者想要创建的工具之间的接口。有意思。我听到的是,人们在想"等等,谁对谁发出请求?"这种命名会造成一些混淆。但你给出的理由很合理,我想我会用"消费者和生产者"来思考,这似乎是你们的心智模型。那么,什么样的应用程序使用MCP?我看到你们最初的启示和使用案例来自用户在不同AI应用程序间的切换。除了这个,你们还看到哪些其他用例?当你们最初设计这个协议时,你们为哪些类型的应用程序设计它?
Justin/David [00:11:08]: 是的,我们最初关注的是IDE。从某种意义上说,我们一开始就试图解决我自己面临的问题,就是在Cursor和Cloud Desktop之间切换。但很早就变得显而易见,我们正在构建的东西可以应用于许多不同的领域。比如,如果客户端本身就包含一个模型...假设你有个聊天机器人客户端,它使用模型与你对话。那么这个聊天机器人可以通过MCP连接各种服务器来增强自己的能力,无论是搜索网页、查询数据库,还是控制智能家居设备。或者一个知识管理应用程序,它可以汇总和组织信息,可能也会使用支持MCP的服务器来获取特定领域的知识或数据分析能力。再比如,可能有一个面向学生的应用程序,它可以提供个性化的教学和反馈,然后使用MCP连接到各种教育资源和工具。这些只是一些例子,说明MCP如何可以应用于各种不同类型的应用程序。
Justin/David [00:12:19]: 是的,另一个早期用例是我们称之为"嵌入服务器"的概念。这个想法很简单:如果我在使用一个应用程序,比如说是个文档编辑器,我可以点击一个按钮,然后弹出一个小窗口,里面有一个聊天接口。这个聊天接口已经预先连接到文档编辑器,所以它可以"看到"我正在编辑的内容,并可以直接对文档进行修改。这是我们早期考虑的一个用例。另一个是互操作性,即一个支持MCP的应用能够利用其他应用的功能,无需这些应用专门为此构建集成。
swyx [00:13:11]: 这很有意思。对我来说,这听起来非常像Office插件系统,但更像是AI原生的。这很酷。让我们切换话题,谈谈一些社区上的内容。我们看到了相当多的开发者对MCP的反应,并且我要说,你们谈到的这些API设计决策非常好,比如有服务器发现、双向通信和这些东西。我看到人们非常非常积极地采用它。我们在观察者中看到了一个统计数据,MCP现在超过了OpenAPI,这是一个非常令人印象深刻的里程碑。现在有哪些社区建设的工作让你感到最自豪?
Justin/David [00:13:46]: 我认为两件事。第一个是最初的规范是由我和David编写的,但很快就变成了一个社区项目。有很多人贡献了非常重要的功能。特别是HTTP通道,那是我记得的重要功能之一。很高兴看到社区积极参与定义协议的演进。无论是直接贡献代码,还是提供反馈和建议,社区参与对MCP的发展至关重要。第二个是看到不同公司的支持。OpenAI和Google的支持是一个关键时刻,当然还有许多其他公司也在积极实施MCP。这种广泛的采用证明了MCP正在满足一个真实的需求。
Justin/David [00:14:26]: 我也非常自豪的是,随着规范的发展,我们看到了SDK的发展,尤其是在各种语言中。Python SDK是最早出现的,它非常好用,有很好的APIs设计。Java SDK也很出色,特别是最近加入的C# SDK。每个SDK都反映了各自社区的最佳实践,这真的很棒。还有一点让我自豪的是人们正在构建的所有服务器。比如有人构建了各种文件系统服务器、网络浏览器服务器,甚至还有游戏引擎服务器。看到这些创新的应用真的很令人兴奋。
swyx [00:15:06]: 很酷,是的,这是一个非常活跃的生态系统。让我们谈一些技术决策。我对采用MCP感兴趣,有些是在技术方面做的决定,有些是在产品方面做的决定。我想从一个相关的问题开始:MCP与OpenAPI有何不同?因为它们解决的是同一个问题,但采用了不同的方法。
Justin/David [00:15:28]: 是的,这是个很好的问题。我认为有几个关键区别。首先,MCP是专门为AI应用设计的,支持双向通信。这意味着不仅客户端可以向服务器发送请求,服务器也可以修改模型的输出,这是OpenAPI不直接支持的功能。其次,MCP包含了丰富的元数据,允许客户端了解服务器的能力,使交互更加智能和上下文感知。第三,MCP支持异步和流式处理,这对于长时间运行的任务或实时反馈至关重要。最后,MCP的设计考虑到了AI特有的挑战,如处理不确定性和上下文管理。所以虽然OpenAPI是一个出色的API文档和交互工具,但MCP是专门为AI应用场景量身定制的。
swyx [00:17:05]: 非常好的总结。所以如果你是一个开发者,你想要构建一个MCP服务器,首先你需要理解这些关键部件。你刚才提到了三个核心构建块。你能解释一下开发者需要做什么来创建一个MCP服务器吗?
Justin/David [00:17:21]: 当然。构建MCP服务器的基本步骤是:首先,你需要定义你的服务器能力。这包括它可以提供什么功能,需要什么参数,以及它如何响应请求。其次,你需要实现处理这些能力的逻辑,这通常涉及到创建处理函数来响应客户端的调用。第三,你需要设置通信通道。MCP支持多种传输方式,包括WebSocket和HTTP,你需要选择适合你应用的方式。最后,你需要处理错误和边缘情况,确保你的服务器能够优雅地处理异常情况。幸运的是,有许多SDK可以简化这个过程,特别是Python SDK,它提供了很多有用的抽象。所以整体来说,虽然有很多细节需要考虑,但基本思路是相对直接的:定义能力,实现逻辑,设置通信,处理错误。
Justin/David [00:19:13]: 我想补充一点,实际上非常简单。如果你看我们的Python SDK,基本上你只需要定义一个继承自MCP Server的类,然后实现一些方法。大多数方法都有合理的默认值,所以你只需要实现你关心的那些。最简单的情况下,你可能只需要实现一个handle_tool_call方法,告诉服务器如何处理工具调用。这真的很简单,我们的目标是让服务器尽可能容易实现。
Alessio [00:19:44]: 我有一个问题。人们将要构建有用的、有价值的MCP服务器。但我不确定我是否听到你们讨论过认证和授权模型。对于用户来说,了解他们正在使用的服务器是否值得信任非常重要。你们是如何处理这个问题的?
Justin/David [00:20:06]: 这是个极好的问题,我很高兴你提出来。认证和授权确实是一个关键考虑因素。在MCP中,我们采用了OAuth 2.1标准作为认证框架。这允许服务器确定客户端是谁,以及它们有权访问哪些功能。具体来说,我们使用了范围(scopes)概念,服务器可以定义不同的权限级别,客户端需要请求这些范围才能访问特定功能。此外,我们还支持各种授权流程,包括授权码流程和设备流程,以适应不同的使用场景。这为开发者提供了灵活性,同时确保了安全性。我们也鼓励服务器实现适当的访问控制机制,以保护敏感数据和功能。总的来说,MCP的安全模型旨在平衡便利性和保护,让用户能够安全地使用各种服务器。
Alessio [00:21:57]: 所以本质上是委托给OAuth 2.1,然后让服务器通过范围定义可用的功能?
Justin/David [00:22:06]: 是的,完全正确。我们委托给OAuth 2.1作为一个已经经过验证的、广泛使用的标准。然后通过范围机制,服务器可以精确地控制客户端可以访问哪些功能。这不仅提供了安全性,还允许服务器实现细粒度的访问控制。
swyx[00:22:26]: 我们已经讨论了不少技术细节,我想稍微转移话题,谈谈模型独立性。这是MCP的一个关键方面,即它不依赖于特定的模型。你们能谈谈为什么这很重要,以及你们如何确保MCP能够与各种不同的模型一起工作吗?
Justin/David [00:22:46]: 这是MCP的一个核心设计原则。我们认为,构建一个真正开放的生态系统需要避免与特定模型或提供商绑定。有几个关键方面支持模型独立性:首先,MCP专注于API和接口,而不是模型的内部工作方式。这意味着任何能够理解MCP消息格式的模型都可以参与生态系统。其次,我们设计协议时考虑了不同模型的能力和限制,确保即使是能力不同的模型也能有效地参与。第三,我们支持不同的交互模式,包括聊天式和接近程序式的交互,以适应不同类型的模型。这种模型独立性对于生态系统的长期健康至关重要,它确保开发者不会被锁定在特定的技术栈中,并允许随着时间的推移采用新的和改进的模型。
Alessio [00:24:10]: 很好。我想问一下,你们是否花时间思考过MCP如何允许构建更丰富的系统?比如,你在同一个会话中可能有多个代理或助手,它们可能通过MCP连接,可能互相交互。你们能谈谈这方面的内容吗?
Justin/David [00:24:32]: 这是个很好的问题。我们确实考虑了这一点,尽管这不是我们初始设计的主要目标。但MCP确实为构建更复杂、更丰富的系统提供了基础。例如,你可以有一个主客户端与多个专业服务器通信,形成一种"团队"结构,其中不同的服务器处理不同的专业任务。另一种模式是客户端可以充当"编排者",协调多个服务器之间的交互,甚至可以在服务器之间传递信息。最有趣的可能是"嵌套"模式,其中一个MCP服务器本身可以是另一个MCP客户端,形成一种层次结构。这允许构建非常复杂的系统,其中信息可以通过多个层次流动。虽然这些高级用例在当前实现中可能还不是完全无缝的,但协议的灵活性确实允许这些类型的架构,我们期待看到社区如何探索这些可能性。
swyx [00:25:51]: 非常有趣。我想我还没有意识到MCP是如何定义代理这个概念的。我们一直在谈论客户端和服务器,但没有提到"代理"。当我们谈论代理时,我们通常指的是一个具有某种规划能力的AI助手。MCP是如何处理或定义代理的?
Justin/David [00:26:12]: 这是个很好的问题。实际上,MCP并没有直接定义"代理"这个概念。MCP主要关注通信协议和交互模式,而不是定义什么构成了代理。在MCP的上下文中,客户端可以是代理,也可以不是代理,这取决于它如何实现和使用协议。代理通常被理解为具有某种程度的自主性和规划能力的系统,而MCP提供了使这些能力更加强大的工具,但它不限制或定义这些系统必须如何工作。这种灵活性是有意的 - 我们想要一个协议,它能够支持各种不同的代理实现,从简单的基于规则的系统到复杂的规划代理。所以简单来说,MCP提供了构建和增强代理的机制,但它不规定什么是或不是代理。
Justin/David [00:27:28]: 我想补充一点,从某种意义上说,我们故意不使用"代理"这个术语,因为它在不同的上下文中有不同的含义。我们更喜欢专注于具体的功能和能力,而不是给系统贴上特定的标签。这允许开发者根据自己的需求和理解来使用协议,而不会被特定的术语所限制。
swyx [00:27:53]: 这很有道理。接下来的问题,嵌套能力是否会导致工具混淆的问题?比如说,如果我是一个代理,我连接到一个服务器,但那个服务器又连接到其他服务器,这是否会导致一种递归或混淆的情况?
Justin/David [00:28:17]: 这是一个很好的问题,也是我们考虑过的问题。嵌套确实可能导致复杂性和潜在的混淆。有几个因素需要考虑:首先,最基本的是,服务器和客户端需要清晰地理解和管理它们的职责边界。一个充当中间人的系统需要谨慎地管理传递的信息,确保上下文和意图不会丢失。其次,命名和范围界定变得非常重要 - 确保每个系统知道它正在与哪个其他系统通信,以及它可以访问哪些功能。第三,错误处理和恢复机制需要考虑嵌套的复杂性,确保问题不会在系统中级联。这确实是一个挑战领域,但也是一个机会 - 通过细心的设计和明确的边界,嵌套系统可以非常强大,允许专业化和组合。我们在协议中添加了一些功能,如上下文传递和错误传播,以帮助管理这些复杂性,但最终这也取决于实现者如何设计他们的系统。
Justin/David [00:29:43]: 我想补充一点,工具混淆是一个真实的问题,尤其是在涉及多个层次的系统中。我们在设计协议时考虑了这一点,特别是在思考如何使工具调用尽可能明确和透明。例如,我们在工具调用中包含了丰富的元数据,包括描述和参数文档,以帮助客户端理解每个工具的功能和适当的使用方式。但是,正如David所说,这在很大程度上是一个实现问题,需要系统设计者明智地处理。
Alessio [00:30:20]: 还有一个相关的问题。我们一直在讨论客户端和服务器之间的关系,但我想知道客户端是否对工具的调用有最终控制权?比如说,如果服务器想要启动一个工具调用,它是否需要得到客户端的批准?或者服务器可以自主决定调用其他工具?
Justin/David [00:30:46]: 这是一个重要的问题,关系到控制流和安全性。在MCP中,基本上是客户端保持最终控制权。服务器不能直接调用其他工具 - 它必须通过请求客户端代表它进行调用。这种设计是有意的,因为它确保了控制流的清晰性和可预测性。客户端可以查看、评估、甚至拒绝来自服务器的工具调用请求。这为客户端提供了安全机制,防止恶意或错误的服务器行为。例如,客户端可以实现策略来限制某些类型的工具调用,或者要求用户确认敏感操作。当然,客户端也可以选择自动批准某些类型的请求,以提高效率,但关键是选择权在客户端。这种模式反映了我们对安全和控制的重视,同时仍然允许构建灵活和强大的系统。
Justin/David [00:32:11]: 我想澄清一点,当我们谈论服务器不能直接调用其他工具时,我们指的是服务器不能绕过客户端直接访问其他MCP服务器。服务器当然可以使用自己的API或工具,只要这些是它自己的一部分。比如,一个文件系统服务器可以调用底层操作系统的文件操作,无需请求客户端批准。我们讨论的是在MCP生态系统内的交互模式。
Alessio [00:32:45]: 这很有帮助。现在我想回到授权和服务器信任的话题。当我们谈论带有很多第三方集成的系统时,每个集成都可能有自己的授权和信任级别。用户如何知道他们可以信任哪些服务器?除了使用OAuth,你们还有其他机制来帮助用户管理这种信任吗?
Justin/David [00:33:18]: 这是个深刻的问题,确实是整个生态系统面临的关键挑战。除了OAuth的技术机制外,我们正在考虑几种方法来解决信任问题:首先,透明度是关键 - 服务器应该清楚地声明它们的功能、数据使用政策和安全实践。我们在协议中包含了元数据字段,使服务器能够表达这些信息。其次,我们正在探索认证或验证机制的可能性,可能类似于应用商店的审核过程,尽管这需要谨慎设计以避免创建封闭的生态系统。第三,社区反馈和评级系统可能是有价值的,让用户了解其他人的经验。最后,客户端可以实现不同级别的控制 - 从完全自动化到要求用户明确批准每个服务器交互。这是一个我们还在积极思考的领域,我们欢迎社区的输入和想法。最终,这可能是一个需要技术和社会解决方案结合的问题。
Justin/David [00:34:52]: 我想补充的是,我们的目标是为服务器提供表达其意图和功能的手段,同时为客户端提供评估这些声明的工具。不过,我们也很清楚,技术机制有其局限性,生态系统的健康也依赖于良好的实践、透明度和社区规范。
swyx [00:35:20]: 非常有深度的回答。我想问的是,你们在这个项目上工作了多久?你们提到了这在某种程度上是有机形成的。什么时候你们发现,"哦,这实际上可能是一个更广泛采用的东西"?
Justin/David [00:35:35]: 我们在2024年7月开始这个项目,最初只是作为一个内部工具来解决我们自己的问题。但随着我们继续开发,我们越来越意识到这可能对更广泛的社区有价值。转折点大概是在我们完成初始设计并开始获得内部反馈后的几周。同事们的反应非常积极,许多人开始询问他们是否可以使用这个协议来解决自己的问题。这让我们认识到,我们正在解决的不仅仅是我们自己的特定问题,而是整个行业面临的更普遍的挑战。所以在开始后大约一个月,我们开始认真考虑将其作为一个开放标准发布。然后花了几个月来完善设计、编写文档,并准备初始实现。我们的目标是确保在发布时,它不仅有坚实的概念基础,还有实用的工具让人们能够立即开始使用它。
swyx [00:36:46]: 这是非常快的转变,从一个想法到一个广泛采用的标准。你们是否惊讶于它被如此快速地采用?
Justin/David [00:36:56]: 老实说,是的,我们确实感到惊讶。我们当然希望它会有所回响,但看到它如此迅速地获得关注和采用是相当惊人的。我认为这反映了行业对这种标准的真正需求。随着越来越多的AI应用被开发,互操作性和扩展性的问题变得越来越突出。MCP似乎恰好在正确的时间解决了正确的问题。也许更令人惊讶的是大公司的兴趣和支持。通常,大型组织在采用新标准时可能会更谨慎,特别是如果它们没有参与创建过程。但在这个案例中,我们看到了来自主要参与者的真正兴趣和承诺,这是非常鼓舞人心的。
swyx [00:37:38]: 关于产品方面,你们如何处理开源社区的治理?因为当你拥有像MCP这样的东西时,你会想"好的,让我们为这个创建一个基金会",但如果你做那样的事情,它会变成一个大型委员会,可能会非常缓慢。你们如何处理开源治理方面的问题?
Justin/David [00:38:04]: 这是一个我们非常重视的问题。我们的目标是在开放、包容和有效决策之间取得平衡。目前,我们的方法相对轻量级 - 我们有一个核心团队监督项目,但我们积极寻求和鼓励社区贡献。我们使用GitHub上的标准开源流程 - 问题讨论、拉取请求审查等,这使得任何人都可以参与并有发言权。关于基金会的问题,我们确实考虑过这个选项,但正如你所说,我们担心过度的形式化可能会导致发展停滞。AI领域发展如此之快,我们需要保持敏捷。所以现在我们更倾向于一种"精益治理"方法 - 足够的结构来确保项目的健康和包容性,但不会变成官僚主义的障碍。随着项目的成熟,我们可能会重新评估这种方法,但目前我们认为这种平衡对于保持动力和创新是重要的。
Justin/David [00:39:21]: 我想补充的是,我们非常注重透明度和开放性。所有的讨论和决策过程都是公开的,我们积极寻求不同利益相关方的输入。我们意识到,随着更多组织采用MCP,治理模式可能需要演变,但我们希望保持协议的开放精神,确保它不会被任何单一实体所控制。
swyx [00:40:05]: 太好了。在我们结束之前,我想问一下MCP的未来发展方向。你们正在进行哪些工作,未来的路线图是什么?
Justin/David [00:40:19]: 我们有几个令人兴奋的方向正在探索。首先是扩展和完善现有功能,尤其是基于社区反馈和实际使用经验。我们特别关注流式处理和长时间运行任务的改进,这对于许多复杂应用场景至关重要。其次,我们正在开发更多的参考实现和示例,以便开发者能够更容易地上手和实现复杂的集成。第三,我们正在探索更丰富的元数据和发现机制,使客户端能够更智能地理解和使用服务器能力。最后,我们也在考虑协议的性能优化和扩展性改进,使其能够在更多样化的环境中高效运行。总的来说,我们的目标是使MCP成为一个更强大、更灵活的工具,同时保持其简单性和可访问性。我们也非常重视社区的想法和需求,所以路线图在很大程度上将由使用者的反馈来塑造。
swyx [00:41:34]: 听起来很棒。关于无状态服务器,你们能详细说明一下吗?这对于开发者来说意味着什么?
Justin/David [00:41:46]: 当然。无状态服务器是我们正在积极开发的一个重要概念。传统上,MCP服务器需要维护与客户端会话的状态,这在某些环境中可能是复杂的,特别是在云或无服务器部署中。无状态方法允许服务器在每个请求之间不保留状态,这带来了几个重要的好处:首先,它极大地简化了部署和扩展,因为你可以轻松地横向扩展服务器而不用担心会话一致性。其次,它提高了弹性 - 如果一个服务器实例失败,请求可以简单地路由到另一个实例,而不会丢失上下文。第三,它使得在无服务器环境(如AWS Lambda或Azure Functions)中运行MCP服务器变得更加实际。从开发者的角度来看,这意味着可以更简单地构建和部署MCP服务器,特别是在云环境中。当然,这也需要一些权衡 - 上下文必须在每个请求中传递,这可能增加消息大小。但我们认为对于许多用例来说,这是一个值得的权衡,这就是为什么我们正在将其作为协议的一个重要扩展来开发。
Alessio [00:43:18]: 这很有趣。回到技术问题,你们如何处理会话管理和上下文保存?特别是在使用无状态服务器时,客户端如何维护对话状态?
Justin/David [00:43:37]: 这是一个关键问题。在无状态模式下,基本原则是会话状态由客户端管理和存储,而不是服务器。每次客户端向服务器发送请求时,它会包含必要的上下文信息,使服务器能够处理请求,就好像它一直参与对话一样。这些上下文可能包括之前的交互历史、用户偏好或任何其他相关状态。具体实现上,我们正在开发几种机制:首先是"上下文令牌"方法,其中服务器提供一个令牌(可能是加密的或签名的),客户端在后续请求中返回该令牌。其次是"完整状态"方法,其中客户端在每个请求中发送完整的会话状态。最后是"混合"方法,其中一些状态由服务器存储(可能在数据库中),而客户端只传递一个引用键。这样的灵活性允许开发者根据他们的特定需求和约束选择最合适的方法。这确实增加了客户端的复杂性,但我们正在开发抽象和工具来简化这一过程,使其对开发者来说尽可能透明。
swyx [00:45:14]: 很好的解释。在我们结束之前,有没有你们希望在社区中看到更多的东西?或者有没有你们想要分享的愿望清单?
Justin/David [00:45:26]: 绝对有!首先,我们希望看到更多的样例服务器和集成。我特别想看到更多采样客户端的实现,这些客户端能够充分利用协议的广度。这不仅仅是为了使用Claude,而是为了展示MCP的模型独立性。我也希望看到更多创新的服务器,比如游戏引擎集成、特定领域的工具或者创造性的应用。我个人很想看到与Godot游戏引擎的集成,因为这是我个人项目中使用的工具。想象一下,有一个MCP客户端或服务器能让AI运行和测试你的游戏,就像"Claude玩Pokemon"那样 - 这将是非常酷的!
Alessio [00:46:27]: 对,这听起来很有趣。我们实际上正在与David Hershey一起策划一个"Claude玩Pokemon"的黑客马拉松,所以也许我们可以将MCP整合进去。
Justin/David [00:46:40]: 那太棒了!我们很期待看到这个项目。
swyx [00:46:45]: 很好。谢谢你们抽出时间来分享你们的见解和MCP的故事。这真的很有启发性。
Alessio [00:46:53]: 是的,非常感谢你们。继续保持好工作!
Justin/David[00:46:58]: 谢谢你们两位,这次谈话很愉快。我们真的很感谢有机会分享我们的工作,也感谢社区的所有支持和兴趣。期待看到MCP继续发展壮大。