文章目录
一、AI 的发展历程
二、关键技术演进
- 2.1 架构演进
- 2.2 训练方法演进
- 2.3 应用领域扩展
三、重要里程碑产品/工具
- 3.1 开发框架
- 3.2 AI 应用
四、MCP
-
4.1 什么是MCP(Model Context Protocol)
- 4.1.1 定义
- 4.1.2 为什么MCP是一个突破
-
4.2 Prompt/LLM/FunctionCall/Agent/MCP区别(为什么是 MCP)
- 4.2.1 具体示例
- 4.2.2 思考
-
4.3 MCP 如何工作
- 4.3.1 MCP 架构
- 4.3.2 MCP Server 的工作原理
-
4.4 如何使用 MCP
- Cursor MCP 使用示例(自定义mcp server)
-
MCP 的一些资源
一、AI 的发展历程
-
早期探索阶段(1950-1969)
-
1950:图灵测试(Turing Test)提出
-
1956:达特茅斯会议,"人工智能"术语诞生
-
1958:感知器(Perceptron)发明,最早的人工神经网络
-
1964:ELIZA 问世,首个聊天机器人
-
1965:专家系统开始发展
-
-
第一次低谷(1970-1979)
-
AI 研究经费削减
-
计算能力限制
-
理论基础不足
-
实际应用困难
-
-
专家系统繁荣(1980-1987)
-
1980s:专家系统广泛应用
- XCON:Digital Equipment 公司的配置系统
- MYCIN:医疗诊断系统
-
1982:Hopfield 网络提出
-
1986:反向传播算法(Backpropagation)发展
-
-
第二次低谷(1988-1993)
-
专家系统维护成本高
-
适应性差
-
通用性不足
-
-
现代AI起步(1994-2010)
-
1997:IBM Deep Blue 战胜国际象棋冠军卡斯帕罗夫
-
1998:支持向量机(Support Vector Machine,SVM)理论成熟
-
2006:深度学习概念提出
- 深度信念网络
- 预训练技术
-
2010:ImageNet 大规模视觉识别挑战赛开始
-
-
深度学习爆发(2011-2018)
-
2011:IBM Watson 在智力问答节目获胜
-
2012:AlexNet 在 ImageNet 比赛中取得突破性进展
-
2014:
- GAN(生成对抗网络,Generative Adversarial Network)提出
- DeepMind 被 Google 收购
-
2015:
- ResNet 残差网络提出
- 谷歌开源 TensorFlow 框架
-
2016:
- AlphaGo 战胜李世石
- OpenAI 成立
-
2017:
- Transformer 架构提出
- AlphaGo Zero 发布
-
2018:BERT(Bidirectional Encoder Representation from Transformers) 模型发布
-
-
大语言模型时代(2019-2022)
-
2019:
- GPT-2 发布
- BERT 得到广泛应用
-
2020:
- GPT-3 发布
- DALL-E 首次亮相
-
2021:
- Codex(GitHub Copilot 背后的模型)发布
- PaLM 模型发布
-
2022:
- ChatGPT 发布
- Stable Diffusion 发布
- DALL-E 2 发布
-
-
AI 大爆发(2023-至今)
-
2023(AI大模型竞争年 GPT系列、Claude系列1.0-2.1):
- GPT-4 发布
- Claude 系列模型发布
- Midjourney V5
- Stable Diffusion XL
- Google发布Gemini
- DALL-E 3
- Code Llama
- Llama 2
-
2024(AI应用落地年):
- Claude 3
- Gemini 1.5
- GPT-4 Turbo
- Sora(OpenAI 视频生成模型)
-
2025
- Deepseek
- GPT-4
- Claude 3.5,Claude 4
- AI Agent
-
二、关键技术演进
2.1 架构演进
- 感知器 → 多层感知器
- CNN → RNN → LSTM
- Transformer
- Diffusion Models
2.2 训练方法演进
- 监督学习
- 无监督学习
- 强化学习
- 半监督学习
- 自监督学习
- 提示学习(Prompt Learning)
2.3 应用领域扩展
- 计算机视觉:
- 图像分类
- 目标检测
- 图像生成
- 视频生成
- 自然语言处理:
- 机器翻译
- 文本生成
- 问答系统
- 对话系统
- 语音技术:
- 语音识别
- 语音合成
- 声音克隆
- 多模态:
- 图文理解
- 跨模态生成
- 3D 生成
三、重要里程碑产品/工具
3.1 开发框架
- TensorFlow
- PyTorch
- JAX
- Keras
- Hugging Face Transformers
3.2 AI 应用
- 语言模型:
- ChatGPT
- Claude
- Gemini
- Llama
- 图像生成:
- DALL-E
- Midjourney
- Stable Diffusion
- 代码生成:
- GitHub Copilot
- Amazon CodeWhisperer
- Cursor
四、MCP
在2024.11月之前,AI 技术虽然日新月异,但是 AI 应用层的开发并没有多少新的东西,大体还是Prompt、RAG(Retrieval Augmented Generation)、Agent。
但是自从去年 11 月底 Claude(Anthropic) 主导发布了 MCP(Model Context Protocol 模型上下文协议) 后,AI 应用层的开发算是进入了新的时代。
MCP逐渐被接受,是因为MCP是开放标准。在AI项目开发中可以发现,集成AI模型复杂。MCP的优势:一是开放标准利于服务商开发API,二是避免重复造轮子,可利用现有MCP服务增强Agent。
查看全球热点趋势的网站 Google Trends
4.1 什么是MCP(Model Context Protocol)
4.1.1 定义
MCP(Model Context Protocol,模型上下文协议) ,2024年11月底,由 Anthropic(Claude的母公司) 推出的一种开放标准,是一种为大语言模型(LLM)和AI Agent生态设计的上下文管理与交互协议 ,帮助 AI 模型更好地理解上下文。它的核心目标是标准化模型与外部世界(如插件、工具、数据库、其他模型等)之间的上下文信息交换和调用方式。定义了模型如何获取上下文、调用外部函数、管理会话状态、处理多轮对话等机制。
简单来说,MCP 是一个 AI 大模型的标准化工具箱 。大模型可以通过这些工具与 外界互动 ,获取信息 ,并 完成具体任务。
为什么需要MCP?
- 标准化交互:不同AI模型、插件、工具之间的接口和数据格式不统一,MCP提供统一协议,降低集成和扩展成本。
- 丰富上下文:模型可以获取更丰富的上下文信息(如用户历史、环境变量、外部知识),提升智能和个性化能力。
- 安全与可控:通过协议层控制模型能访问哪些功能、数据,提升安全性和可控性。
- 多模型/多Agent协作:支持多个模型/Agent之间的协作与分工,适合复杂任务和场景。
主要内容包括:
- 上下文管理:定义如何组织、传递和更新模型的上下文信息(如历史对话、外部知识、用户状态等)。
- 多模型/多Agent协作:支持多个模型或Agent之间的信息共享与协作。
- 插件/工具调用:标准化模型调用外部工具、API、数据库等的接口协议。
- 可扩展性:为未来更多AI能力的集成和生态建设打下基础。
MCP 服务器可以提供三种主要类型的功能:
- 资源:客户端可以读取的类似文件的数据(例如 API 响应或文件内容)
- 工具:可由 LLM 调用的函数(经用户批准)
- 提示:预先编写的模板,帮助用户完成特定任务
价值:MCP是AI时代的USB协议
举个例子,在过去,为了让大模型等 AI 应用使用数据,要么复制粘贴,要么上传知识库,非常局限。
即使是最强大模型也会受到数据隔离的限制,形成信息孤岛,要做出更强的大模型,每个新数据源都需要自己重新定制实现,使真正互联的系统难以扩展,存在很多的局限性。
现在,MCP 可以直接在 AI 与数据(包括本地数据和互联网数据)之间架起一座桥梁,通过 MCP 服务器和 MCP 客户端,大家只要都遵循这套协议,就能实现"万物互联"。有了MCP,可以和数据和文件系统、开发工具、Web 和浏览器自动化、生产力和通信、各种社区生态能力全部集成,实现强大的协作工作能力,它的价值远不可估量。
4.1.2 为什么MCP是一个突破
我们知道过去一年时间,AI 模型的发展非常迅速,从 GPT 4 到 Claude Sonnet 3.5 到 Deepseek R1,推理和幻觉都进步的非常明显。
新的 AI 应用也很多,但我们都能感受到的一点是,目前市场上的 AI 应用基本都是全新的服务,和我们原来常用的服务和系统并没有集成,换句话说,AI 模型和我们已有系统集成发展的很缓慢。
例如我们目前还不能同时通过某个 AI 应用来做到联网搜索、发送邮件、发布自己的博客等等,这些功能单个实现都不是很难,但是如果要全部集成到一个系统里面,就会变得遥不可及。
如果你还没有具体的感受,我们可以思考一下日常开发中,想象一下在 IDE 中,我们可以通过 IDE 的 AI 来完成下面这些工作。
- 询问 AI 来查询本地数据库已有的数据来辅助开发
- 询问 AI 搜索 Github Issue 来判断某问题是不是已知的bug
- 通过 AI 将某个 PR 的意见发送给同事的即时通讯软件(例如 Slack)来 Code Review
- 通过 AI 查询甚至修改当前 AWS、Azure 的配置来完成部署
以上谈到的这些功能通过 MCP 目前正在变为现实,大家可以关注 Cursor MCP 和 Windsurf MCP 获取更多的信息。可以试试用 Cursor MCP + browsertools 插件来体验一下在 Cursor 中自动获取 Chrome dev tools console log 的能力。
为什么 AI 集成已有服务的进展这么缓慢?这里面有很多的原因,一方面是企业级的数据很敏感,大多数企业都要很长的时间和流程来动。另一个方面是技术方面,我们缺少一个开放的、通用的、有共识的协议标准。
MCP 就是 Claude(Anthropic) 主导发布的一个开放的、通用的、有共识的协议标准,如果我们对 AI 模型熟悉,想必对 Anthropic 这个公司不会陌生,2025.5.22他们发布了 Claude Sonnet 4、Claude Opus 4 的模型(更精准地执行指令、且在"记忆"能力上实现提升,在需要持续专注且涉及数千步骤的长期任务中保持稳定性能),到目前为止应该还是最强的编程 AI 模型。在一项对比不同大型语言模型软件工程任务表现的基准测试中,Anthropic的两款模型击败了OpenAI的最新模型,而谷歌的最佳模型则表现落后。

