人工智能|大模型—— 框架 ——一文详解MCP(从原理到实践)

人工智能|大模型—— 框架 ——一文详解MCP(从原理到实践)

最近 MCP 这个关键词逐渐活跃在我所浏览的一些文章及评论区中。突然发现我对它仅有粗糙的理解,我决定深入学习并记录一下。在阅读这篇文章前,我也简单地浏览了现有介绍 MCP 的文章。我发现大部分文章停留在“翻译” https://modelcontextprotocol.io/ 网站中的内容,或者花时间在绝大部分用户不关心的技术细节上(还有一些纯 AI 文)。因此,我将从使用者的角度出发,分享实用内容,并以一个示例展示 MCP 的开发过程与实际应用作为结尾。本篇旨在回答以下三个问题:

  • 什么是 MCP?
  • 为什么需要 MCP?
  • 作为用户,我们如何使用/开发 MCP?

一、什么是MCP

MCP起源于2024年11月25日Anthropic发布的文章:Introducing the Model Context Protocol。MCP(Model Context Protocol,模型上下文协议)定义了应用程序和 AI 模型之间交换上下文信息的方式。这使得开发者能够以一致的方式将各种数据源、工具和功能连接到 AI 模型(一个中间协议层),就像 USB-C 让不同设备能够通过相同的接口连接一样。MCP的目标是创建一个通用标准,使AI应用程序的开发和集成变得更加简单和统一。

所谓一图胜千言,我这里引用一些制作的非常精良的图片来帮助理解:

可以看出,MCP就是以更标准的方式让 LLM Chat 使用不同工具,更简单的可视化如下图所示,这样你应该更容易理解“中间协议层”的概念了。Anthropic旨在实现 LLM Tool Call 的标准。

为保证阅读的流畅性,本文将 MCP Host / Client / Server 的定义后置。初学者/用户可暂不关注这些概念,不影响对 MCP 的使用。

二、为什么需要MCP

我认为 MCP 的出现是 prompt engineering 发展的产物。更结构化的上下文信息对模型的performance 提升是显著的。我们在构造 prompt 时,希望能提供一些更 specific 的信息(比如本地文件,数据库,一些网络实时信息等)给模型,这样模型更容易理解真实场景中的问题。
想象一下没有 MCP 之前我们会怎么做?我们可能会人工从数据库中筛选或者使用工具检索可能需要的信息,手动的粘贴到 prompt 中。随着我们要解决的问题越来越复杂,手工把信息引入到 prompt 中会变得越来越困难。为了克服手工 prompt 的局限性,许多 LLM 平台(如 OpenAI、Google)引入了 function call 功能。这一机制允许模型在需要时调用预定义的函数来获取数据或执行操作,显著提升了自动化水平。
但是 function call 也有其局限性(我对于 function call vs MCP 的理解不一定成熟,欢迎大家补充),我认为重点在于 function call 平台依赖性强,不同 LLM 平台的 function call API 实现差异较大。例如,OpenAI 的函数调用方式与 Google 的不兼容,开发者在切换模型时需要重写代码,增加了适配成本。除此之外,还有安全性,交互性等问题。

数据与工具本身是客观存在的,只不过我们希望将数据连接到模型的这个环节可以更智能更统一。Anthropic 基于这样的痛点设计了 MCP,充当 AI 模型的"万能转接头",让 LLM 能轻松的获取数据或者调用工具。更具体的说 MCP 的优势在于:

  • 生态 - MCP 提供很多现成的插件,你的 AI 可以直接使用。
  • 统一性 - 不限制于特定的 AI 模型,任何支持 MCP 的模型(或者说是工具,如windsuf、cursor)都可以灵活切换。
  • 数据安全 - 你的敏感数据留在自己的电脑上,不必全部上传。(因为我们可以自行设计接口确定传输哪些数据)

三、MCP的类型

