资讯动态

MCP 初探,为大模型装上“手“和“眼“

发布时间:2026/9/28 11:48:53 来源:尧图企业网站定制
第一部分什么是 MCP1.1 MCP 的定义MCPModel Context Protocol模型上下文协议是由 Anthropic 公司发起并开源的一套开放标准协议。它的核心目标是为大语言模型LLM与外部工具、数据源之间建立一套统一的通信规范使不同厂商的 AI 应用能够以一致的方式接入各类外部能力。可以将 MCP 类比为智能设备领域的 USB-C 接口无论设备厂商是谁只要遵循统一的接口标准就能实现互联互通。MCP 在 AI 生态中扮演的正是这样一个统一接口的角色——开发者只需开发一次 MCP Server便可被多种 AI 工具和平台调用。1.2 MCP 能做什么MCP 通过三种核心能力扩展大模型的边界工具Tools大模型可以主动调用的函数例如查询天气、执行计算、发送邮件等。工具是 MCP 最常被使用的能力它赋予了大模型动手操作的能力。资源Resources大模型可以读取的数据源例如本地文件、数据库记录、API 返回的数据等。资源相当于大模型的眼睛使其能够感知外部世界的信息。提示模板Prompts预定义的提示词模板用于标准化某些固定的交互场景。1.3 MCP 的优势作为一项开放标准MCP 具有以下显著优势一次开发到处运行遵循 MCP 协议开发的服务可以被所有支持该协议的 AI 平台使用包括 Claude、ChatGPT、Gemini、豆包、Grok、Mistral 等主流产品以及 Cursor、Trae 等 AI IDE。语言无关MCP 定义的是通信协议而非实现语言开发者可以使用 Python、Java、Node.js、Go 等任意语言来实现服务端。传输方式灵活支持 stdio标准输入输出、SSEServer-Sent Events、Streamable HTTP 等多种传输方式可根据部署场景灵活选择。由大模型自主决策与传统 API 由人工编排调用不同MCP 环境下的大模型会根据当前任务自主判断何时调用哪个工具实现真正的闭环推理。1.4 MCP 与传统 Web 服务的区别MCP Server 虽然在形态上与 Web 服务有相似之处都是对外提供能力的程序但二者存在本质差异对比维度传统 Web 服务RESTful APIMCP Server通信协议HTTP REST 动词JSON-RPC调用者人或前端应用大语言模型编排方式人工显式调用大模型自主决策调用时机能力发现需查阅接口文档服务启动时自动告知客户端简言之Web 服务是为人设计的接口而 MCP 是为大模型设计的接口。第二部分MCP 的工作机制与关键概念澄清2.1 MCP 的基本架构一个完整的 MCP 工作链路包含三个角色AI 客户端Client如 Claude Desktop、Cursor、Perplexity 等负责与用户交互并驱动大模型推理。MCP Server由开发者实现的外部能力提供者运行在本地或远程服务器上。大语言模型推理的核心根据用户需求决定是否调用工具。工作流程如下用户向 AI 客户端提出需求 → 大模型判断需要外部能力 → 通过 JSON-RPC 协议向 MCP Server 发起调用 → MCP Server 执行逻辑并返回结果 → 结果直接注入大模型的上下文窗口 → 大模型基于结果继续推理并回复用户。2.2 传输协议与数据格式MCP 采用JSON-RPC作为通信协议数据以 JSON 格式在客户端与服务端之间传递。传输层支持多种方式stdio通过标准输入输出进行通信适用于本地运行的场景。这是最常见、最简单的方式。SSE / Streamable HTTP基于 HTTP 的流式传输适用于将 MCP Server 部署到远程云服务器的场景。2.3 关于本地服务能否被远程网站访问的澄清需要特别说明的是运行在本地电脑上的 MCP Server无法被远程 AI 网站直接访问。例如网页版 ChatGPT 或网页版 Claude 的服务器运行在云端它们无法穿透用户的家庭或企业网络访问到本地电脑上的localhost服务。能够直接调用本地 MCP Server 的是运行在同一台电脑上的本地 AI 客户端例如 Claude Desktop、Cursor、Trae IDE 等。这些客户端通过 stdio 或本地 HTTP 与 MCP Server 通信。若希望远程 AI 平台也能使用某个 MCP 服务需要将该服务部署到云服务器上使用 Streamable HTTP 传输或通过 ngrok、frp 等内网穿透工具将本地端口临时暴露到公网。2.4 关于工具返回结果的传递方式的澄清MCP 工具的返回结果会直接以文本形式注入大模型的上下文窗口不需要先将结果落盘为一个中间文件再传递。完整的数据链路为MCP Server 执行工具逻辑读取文件、处理数据、汇总信息→ 返回文本字符串可以是 Markdown 或纯文本→ 文本直接进入大模型的上下文 → 大模型据此推理并回复用户。全程无需中间文件。2.5 MCP 的能力范围MCP 不仅仅是文件处理工具。虽然文件读取与处理是 MCP 最典型的应用场景之一但 MCP 的能力范围远不止于此。任何能够通过程序实现的功能理论上都可以封装为 MCP 工具例如调用第三方 API、操作数据库、执行代码、控制硬件设备等。MCP 本质上是一个通用的能力扩展框架。2.6 MCP 与AI 的交互流程第三部分实践开发——一个本地文档访问 MCP Server3.1 需求与设计我们要开发一个运行在本地 Windows 系统上的 MCP Server使其能够访问指定目录E:\MCP Test下的文档并为大模型提供以下四项能力递归列出目录下的所有文件支持按文件名模式过滤。读取指定文件的文本内容支持按行数截断。在所有文本文件中按关键词搜索内容。生成目录的汇总统计报告文件数量、类型分布、总大小、子目录结构。3.2 技术选型使用 Python 语言和官方mcpSDK 进行开发。在mcp2.x 版本中高层封装类由FastMCP更名为MCPServer使用装饰器即可快速注册工具代码简洁直观。3.3 核心代码结构importosimportfnmatchfromdatetimeimportdatetimefrompathlibimportPathfromtypingimportOptionalfrommcp.server.mcpserverimportMCPServer TARGET_DIRrE:\MCP TestmcpMCPServer(LocalDocServer)完整样例代码importosimportfnmatchfromdatetimeimportdatetimefrompathlibimportPathfromtypingimportOptionalfrommcp.server.mcpserverimportMCPServer TARGET_DIRrE:\MCP TestmcpMCPServer(LocalDocServer)TEXT_EXTENSIONS{.txt,.md,.json,.csv,.xml,.yaml,.yml,.py,.js,.ts,.html,.css,.sql,.log,.ini,.cfg,.toml,.rst,.tex,.sh,.bat,.ps1,.java,.c,.cpp,.h,.hpp,.cs,.go,.rs,.rb,.php,.swift,.kt,.scala,.r,.m,.vbs,.psm1,.psd1,}def_is_text_file(filepath:str)-bool:extPath(filepath).suffix.lower()returnextinTEXT_EXTENSIONSdef_format_size(size_bytes:int)-str:forunitin(B,KB,MB,GB):ifsize_bytes1024:returnf{size_bytes:.1f}{unit}size_bytes/1024returnf{size_bytes:.1f}TBdef_format_time(timestamp:float)-str:returndatetime.fromtimestamp(timestamp).strftime(%Y-%m-%d %H:%M:%S)def_ensure_target_dir()-str:ifnotos.path.isdir(TARGET_DIR):returnf错误: 目录 {TARGET_DIR} 不存在。请确认路径是否正确。returnmcp.tool()deflist_all_files(pattern:Optional[str]None)-str:列出 E:\\MCP Test 目录下的所有文件递归扫描。 参数 pattern: 可选的文件名匹配模式如 *.txt 或 report*。不传则列出全部文件。 error_ensure_target_dir()iferror:returnerror files[]forroot,dirs,filenamesinos.walk(TARGET_DIR):forfilenameinfilenames:ifpatternandnotfnmatch.fnmatch(filename,pattern):continuefilepathos.path.join(root,filename)statos.stat(filepath)rel_pathos.path.relpath(filepath,TARGET_DIR)files.append({path:rel_path,size:stat.st_size,size_display:_format_size(stat.st_size),modified:_format_time(stat.st_mtime),is_text:_is_text_file(filepath),})ifnotfiles:returnf在 {TARGET_DIR} 中没有找到匹配 {patternor*} 的文件。files.sort(keylambdaf:f[path])lines[fE:\\MCP Test 目录下的文件列表共{len(files)}个文件:]lines.append(*80)fori,finenumerate(files,1):type_tag[文本]iff[is_text]else[二进制]lines.append(f{i:4d}.{type_tag}{f[path]}f({f[size_display]}, 修改于{f[modified]}))return\n.join(lines)mcp.tool()defread_file_content(relative_path:str,max_lines:Optional[int]None)-str:读取 E:\\MCP Test 目录下指定文件的内容。 参数 relative_path: 文件相对于 E:\\MCP Test 的路径如 subdir/report.txt 参数 max_lines: 可选最多读取的行数。不传则读取全部内容。 error_ensure_target_dir()iferror:returnerror full_pathos.path.normpath(os.path.join(TARGET_DIR,relative_path))ifnotfull_path.startswith(os.path.normpath(TARGET_DIR)):returnf安全限制: 不允许访问 {TARGET_DIR} 目录之外的文件。ifnotos.path.isfile(full_path):returnf错误: 文件 {relative_path} 不存在。ifnot_is_text_file(full_path):size_format_size(os.path.getsize(full_path))returnf{relative_path} 是二进制文件 ({size})无法直接读取其文本内容。try:withopen(full_path,r,encodingutf-8)asf:ifmax_linesisnotNoneandmax_lines0:lines[]fori,lineinenumerate(f):ifimax_lines:breaklines.append(line.rstrip(\n))content\n.join(lines)suffixf\n\n... (已截断仅显示前{max_lines}行共{i1}行已读取)returnf文件:{relative_path}\n{*80}\n{content}{suffix}else:contentf.read()line_countcontent.count(\n)1returnf文件:{relative_path}共{line_count}行\n{*80}\n{content}exceptUnicodeDecodeError:returnf错误: {relative_path} 无法以 UTF-8 编码读取可能是二进制文件或使用了其他编码。mcp.tool()defsearch_by_keyword(keyword:str,file_pattern:Optional[str]None)-str:在所有文本文件中搜索包含指定关键词的内容返回匹配行及上下文。 参数 keyword: 要搜索的关键词不区分大小写 参数 file_pattern: 可选的文件名匹配模式如 *.md 只搜索 Markdown 文件。 error_ensure_target_dir()iferror:returnerror results[]keyword_lowerkeyword.lower()forroot,dirs,filenamesinos.walk(TARGET_DIR):forfilenameinfilenames:iffile_patternandnotfnmatch.fnmatch(filename,file_pattern):continuefilepathos.path.join(root,filename)ifnot_is_text_file(filepath):continuetry:withopen(filepath,r,encodingutf-8)asf:forline_no,lineinenumerate(f,1):ifkeyword_lowerinline.lower():rel_pathos.path.relpath(filepath,TARGET_DIR)results.append({file:rel_path,line:line_no,content:line.strip(),})except(UnicodeDecodeError,PermissionError,OSError):continueifnotresults:returnf在 {TARGET_DIR} 中没有找到包含关键词 {keyword} 的文本文件。lines[f搜索关键词 {keyword} 的结果共{len(results)}处匹配:]lines.append(*80)current_fileforrinresults:ifr[file]!current_file:current_filer[file]lines.append(f\n---{current_file}---)lines.append(f 行{r[line]:5d}:{r[content]})return\n.join(lines)mcp.tool()defget_directory_summary()-str:获取 E:\\MCP Test 目录的汇总信息包括文件总数、总大小、文件类型分布、子目录结构等。error_ensure_target_dir()iferror:returnerror total_files0total_size0text_count0binary_count0ext_counter{}dirs_list[]forroot,dirs,filenamesinos.walk(TARGET_DIR):rel_diros.path.relpath(root,TARGET_DIR)ifrel_dir.:rel_dirdirs_list.append(rel_dir)forfilenameinfilenames:filepathos.path.join(root,filename)try:statos.stat(filepath)total_files1total_sizestat.st_size extPath(filename).suffix.lower()or(无扩展名)ext_counter[ext]ext_counter.get(ext,0)1if_is_text_file(filepath):text_count1else:binary_count1exceptOSError:continueiftotal_files0:returnf目录 {TARGET_DIR} 存在但没有文件。sorted_extssorted(ext_counter.items(),keylambdax:x[1],reverseTrue)lines[E:\\MCP Test 目录汇总报告,*80,f总文件数:{total_files},f - 文本文件:{text_count},f - 二进制文件:{binary_count},f总大小:{_format_size(total_size)},f子目录数:{len([dfordindirs_listifd])},,文件类型分布 (Top 15):,-*40,]forext,countinsorted_exts[:15]:pct(count/total_files)*100lines.append(f{ext:20s}{count:5d}个 ({pct:5.1f}%))iflen(sorted_exts)15:lines.append(f ... 及其他{len(sorted_exts)-15}种类型)lines.append()lines.append(子目录结构:)lines.append(-*40)fordinsorted(dirs_list):indent *d.count(os.sep)ifdelse (根目录)lines.append(f{indent}{os.path.basename(d)ifdelseE:\\MCP Test\\})return\n.join(lines)if__name____main__:print(fMCP Server 启动中... 目标目录:{TARGET_DIR})ifnotos.path.isdir(TARGET_DIR):print(f警告: 目录 {TARGET_DIR} 不存在请确认路径是否正确。)print(Server 仍会启动但所有工具调用将返回错误提示。)mcp.run()通过mcp.tool()装饰器即可将普通函数注册为 MCP 工具函数的文档字符串会自动作为工具的描述提供给大模型函数的参数类型注解会被自动解析为工具的输入参数 Schema。3.4 安全设计出于安全考虑实现中加入了路径越界保护所有文件读取操作都被限制在TARGET_DIR目录之内任何尝试通过../等方式访问目录外文件的请求都会被拒绝。此外二进制文件如 PDF、图片会被识别并返回提示而不会强行以文本方式读取。3.5 运行方式在项目目录下执行以下命令即可启动 Server.\.venv\Scripts\Activate.ps1 python mcp_server.pyServer 启动后将通过 stdio 协议等待 AI 客户端连接。第四部分在 AI 客户端中配置与使用 MCP 服务4.1 以 Perplexity 为例的配置流程在 Perplexity 中添加本地 MCP 服务时会出现一个名为添加 MCP 服务器的配置界面如1.png所示。该界面提供本地stdio和远程HTTP两种连接模式本地服务选择本地stdio即可。界面中包含以下字段名称为该 MCP 服务起一个标识名例如my-server。命令指向可执行文件的绝对路径。对于 Python 实现的 MCP Server此处应填写 Python 解释器的绝对路径例如C:\Users\darkdragonking\PycharmProjects\PythonProject\.venv\Scripts\python.exe参数传递给命令的参数每行一个。此处应填写 MCP Server 脚本的路径C:\Users\darkdragonking\PycharmProjects\PythonProject\mcp_server.py工作目录可选Server 运行时的工作目录可留空。环境变量可选Server 所需的环境变量可留空。如2.png所示界面还提示本地服务器在沙盒之外运行它们以您的用户权限运行可以访问您的文件和网络因此应只添加信任的 MCP 服务。实际上只需填写名称、“命令”、参数三项即可其余字段保持默认或留空即可正常工作。4.2 完整使用步骤在终端中启动本地 MCP Server执行python mcp_server.py。在 Perplexity 的 MCP 配置界面中填写名称、命令、参数点击添加。配置成功后即可在对话中让大模型调用该服务提供的工具例如询问列出 E 盘 MCP Test 目录下的所有文件大模型会自动调用list_all_files工具并返回结果。4.3 其他客户端的配置Claude Desktop 的配置方式是编辑%APPDATA%\Claude\claude_desktop_config.json文件在其中添加mcpServers配置项结构如下{mcpServers:{local-doc-server:{command:C:\\Users\\darkdragonking\\PycharmProjects\\PythonProject\\.venv\\Scripts\\python.exe,args:[C:\\Users\\darkdragonking\\PycharmProjects\\PythonProject\\mcp_server.py]}}}其中command对应 Perplexity 中的命令字段args对应参数字段配置语义完全一致。Cursor、Trae 等其他支持 MCP 的客户端也遵循类似的配置方式。第五部分总结MCP 协议通过标准化的 JSON-RPC 通信机制为大模型与外部能力之间搭建了一座通用桥梁。开发者只需遵循协议规范开发一次 MCP Server即可让多种 AI 客户端共享同一套外部能力极大地降低了 AI 应用与工具集成的成本。对于希望扩展 AI 能力边界的开发者而言掌握 MCP 协议的开发与配置是进入 AI 工具生态的一把关键钥匙。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