这里还是要多提一句,这个协议的发布最好机会应该是属于 OpenAI 的,如果 OpenAI 刚发布 GPT 时就推动协议,相信大家都不会拒绝,但是 OpenAI 变成了 CloseAI,只发布了一个封闭的 GPTs,这种需要主导和共识的标准协议一般很难社区自发形成,一般由行业巨头来主导。
Claude 发布了 MCP 后,官方的 Claude Desktop 就开放了 MCP 功能,并且推动了开源组织 Model Context Protocol,由不同的公司和社区进行参与,例如下面就列举了一些由不同组织发布 MCP 服务器的例子。
MCP 官方集成教学
- Git - Git 读取、操作、搜索。
- GitHub - Repo 管理、文件操作和 GitHub API 集成。
- Google Maps - 集成 Google Map 获取位置信息。
- PostgreSQL - 只读数据库查询。
- Slack - Slack 消息发送和查询。
第三方平台官方支持 MCP 的例子
由第三方平台构建的 MCP 服务器。
社区 MCP 服务器
下面是一些由开源社区开发和维护的 MCP 服务器。
- AWS - 用 LLM 操作 AWS 资源。
- Atlassian - 与 Confluence 和 Jira 进行交互,包括搜索/查询 Confluence 空间/页面,访问 Jira Issue 和项目。
- Google Calendar - 与 Google 日历集成,日程安排,查找时间,并添加/删除事件。
- Kubernetes - 连接到 Kubernetes 集群并管理 pods、deployments 和 services。
- X (Twitter) - 与 Twitter API 交互。发布推文并通过查询搜索推文。
- YouTube - 与 YouTube API 集成,视频管理、短视频创作等。
4.2 Prompt/LLM/FunctionCall/Agent/MCP区别(为什么是 MCP)
看到这里你可能有一个问题,在 23 年 OpenAI 发布 GPT function calling 的时候,不是也是可以实现类似的功能吗?目前热门的 AI Agent,不就是用来集成不同的服务吗?为什么又出现了 MCP。
function call、AI Agent、MCP 这三者之间有什么区别?
网上有个说法:Agent是智能体,MCP是AI时代的USB协议。
概念简述
- Prompt:提出的问题或想说的话。SYSTEM PROMPT 描述AI的角色、性格、背景知识、语气等
- LLM:大语言模型(如GPT-4),能理解和生成自然语言文本
- Function Call:LLM通过结构化方式调用外部函数/工具的机制(单一API调用)
- AI Agent:具备自主决策、任务分解、调用工具能力的智能体,通常基于LLM,利用Function Calling和MCP来分析和执行任务,实现特定目标(复杂任务自动化)
- MCP:Model Context Protocol,标准化模型与外部世界(工具、Agent等)交互的协议,使大模型与API无缝交互(场景:多Agent协作、插件生态)
区别与联系
1.LLM(大语言模型)
- 本质:核心的AI能力提供者,负责理解和生成文本。
- 局限:本身不具备调用外部工具、记忆复杂上下文、主动决策等能力。
2.Function Call(函数调用)
- 本质:让LLM能以结构化方式调用外部函数/API的机制。充当 AI 模型与外部系统之间的桥梁,不同的模型有不同的 Function Calling 实现,代码集成的方式也不一样。由不同的 AI 模型平台来定义和实现(通过代码给 LLM 提供一组 functions,并且提供清晰的函数描述、函数输入和输出,LLM 就可以根据清晰的结构化数据进行推理、执行函数)
- 局限:通常是一次性、无复杂上下文管理,功能有限。处理不好多轮对话和复杂需求,适合边界清晰、描述明确的任务。如果需要处理很多的任务,那么 Function Calling 的代码比较难维护
3.AI Agent(智能体)
- 本质:智能系统,自主运行以实现特定目标。在LLM基础上,能自主决策、任务分解、调用多种工具/函数的 。(传统的 AI 聊天仅提供建议或者需要手动执行任务,AI Agent 则可以分析具体情况、做出决策、并自行采取行动)
- AI Agent 可以利用 MCP 提供的功能描述来理解更多的上下文,并在各种平台/服务自动执行任务
- Agent概念的核心:让AI真正实现自主完成任务 想+做
- 联系:通常用LLM作为"思考大脑",通过Function Call等方式与外部世界交互。
- 优势:能处理复杂、多步任务,维护长期目标和上下文。
4.MCP(Model Context Protocol)
- 本质:一个标准协议,定义模型与外部世界(工具、Agent、环境等)如何结构化交互、共享上下文、管理会话,如同电子设备的 Type C 协议(可以充电也可以传输数据)。 旨在替换碎片化的 Agent 代码集成,建立通用标准,服务商可以基于协议推出自己服务的AI能力、更强大的AI应用;开发者也无需重复造轮子,通过开源项目可以建立强大的 AI Agent 生态
- 联系:
- MCP可以规范Function Call的格式和流程。
- MCP为AI Agent提供统一的上下文、工具发现、权限管理等能力。
- LLM通过MCP可以更好地与外部世界协作,成为Agent的一部分。
- 优点:可以在不同的应用/服务之间保持上下文,从而增强整体自主执行任务的能力
MCP 与 Function Call 的区别
- MCP(Model Context Protocol),模型上下文协议
- Function Calling,函数调用
这两种技术都旨在增强 AI 模型与外部数据的交互能力,但 MCP 不止可以增强 AI 模型,还可以是其他的应用系统。
(MCP 协议 与 Function Calling 相似,MCP最大优点 是整合之前各大模型不同的Function Call标准 ,形成一个统一的标准协议)