MCP (Model Context Protocol) 是 Anthropic 推出的标准化 LLM 与外部工具通信协议,内置两种核心传输方式:
对比维度STDIO (标准输入 / 输出) 传输Streamable HTTP/SSE 传输
核心定位本地 "面对面" 通信,单进程直连远程 "电话热线" 通信,跨网络连接
连接方式进程间直接通过标准 I/O 流传递消息基于 HTTP 协议,支持 Server-Sent Events
适用场景本地模型与工具集成 (如 IDE 插件、桌面助手)、低延迟需求场景远程服务器访问、多客户端共享服务、云端部署场景
并发支持通常服务单个客户端支持多个客户端同时连接
网络开销无网络开销,延迟低至微秒级存在网络传输延迟,需处理网络波动
安全特性依赖本地系统权限隔离可通过 HTTPS 加密传输,支持细粒度访问控制
实现复杂度最简单,无需网络配置中等,需处理 HTTP 连接管理和状态保持

四、如何使用MCP

(一)Claude APP

对于用户来说,我们并不关心 MCP 是如何实现的,通常我们只考虑如何更简单的用上这一特性。具体的使用方式参考官方文档:For Claude Desktop Users。这里不再赘述,配置成功后可以在 Claude 中测试:Can you write a poem and save it to my desktop? Claude 会请求你的权限后在本地新建一个文件。并且官方也提供了非常多现成的 MCP Servers,你只需要选择你希望接入的工具,然后接入即可。
比如官方介绍的 filesystem 工具,它允许 Claude 读取和写入文件,就像在本地文件系统中一样。

(二)Cursor

鉴于cursor需要收费,如果有账号或采用破解版工具的,软件配置可参考博文(MCP Server 开发实战指南(Python版) - Ryan_zheng - 博客园)自行配置,此处不再赘述。

(三)VSCode+Cline