4.2.1 具体示例
1.LLM 只做问答
用户问:"北京天气如何?"
- LLM直接生成文本:"北京今天晴,气温25度。"
2.Function Call
用户问:"北京天气如何?"
- LLM识别到需要调用天气API,生成结构化调用

- 外部系统执行API,返回结果,LLM再生成回答。
3.AI Agent
用户问:"帮我订明天去北京的机票,并告诉我天气。"
- Agent分解任务:
- 查询明天北京天气(调用getWeather)
- 查询航班(调用searchFlight)
- 预订机票(调用bookFlight)
- Agent维护任务状态,自动串联多步操作,最终给出完整答复。
4.MCP
同样的任务,MCP提供:
- 统一的上下文(如用户历史、可用API、权限等)
- 结构化的多轮交互协议
- 支持多Agent/多工具协作
MCP交互示例:
JSON
{
"function_call": {
"name": "getWeather",
"arguments": {"city": "Beijing"}
}
}
- MCP让LLM/Agent能动态发现可用工具、获取丰富上下文、自动完成多步任务。
4.2.2 思考
为什么 Claude 推出 MCP 后会被广泛接受呢?开发AI项目过程中,将 AI 模型集成现有的系统或者第三方系统比较麻烦。虽然市面上有一些框架支持 Agent 开发,例如 LangChain Tools, LlamaIndex 或者是 Vercel AI SDK。
LangChain 和 LlamaIndex 虽然都是开源项目,但是整体发展还是挺混乱的,首先是代码的抽象层次太高了,想要推广的都是让开发人员几行代码就完成某某 AI 功能,这在 Demo 阶段是挺好用的,但是在实际开发中,只要业务一旦开始复杂,糟糕的代码设计带来了非常糟糕的编程体验。还有就是这几个项目都太想商业化了,忽略了整体生态的建设。
还有一个就是 Vercel AI SDK,尽管 Vercel AI SDK 代码抽象的比较好,但是也只是对于前端 UI 结合和部分 AI 功能的封装还不错,最大的问题是和 Nextjs 绑定太深了,对其它的框架和语言支持度不够。
所以 Claude 推动 MCP 可以说是一个很好的时机,首先是 Claude Sonnet 3.5 在开发人员心中有较高的地位,而 MCP 又是一个开放的标准,所以很多公司和社区都愿意参与进来,希望 Claude 能够一直保持一个良好的开放生态。
MCP 对于社区生态的好处主要是下面两点:
- 开放标准给服务商,服务商可以针对 MCP 开放自己的 API 和部分能力。
- 不需要重复造轮子,开发者可以用已有的开源 MCP 服务来增强自己的 Agent。
4.3 MCP 如何工作
4.3.1 MCP 架构