详细的配置与使用请参考博文(使用MCP连接通义千问与ComfyUI实现文生图并自动发布小红书-开发者社区-阿里云

(四)PyCharm

在 PyCharm 中部署 MCP(Model Context Protocol)服务可分为两个核心场景:使用 PyCharm 内置 MCP 服务器(连接 IDE 功能)和开发自定义 MCP 服务(实现 AI 模型上下文交互)。以下是详细分步操作,确保你能快速完成部署并验证可用性。

(1)安装uv包

此步骤需要科学上网
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

(2)创建项目目录

uv init mcp-server cd mcp-server

(3)创建并激活虚拟环境

uv venv source .venv/bin/activate # Windows环境中使用以下命令: .venv\Scripts\activate

(4)安装依赖

uv add "mcp[cli]" httpx

(5)创建服务器实现文件

touch main.py # windows下使用:ni main.py

(6)构建工具函数(Stdio)

为了让大模型能访问市面上主流框架的技术文档,我们主要通过用户输入的 query,结合指定 site 特定域名的谷歌搜索进行搜索相关网页,并对相关网页进行解析提取网页文本并返回。mcp server封装如下(Stdio):
# main.py from mcp.server.fastmcp import FastMCP from dotenv import load_dotenv import httpx import json import os from bs4 import BeautifulSoup from typing import Any import httpx from mcp.server.fastmcp import FastMCP from starlette.applications import Starlette from mcp.server.sse import SseServerTransport from starlette.requests import Request from starlette.routing import Mount, Route from mcp.server import Server import uvicorn load_dotenv() mcp = FastMCP("Agentdocs") USER_AGENT = "Agentdocs-app/1.0" SERPER_URL = "https://google.serper.dev/search" docs_urls = { "langchain": "python.langchain.com/docs", "llama-index": "docs.llamaindex.ai/en/stable", "autogen": "microsoft.github.io/autogen/stable", "agno": "docs.agno.com", "openai-agents-sdk": "openai.github.io/openai-agents-python", "mcp-doc": "modelcontextprotocol.io", "camel-ai": "docs.camel-ai.org", "crew-ai": "docs.crewai.com" } async def search_web(query: str) -> dict | None: payload = json.dumps({"q": query, "num": 2}) headers = { "X-API-KEY": os.getenv("SERPER_API_KEY"), "Content-Type": "application/json", } async with httpx.AsyncClient() as client: try: response = await client.post( SERPER_URL, headers=headers, data=payload, timeout=30.0 ) response.raise_for_status() return response.json() except httpx.TimeoutException: return {"organic": []} async def fetch_url(url: str): async with httpx.AsyncClient() as client: try: response = await client.get(url, timeout=30.0) soup = BeautifulSoup(response.text, "html.parser") text = soup.get_text() return text except httpx.TimeoutException: return "Timeout error" @mcp.tool() async def get_docs(query: str, library: str): """ 搜索给定查询和库的最新文档。 支持 langchain、llama-index、autogen、agno、openai-agents-sdk、mcp-doc、camel-ai 和 crew-ai。 参数: query: 要搜索的查询 (例如 "React Agent") library: 要搜索的库 (例如 "agno") 返回: 文档中的文本 """ if library not in docs_urls: raise ValueError(f"Library {library} not supported by this tool") query = f"site:{docs_urls[library]} {query}" results = await search_web(query) if len(results["organic"]) == 0: return "No results found" for result in results["organic"]: text += await fetch_url(result["link"]) return text if __name__ == "__main__": mcp.run(transport="stdio") 

启动该脚本的命令如下:

uv run main.py

 (--)构建工具函数(SSE)

from mcp.server.fastmcp import FastMCP from dotenv import load_dotenv import httpx import json import os from bs4 import BeautifulSoup from typing import Any import httpx from mcp.server.fastmcp import FastMCP from starlette.applications import Starlette from mcp.server.sse import SseServerTransport from starlette.requests import Request from starlette.routing import Mount, Route from mcp.server import Server import uvicorn load_dotenv() mcp = FastMCP("docs") USER_AGENT = "docs-app/1.0" SERPER_URL = "https://google.serper.dev/search" docs_urls = { "langchain": "python.langchain.com/docs", "llama-index": "docs.llamaindex.ai/en/stable", "autogen": "microsoft.github.io/autogen/stable", "agno": "docs.agno.com", "openai-agents-sdk": "openai.github.io/openai-agents-python", "mcp-doc": "modelcontextprotocol.io", "camel-ai": "docs.camel-ai.org", "crew-ai": "docs.crewai.com" } async def search_web(query: str) -> dict | None: payload = json.dumps({"q": query, "num": 2}) headers = { "X-API-KEY": os.getenv("SERPER_API_KEY"), "Content-Type": "application/json", } async with httpx.AsyncClient() as client: try: response = await client.post( SERPER_URL, headers=headers, data=payload, timeout=30.0 ) response.raise_for_status() return response.json() except httpx.TimeoutException: return {"organic": []} async def fetch_url(url: str): async with httpx.AsyncClient() as client: try: response = await client.get(url, timeout=30.0) soup = BeautifulSoup(response.text, "html.parser") text = soup.get_text() return text except httpx.TimeoutException: return "Timeout error" @mcp.tool() async def get_docs(query: str, library: str): """ 搜索给定查询和库的最新文档。 支持 langchain、llama-index、autogen、agno、openai-agents-sdk、mcp-doc、camel-ai 和 crew-ai。 参数: query: 要搜索的查询 (例如 "React Agent") library: 要搜索的库 (例如 "agno") 返回: 文档中的文本 """ if library not in docs_urls: raise ValueError(f"Library {library} not supported by this tool") query = f"site:{docs_urls[library]} {query}" results = await search_web(query) if len(results["organic"]) == 0: return "No results found" for result in results["organic"]: text += await fetch_url(result["link"]) return text ## sse传输 def create_starlette_app(mcp_server: Server, *, debug: bool = False) -> Starlette: """Create a Starlette application that can serve the provided mcp server with SSE.""" sse = SseServerTransport("/messages/") async def handle_sse(request: Request) -> None: async with sse.connect_sse( request.scope, request.receive, request._send, # noqa: SLF001 ) as (read_stream, write_stream): await mcp_server.run( read_stream, write_stream, mcp_server.create_initialization_options(), ) return Starlette( debug=debug, routes=[ Route("/sse", endpoint=handle_sse), Mount("/messages/", app=sse.handle_post_message), ], ) if __name__ == "__main__": mcp_server = mcp._mcp_server import argparse parser = argparse.ArgumentParser(description='Run MCP SSE-based server') parser.add_argument('--host', default='0.0.0.0', help='Host to bind to') parser.add_argument('--port', type=int, default=8020, help='Port to listen on') args = parser.parse_args() # Bind SSE request handling to MCP server starlette_app = create_starlette_app(mcp_server, debug=True) uvicorn.run(starlette_app, host=args.host, port=args.port) 
启动命令:
uv run main.py --host 0.0.0.0 --port 8020 
以上 MCP server 代码直接在你的云服务器跑即可。

(7)客户端配置

①Cline插件
设置-插件-marketplace-搜索Cline工具并安装-重启pycharm-右侧工具栏点击Cline-添加mcp server
点击configure-点击Configure MCP Servers-按如下代码进行配置即可。
{ "mcpServers": { "mcp-server": { "command": "uv", "args": [ "--directory", "<你的mcp服务的路径>", "run", "main.py" ] } } } 
配置成功后会在Mcp-Servers的服务列表中有显示(成功后有个小绿点),并可以选择此mcp服务是否启用
②Lingma插件(阿里)
由于cline是收费的,成本较高。大家也可以用Lingma(阿里大模型编程工具插件)进行配置,配置过程如下:

设置-插件-marketplace-搜索Lingma工具并安装-重启pycharm-右侧工具栏点击Lingma-插件设置-会话设置(可以自行选择每次询问或者自动执行)
Lingma-个人设置-左键进入MCP服务-添加MCP服务(可以选择手动添加或者配置文件添加,此处以手动添加为例)-
输入相关MCP配置参数-我的服务-查看是否连接成功(成功后会有一个绿色的链接符号+一个绿色的)

(五)OpenCode

自建MCP服务或者调用远程的MCP都可以。配置过程如下:
  1. 找到opencode配置文件(一般在c盘~.\.config\opencode),如果没有的话可以手动新建,名称是opencode.json
  2. 在配置文件中编写对应的mcp服务内容(有自己的固定格式(本地 or 远程),如下)
  3. 如果想继续添加其他的mcp服务,可以在“mcp”键对应的值中进一步添加。例如:我在自建mcp的基础上,添加了一个名为fetch的网页抓取mcp服务,效果如下图
## 本地mcp部署: { "$schema": "https://opencode.ac.cn/config.json", "mcp": { "my-local-mcp-server": { "type": "local", // Or ["bun", "x", "my-mcp-command"] "command": ["npx", "-y", "my-mcp-command"], "enabled": true, "environment": { "MY_ENV_VAR": "my_env_var_value", }, }, }, } ## 相关参数解释 选项 类型 (Type) 必需 描述 type 字符串 Y MCP 服务器连接的类型,必须是 "local"。 command 数组 Y 运行 MCP 服务器的命令和参数。 environment 对象 运行服务器时要设置的环境变量。 enabled 布尔值 在启动时启用或禁用 MCP 服务器。 timeout 数字 从 MCP 服务器获取工具的超时时间(以毫秒为单位)。默认为 5000(5 秒)。 ------------------------------------------------------------------ ## 远程MCP部署: { "$schema": "https://opencode.ac.cn/config.json", "mcp": { "my-remote-mcp": { "type": "remote", "url": "https://my-mcp-server.com", "enabled": true, "headers": { "Authorization": "Bearer MY_API_KEY" } } } } ## 相关参数解释 选项 类型 (Type) 必需 描述 type 字符串 Y MCP服务器连接的类型,必须是 "remote"。 url 字符串 Y 远程 MCP 服务器的 URL。 enabled 布尔值 在启动时启用或禁用 MCP 服务器。 headers 对象 发送请求时附带的标头。 oauth 对象 OAuth 身份验证配置。请参阅下面的 OAuth 部分。 timeout 数字 从 MCP 服务器获取工具的超时时间(以毫秒为单位)。默认为 5000
以我本地创建的mcp-server为例,其配置参数如下,启动opencode后若mcp配置成功则会在左下角有一个状态显示,直接输入/mcps也可以进行mcp的启停(空格键可手动启动选定的mcp服务):

五、具体使用

以Langma插件为例,通过插件的对话功能,便能够通过 MCP 获取相关文档信息进行回答。例如,提问问题:

“帮我实现openai-agents-sdk构建agent的代码”

六、后续问题

等遇到其他问题再进一步补充吧,例如:1、把 fastapi接口发布成 mcp工具(https://github.com/tadata-org/fastapi_mcp/blob/main/README_zh-CN.md)等

Read more

Hystrix - 微服务韧性演进史:从 Hystrix 到 Service Mesh

Hystrix - 微服务韧性演进史:从 Hystrix 到 Service Mesh

👋 大家好,欢迎来到我的技术博客! 💻 作为一名热爱 Java 与软件开发的程序员,我始终相信:清晰的逻辑 + 持续的积累 = 稳健的成长。 📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。 🎯 本文将围绕Hystrix这个话题展开,希望能为你带来一些启发或实用的参考。 🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获! 文章目录 * Hystrix - 微服务韧性演进史:从 Hystrix 到 Service Mesh 🚀 * 🧠 一、什么是微服务韧性?为何如此重要? * 📌 为什么需要韧性? * 🧱 微服务架构下的挑战 * 🏗️ 二、Hystrix 的诞生:从 Netflix 开始的熔断之旅 * 📦 Hystrix 的历史背景 * 🛠️ Hystrix 的核心机制 * 1. **熔断器模式 (Circuit Breaker)** * 2. **隔离 (Isolation)** * 3.

By Ne0inhk
Python在AI虚拟教学视频开发中的核心技术与前景展望

Python在AI虚拟教学视频开发中的核心技术与前景展望

Python在AI虚拟教学视频开发中的核心技术与前景展望 一、引言:AI虚拟教学的技术革新 随着教育数字化转型加速,AI虚拟教学视频凭借个性化、沉浸式体验成为教育科技的新风口。Python以其强大的多模态处理能力、丰富的开源生态和跨领域兼容性,成为构建智能教学视频系统的首选技术栈。本文结合前沿研究与实战经验,解析Python在AI虚拟教学视频开发中的核心技术框架与典型应用场景。 二、核心技术框架与关键工具库 (一)计算机视觉:构建交互感知系统 Mediapipe:高精度姿态检测 Google开源的Mediapipe提供跨平台的人脸/手势/身体关键点检测,支持实时追踪教师演示动作并映射到虚拟人,提升交互真实感。 import mediapipe as mp mp_drawing = mp.solutions.drawing_utils mp_face_mesh = mp.solutions.face_mesh with mp_face_mesh.FaceMesh(max_num_faces=1)

By Ne0inhk

uv vs conda 终极对决:谁才是 Python 环境管理的王者?

📌 摘要 还在为 Python 项目该用 conda 还是 uv 而纠结吗?本文带你深入剖析两大热门工具的核心差异、性能对比、适用场景。conda 是数据科学的“老将”,自带 Python 发行版,支持跨语言包管理;而 uv 是由 Ruff 团队打造的“新锐战神”,用 Rust 编写,速度比 pip 快 10-100 倍!我们将从虚拟环境管理、包安装速度、项目初始化、工具链整合等维度全面对比,帮你选出最适合你项目的那一个。无论你是 AI 工程师还是 Web 开发者,这篇都能让你豁然开朗! 🚀 一句话总结:本质不同 conda 是一个“全能型选手”,自带 Python

By Ne0inhk
Python IDLE 使用教程 一文让你掌握Python3.8 自带的集成开发环境的使用

Python IDLE 使用教程 一文让你掌握Python3.8 自带的集成开发环境的使用

说明:本教程聚焦IDLE(Python自带的集成开发环境)的常用功能,帮助你快速上手。 本文中使用的截图软件为Snipaste(免费好用) 详细使用步骤可以移步我的另一篇博客 Snipaste安装使用教程 📑 目录 * 一、启动IDLE * 二、Shell交互模式 * 三、编辑器使用 * 四、调试功能 * 五、实用技巧 * 六、常见问题 一、启动IDLE 1.1 三种启动方式 方式一:开始菜单(Windows) 1. 点击"开始"菜单 2. 找到 Python 3.x 文件夹 3. 点击 IDLE (Python 3.x) ######方式二:搜索启动

By Ne0inhk