MCP 遵循客户端-服务器架构(client-server),总共分为了下面五个部分:
- MCP Hosts(MCP 主机): Hosts 是指 LLM 启动连接的应用程序,像 Cursor, Claude Desktop、Cline 这样的应用程序。
- MCP Clients(MCP 客户端): 客户端是用来在 Hosts 应用程序内维护与 Server 之间 1:1 连接。
- MCP Servers(MCP 服务器): 通过标准化的协议,为 Client 端提供上下文、工具和提示。
- Local Data Sources(本地资源): 本地的文件、数据库和 API,可供 MCP Server 安全访问。
- Remote Services(远程资源): 外部的文件、数据库和 API。
整个 MCP 协议核心的在于 Server,因为 Host 和 Client 相信熟悉计算机网络的都不会陌生,非常好理解,但是 Server 如何理解呢?
看看 Cursor 的 AI Agent 发展过程,我们会发现整个 AI 自动化的过程发展会是从 Chat 到 Composer 再进化到完整的 AI Agent。
AI Chat 只是提供建议,如何将 AI 的 response 转化为行为和最终的结果,全部依靠人类,例如手动复制粘贴,或者进行某些修改。
AI Composer 是可以自动修改代码,但是需要人类参与和确认,并且无法做到除了修改代码之外的其它操作。
AI Agent 是一个完全的自动化程序,未来完全可以做到自动读取 Figma 的图片,自动生产代码,自动读取日志,自动调试代码,自动 push 代码到 GitHub。
而 MCP Server 就是为了实现 AI Agent 的自动化而存在的,它是一个中间层,告诉 AI Agent 目前存在哪些服务,哪些 API,哪些数据源,AI Agent 可以根据 Server 提供的信息来决定是否调用某个服务,然后通过 Function Calling 来执行函数。
MCP Client
MCP client 充当 LLM 和 MCP server 之间的桥梁,MCP client 的工作流程如下:
- MCP client 首先从 MCP server 获取可用的工具列表。
- 将用户的查询连同工具描述通过 function calling 一起发送给 LLM。
- LLM 决定是否需要使用工具以及使用哪些工具。
- 如果需要使用工具,MCP client 会通过 MCP server 执行相应的工具调用。
- 工具调用的结果会被发送回 LLM。
- LLM 基于所有信息生成自然语言响应。
- 最后将响应展示给用户。
Claude Desktop 和Cursor都支持了MCP Server接入能力,它们就是作为 MCP client来连接某个MCP Server感知和实现调用。
MCP Server
MCP server 是 MCP 架构中的关键组件,它可以提供 3 种主要类型的功能:
- 资源(Resources):类似文件的数据,可以被客户端读取,如 API 响应或文件内容。
- 工具(Tools):可以被 LLM 调用的函数(需要用户批准)。
- 提示(Prompts):预先编写的模板,帮助用户完成特定任务。
这些功能使 MCP server 能够为 AI 应用提供丰富的上下文信息和操作能力,从而增强 LLM 的实用性和灵活性。
你可以在 MCP Servers Repository 和 Awesome MCP Servers 这两个 repo 中找到许多由社区实现的 MCP server。使用 TypeScript 编写的 MCP server 可以通过 npx 命令来运行,使用 Python 编写的 MCP server 可以通过 uvx 命令来运行。
4.3.2 MCP Server 的工作原理
我们先看一个简单的例子,假设我们想让 AI Agent 完成自动搜索 GitHub Repository,接着搜索 Issue,然后再判断是否是一个已知的 bug,最后决定是否需要提交一个新的 Issue 的功能。
那么我们就需要创建一个 Github MCP Server,这个 Server 需要提供查找 Repository、搜索 Issues 和创建 Issue 三种能力。
该后台服务进程 核心功能:将一系列GitHub操作封装成工具Tools,并提供给一个外部系统(很可能是一个大型语言模型或AI智能体)来调用。
我们直接来看看代码:
TypeScript
// 服务器初始化,创建一个服务器实例
const server = new Server(
{
name: "github-mcp-server",
version: VERSION,
},
{
capabilities: {
tools: {},
},
}
);
// 菜单------注册可用的工具列表。
// setRequestHandler 为服务器注册一个请求处理器,ListToolsRequestSchema列出所有可用工具
// inputSchema: zodToJsonSchema(...): 每个工具的"使用说明书"。定义调用这个工具需要提供哪些参数,以及这些参数的格式和类型。zod库来做格式校验
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "search_repositories",
description: "Search for GitHub repositories",
inputSchema: zodToJsonSchema(repository.SearchRepositoriesSchema),
},
{
name: "create_issue",
description: "Create a new issue in a GitHub repository",
inputSchema: zodToJsonSchema(issues.CreateIssueSchema),
},
{
name: "search_issues",
description: "Search for issues and pull requests across GitHub repositories",
inputSchema: zodToJsonSchema(search.SearchIssuesSchema),
}
],
};
});
// 处理工具调用请求
// CallToolRequestSchema 处理器负责处理"调用某个具体工具"的请求,当外部系统说"帮我执行create_issue"操作时,它会被触发
server.setRequestHandler(CallToolRequestSchema, async (request) => {
try {
if (!request.params.arguments) {
throw new Error("Arguments are required");
}
switch (request.params.name) {
case "search_repositories": {
// 使用zod验证传入的参数 是否符合SearchRepositoriesSchema定义的规范
const args = repository.SearchRepositoriesSchema.parse(request.params.arguments);
// 校验通过,调用searchRepositories 实际的业务逻辑函数
const results = await repository.searchRepositories(
args.query,
args.page,
args.perPage
);
return {
content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
};
}
case "create_issue": {
const args = issues.CreateIssueSchema.parse(request.params.arguments);
const { owner, repo, ...options } = args;
const issue = await issues.createIssue(owner, repo, options);
return {
content: [{ type: "text", text: JSON.stringify(issue, null, 2) }],
};
}
case "search_issues": {
const args = search.SearchIssuesSchema.parse(request.params.arguments);
const results = await search.searchIssues(args);
return {
content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
};
}
default:
throw new Error(`Unknown tool: ${request.params.name}`);
}
} catch (error) {}
});
async function runServer() {
// StdioServerTransport 是理解这个服务运行方式的关键。它没有使用常见的HTTP(网络端口),而使用stdio (Standard Input/Output,标准输入/输出) 作为通信方式
// 这意味着:这个服务作为一个独立的命令行进程运行。它的父进程(比如AI模型的主程序)通过向它的标准输入(stdin)写入请求数据来和它通信,并通过读取它的标准输出(stdout)来接收响应。这是一种高效的进程间通信方式
const transport = new StdioServerTransport();
// 将服务器逻辑和通信方式连接起来,让服务器正式开始监听来自stdio的请求
await server.connect(transport);
console.error("GitHub MCP Server running on stdio");
}
runServer().catch((error) => {
console.error("Fatal error in main():", error);
process.exit(1);
});
上面的代码中,我们通过 server.setRequestHandler
来告诉 Client 端我们提供了哪些能力,通过 description
字段来描述这个能力的作用,通过 inputSchema
来描述完成这个能力需要的输入参数。
一个设计良好、模块化的AI工具集服务,将复杂的GitHub操作简化为AI可以直接理解和调用的标准化工具。核心功能:将一系列GitHub操作封装成工具Tools,并提供给一个外部系统(很可能是一个大型语言模型或AI智能体)来调用。
- 启动:作为一个命令行工具启动,通过标准输入/输出与外界通信。
- 广播能力:当被问及时,它会返回一个包含 search_repositories、create_issue 和 search_issues 三个工具的列表,并附上详细的参数说明。
- 执行任务:当收到调用具体工具的请求时,它会:
- 验证传入的参数是否合法。
- 调用相应的函数去执行真正的 GitHub API 操作。
- 将操作结果返回给请求方。
我们再来看看具体的实现代码:
TypeScript
// 使用zod库定义调用GitHub API时所需的参数结构
// 一个可复用的基础搜索选项
export const SearchOptions = z.object({
q: z.string(), // 搜索查询,必须是字符串
order: z.enum(["asc", "desc"]).optional(), // 排序方式,可选,且值必须是 'asc' 或 'desc'
page: z.number().min(1).optional(), // 页码,可选,必须是数字且最小为 1
per_page: z.number().min(1).max(100).optional(), // 每页数量,可选,必须是数字,范围在 1-100
});
// 扩展基础选项,用于搜索 Issue(Issue有自己独特的排序标准,如按评论数排序)
export const SearchIssuesOptions = SearchOptions.extend({
sort: z.enum([ // 排序字段
"comments",
...
]).optional(),
});
// 异步函数,搜索用户
// typeof SearchUsersSchema 获取zod schema对象;z.infer<> 从schema中自动推断出TypeScript类型;保证类型安全
export async function searchUsers(params: z.infer<typeof SearchUsersSchema>) {
return githubRequest(buildUrl("https://api.github.com/search/users", params));
}
// 专门为搜索仓库SearchRepositories函数定义的Schema。describe为字段添加描述信息,可以被一些自动化工具(如文档生成器或AI)读取
export const SearchRepositoriesSchema = z.object({
query: z.string().describe("Search query (see GitHub search syntax)"),
page: z.number().optional().describe("Page number for pagination (default: 1)"),
perPage: z.number().optional().describe("Number of results per page (default: 30, max: 100)"),
});
// 搜索仓库的函数
export async function searchRepositories(query: string,
page: number = 1,
perPage: number = 30) {
const url = new URL("https://api.github.com/search/repositories");
url.searchParams.append("q", query);
url.searchParams.append("page", page.toString());
url.searchParams.append("per_page", perPage.toString());
const response = await githubRequest(url.toString());
// 使用Zod schema(GitHubSearchResponseSchema),验证返回的数据格式是否符合预期
return GitHubSearchResponseSchema.parse(response);
}
这段代码主要由两部分组成:
- Zod Schemas:定义数据结构的"蓝图"或"规则书"。
- API 调用函数:实际执行与 GitHub API 通信的"执行者"。
可以很清晰的看到,我们最终实现是通过了 https://api.github.com
的 API 来实现和 Github 交互的,我们通过 githubRequest
函数来调用 GitHub 的 API,最后返回结果。
在调用 Github 官方的 API 之前,MCP 的主要工作是描述 Server 提供了哪些能力(给 LLM 提供),需要哪些参数(参数具体的功能是什么),最后返回的结果是什么。
所以 MCP Server 并不是一个新颖的、高深的东西,它只是一个具有共识的协议。
如果我们想要实现一个更强大的 AI Agent,例如我们想让 AI Agent 自动的根据本地错误日志,自动搜索相关的 GitHub Repository,然后搜索 Issue,最后将结果发送到 Slack。
那么我们可能需要创建三个不同的 MCP Server,一个是 Local Log Server,用来查询本地日志;一个是 GitHub Server,用来搜索 Issue;还有一个是 Slack Server,用来发送消息。
AI Agent 在用户输入 我需要查询本地错误日志,将相关的 Issue 发送到 Slack
指令后,自行判断需要调用哪些 MCP Server,并决定调用顺序,最终根据不同 MCP Server 的返回结果来决定是否需要调用下一个 Server,以此来完成整个任务。
4.4 如何使用 MCP
如果你还没有尝试过如何使用 MCP 的话,我们可以考虑用 Cursor(此处以Cursor为例),Claude Desktop 或者 Cline 来体验一下。
当然,我们并不需要自己开发 MCP Servers,MCP 的好处就是通用、标准,所以开发者并不需要重复造轮子(但是学习可以重复造轮子)。
首先推荐的是官方组织的一些 Server:官方的 MCP Server 列表。
目前社区的 MCP Server 还是比较混乱,有很多缺少教程和文档,很多的代码功能也有问题,我们可以自行尝试一下 Cursor Directory 的一些例子,具体的配置和实战 可以参考官方文档。
MCP Github地址:github.com/modelcontex...
- 官方MCP服务:github.com/modelcontex...
- 第三方和个人开发的MCP服务
- MCP 工具的聚合网站:smithery.ai
Smithery平台上的MCP工具与github上的MCP工具对比:
- 托管方式:
- Smithery提供两种MCP服务器,①远程,由Smithery在其基础设施上运行,用户通过网络访问;②本地,用户通过Smithery的CLI工具将MCP服务器安装并运行在本地环境中。
- Github:主要提供MCP服务器源码,开发者自行下载配置并在本地服务器运行
- 安装与管理
- Smithery提供统一的界面和CLI工具
- Github:需要手动克隆,安装依赖项
Cursor MCP 使用示例(自定义mcp server)
使用模型上下文协议 (MCP) 插件系统将外部工具和数据源连接到 Cursor
MCP 是一个开放协议,它规范了应用程序向 LLM 提供上下文和工具的方式。MCP 可以理解为 Cursor 的插件系统,它允许您通过标准化接口将 Agent 连接到各种数据源和工具,从而扩展 Agent 的功能。
用途:MCP 允许您将 Cursor 连接到外部系统和数据源。这意味着您可以将 Cursor 与现有的工具和基础架构集成,而无需在代码本身之外告知 Cursor 项目的结构。
Cursor工具中集成mcp server功能对开发增加效率非常明显,配置入口在:File--->Preferences--->Cursor Settings--->MCP--->MCP Servers--->Add new global MCP server
手动配置
MCP 配置文件采用 JSON 格式,结构如下:
JSON
// This example demonstrated an MCP server using the stdio format
// Cursor automatically runs this process for you
// This uses a Python server, ran with `python`
{
"mcpServers": {
"wj-server-name": {
"command": "python",
"args": ["server.py"],
"env": {
"API_KEY": "xxx"
}
}
}
}
基于MCP(Model Context Protocol)协议的天气查询插件服务,可以通过 MCP 框架与外部系统集成,实现"查询指定城市实时天气"的功能。
Python
#!/usr/bin/env python3
import asyncio # Python的标准库,用于编写异步代码,适合处理网络请求等I/O密集型任务
import os
from typing import Any, Dict
import aiohttp # 第三方库,用于执行异步的HTTP请求
from mcp.server import Server # MCP框架相关,用于定义服务、工具和数据类型
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
# 和风天气API设置
API_KEY = os.getenv('WEATHER_API_KEY') # 需要在mcp.json里配置
API_URL = "https://mq564tupt3.re.qweatherapi.com/v7/weather/now"
# 服务初始化。创建一个MCP服务实例,服务名为weather-mcp-server
server = Server("weather-mcp-server")
# 异步请求和风天气API,查询指定城市的实时天气
async def query_weather(city: str) -> Dict[str, Any]:
"""查询天气API"""
if not API_KEY:
return {"error": "WEATHER_API_KEY环境变量未设置"}
params = {
"location": city,
"key": API_KEY
}
try:
# 使用aiohttp的标准模式,创建一个客户端会话,并以aiohttp异步方式发送GET请求
async with aiohttp.ClientSession() as session:
async with session.get(API_URL, params=params) as response:
if response.status == 200:
return await response.json()
else:
return {"error": f"API调用失败: {await response.text()}"}
except Exception as e:
return {"error": f"请求失败: {str(e)}"}
# 工具列表说明
@server.list_tools() # 装饰器Decorator,将list_tools函数注册到server实例上,作为"列出所有工具"请求的处理器
async def list_tools() -> list[Tool]:
return [
Tool(
name="weather_query",
description="查询指定城市的实时天气",
# 输入参数为city
inputSchema={
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "要查询的城市名称(如beijing/shanghai/shenzhen)"
}
},
"required": ["city"]
}
)
]
# 工具调用实现。根据工具名和参数,执行相应的功能
@server.call_tool()
async def call_tool(name: str, arguments: Dict[str, Any]) -> list[TextContent]:
# 如果调用weather_query工具,提取城市名、调用API查询天气、返回结果格式化为文本内容返回
if name == "weather_query":
city = arguments.get("city", "")
result = await query_weather(city)
if "error" in result:
return [TextContent(type="text", text=f"Error: {result['error']}")]
if result.get("code") != "200":
return [TextContent(type="text", text=f"API返回错误: {result.get('code')}")]
now = result.get("now", {})
weather_text = (
f"{city} 当前天气:{now.get('text', '未知')}\n"
f"温度:{now.get('temp', '未知')}℃\n"
f"风向:{now.get('windDir', '未知')}\n"
f"风速:{now.get('windSpeed', '未知')} km/h"
)
return [TextContent(type="text", text=weather_text)]
raise ValueError(f"Unknown tool: {name}")
async def main():
# stdio_server表示服务器的通信方式是标准输入/输出(stdio),而不是通过网络端口
async with stdio_server() as (read_stream, write_stream):
# 启动服务器的主事件循环。服务器会开始从read_stream(标准输入)监听请求,并将响应写入write_stream(标准输出)
await server.run(
read_stream,
write_stream,
server.create_initialization_options()
)
if __name__ == "__main__":
asyncio.run(main())
MCP插件服务:通过和风天气API查询实时天气。对外暴露一个工具weather_query,输入城市名、返回天气信息
使用Python和asyncio,构建一个后台服务进程,将将 Hugging Face 的 BLOOM 模型封装成一个标准化的"工具",供外部系统(如 AI 大模型)调用。
Python
# Hugging Face API settings
API_TOKEN = os.getenv('API_KEY')
API_URL = "https://api-inference.huggingface.co/models/bigscience/bloom"
# Create MCP server
server = Server("huggingface-mcp-server")
async def query_huggingface(payload: Dict[str, Any]) -> Dict[str, Any]:
"""Query Hugging Face API"""
if not API_TOKEN:
return {"error": "API_KEY environment variable not set"}
headers = {"Authorization": f"Bearer {API_TOKEN}"}
try:
# 使用aiohttp的标准模式,创建一个客户端会话,并以异步方式发送一个POST请求,将payload作为JSON数据发送
async with aiohttp.ClientSession() as session:
async with session.post(API_URL, headers=headers, json=payload) as response:
if response.status == 200:
result = await response.json()
return result
else:
error_text = await response.text()
return {"error": f"API call failed: {error_text}"}
except Exception as e:
return {"error": f"Request failed: {str(e)}"}
@server.list_tools() # 装饰器Decorator,将list_tools函数注册到server实例上,作为"列出所有工具"请求的处理器
async def list_tools() -> list[Tool]:
"""List available tools"""
return [
Tool(
name="huggingface_generate",
description="Generate text using Hugging Face BLOOM model",
inputSchema={ # 工具的使用说明书,使用JSON Schema格式定义。告诉调用方需要提供哪些参数(prompt是必须的),参数的类型(string,integer,number),以及默认值
"type": "object",
"properties": {
"prompt": {
"type": "string",
"description": "The text prompt to generate from"
},
"max_length": {
"type": "integer",
"description": "Maximum length of generated text",
"default": 100
},
"temperature": {
"type": "number",
"description": "Temperature for generation",
"default": 0.7
}
},
"required": ["prompt"]
}
)
]
@server.call_tool() # 装饰器Decorator,将call_tool函数注册为"执行具体工具"请求的处理器
async def call_tool(name: str, arguments: Dict[str, Any]) -> list[TextContent]:
"""Handle tool calls"""
if name == "huggingface_generate":
prompt = arguments.get("prompt", "")
max_length = arguments.get("max_length", 100)
temperature = arguments.get("temperature", 0.7)
# Call Hugging Face API
hf_payload = {
"inputs": prompt,
"parameters": {
"max_length": max_length,
"temperature": temperature,
"return_full_text": False
}
}
# 调用query_huggingface函数来完成实际的 API 请求
result = await query_huggingface(hf_payload)
if "error" in result:
return [TextContent(type="text", text=f"Error: {result['error']}")]
else:
generated_text = result[0].get('generated_text', '') if result else ''
return [TextContent(type="text", text=generated_text)]
raise ValueError(f"Unknown tool: {name}")
async def main():
"""Main entry point"""
# stdio_server表示服务器的通信方式是标准输入/输出(stdio),而不是通过网络端口
async with stdio_server() as (read_stream, write_stream):
# 启动服务器的主事件循环。服务器会开始从read_stream(标准输入)监听请求,并将响应写入write_stream(标准输出)
await server.run(
read_stream,
write_stream,
server.create_initialization_options()
)
if __name__ == "__main__": # Python 的标准入口点,确保只有当这个文件被直接执行时,asyncio.run(main()) 才会运行,从而启动整个服务
asyncio.run(main())
这是一个非常典型的 AI Agent 工具化 实践,将一个外部服务(Hugging Face API)包装成了一个可以让 AI 模型方便、安全调用的标准化工具。
完成 server.py、requirements.txt,并在Cursor的config.json添加MCP服务器配置后,可以在Cursor中使用这个自定义模型,操作步骤如下:
步骤 1: 启动你的本地服务器
运行 server.py 文件。这个服务器会作为一个"中间人",接收来自 Cursor 的请求,请求和风天气的API/转发给 Hugging Face API。
重要提示: 在你使用自定义模型的整个过程中,这个终端窗口必须保持打开状态。关闭它就会中断服务器,Cursor 将无法连接。
步骤 2: 在 Cursor 中选择并使用你的模型、开始聊天
选择 wj-server-name 后,你就可以像平常一样使用 Cursor 的聊天功能了。
两种方式:
- Cursor编辑器 选中/激活weather-server,找到weather-server相关的工具。
- 选择weather_query工具,输入参数(城市名),工具会自动调用MCP Server,返回天气信息并显示在编辑器侧边栏或弹窗中
- 在Cursor的Chat,选择weather-server 作为当前MCP工具,输入
weather_query city=beijing
所有这些请求现在都会发送到你的本地 server.py,再由它调用 和风天气 的API(可以用其他各种模型等)进行处理,最后将结果返回到 Cursor 界面。
MCP 的一些资源
MCP 官方资源
社区的 MCP Server 的列表
Agent
2D数字人项目:github.com/wan-h/aweso...
参考: