
如果你每天要花一两个小时在Excel上做重复劳动——合并表格、清洗脏数据、格式转换、按条件挑最大值——这篇文章大概率能帮你省下这笔时间。我最近折腾完自己的第一个MCP服务端把所有高频Excel操作封装成了AI可以直接调用的工具实测下来同样一批活从“打开Excel手动点”变成了“用一句话下达需求”。这里说的MCP全称叫Model Context Protocol是一套让AI模型和外部工具之间“握手”的应用层通信协议。你可以把它理解成给AI装配外部设备的标准接口AI是大脑MCP服务端是手和脚Excel处理能力就是这样被“重构”进AI工作流里的。这篇文章适合两类人一是被Excel重复操作折磨、想提效的办公族二是想搞懂MCP到底是什么、怎么写第一个MCP Server的开发者。前者可以直接抄作业后者能看到完整的设计和排坑过程。1. 为什么是MCPExcel自动化的老路与新变局1.1 Excel自动化的“经典三件套”及其天花板在MCP出现之前我们让Excel“自动化”的办法基本就是三条路。第一条是VBA宏录制宏或者手写VBA在Excel内部跑。它的毛病我想不用多说了版本升级可能禁用宏、安全软件动不动拦一下、代码只能在自己机器上跑同事拿去还要调环境。更尴尬的是每次业务逻辑变一点你得打开VBA编辑器去改代码本质上还是在“编程”只是换了个语言。第二条路是Python脚本用pandas、openpyxl写批量处理。这条路的灵活性确实高能跨文件、跨目录、做复杂清洗和聚合但问题是“代码是代码人是人”。一个非程序员同事的需求传到你这里你读懂需求、改参数、跑脚本、导出结果链路很长。而且哪怕AI已经能帮你生成这段Python代码你还是得亲手复制到终端里去执行——AI停在“给建议”这一步没跨过“帮你干活”这一步。第三条路是Excel自带的Power Query、加载项以及各种“Excel增强插件”。它们解决的问题很具体比如分组汇总、合并查询但学习曲线不平缓跨文件批量场景弱而且你没法用自然语言去指挥它。这三条路的共同天花板是人必须参与“执行”环节要么人写代码要么人点按钮。AI再聪明也只能给你一段代码或者一段操作说明。所以大多数人嘴上说“AI帮我做Excel”实际还是“AI教我怎么做Excel”。1.2 MCP到底解决了什么把“工具供给”标准化MCP的核心贡献是定义了一个标准协议让AI模型能够阅读“工具说明书”并自主决定调用哪个工具、传什么参数。它有三个角色MCP客户端也叫宿主是你装的那款支持MCP的AI桌面应用、MCP服务端Server提供一堆工具函数、以及大模型负责理解需求并调用工具。我用USB接口来类比你的电脑AI客户端有USB口鼠标、键盘、U盘各种MCP Server只要符合USB标准就能插上即用。以前每类外设都要自己的专用接口现在全世界统一了。MCP就是AI世界的USB标准。所以你不需要给AI单独定制一个“读Excel的私有接口”和“写Excel的私有接口”大家都按MCP协议来做一次工具开发所有支持MCP的客户端都能用。这里顺便回应一个很多人问过的问题MCP到底是软件协议还是硬件协议它是纯软件层面的应用层协议跟串口、USB、蓝牙这些硬件协议完全不是一个概念。MCP不在物理层也不关心数据怎么在网上跑它只约定“工具怎么描述自己”“请求和结果用什么格式封包”。1.3 用MCP重构Excel工作流的整体思路拿我做的这个Excel MCP Server举例。整体流程是本地Excel文件 → MCP Server里的工具函数读取并解析 → 客户端把工具能力交给大模型 → 大模型根据你的自然语言需求决定调用read_excel还是clean_excel还是merge_excel_files → 结果直接写回文件或返回给你。这个过程最大的变化是AI从“提建议的人”变成了“实际执行的人”。你说“把这个表去重按销售额排序生成一个新文件”AI自己去调用工具自己解读工具的返回结果出错了还能根据报错信息换个参数再来一次。因为所有数据都在本地处理不必须上传到云端敏感信息的存在感也低了很多。这不是“给Excel装一个AI插件”而是“给AI装一个Excel能力工具箱”。2. 动手前的设计选型、工具清单与边界2.1 技术选型官方Python SDK pandas openpyxl第一个问题是要不要自己实现MCP协议我的回答是千万别。MCP底层是JSON-RPC的一整套封装包括初始化握手、能力协商、工具列表广播、参数校验、结果返回、错误处理自己从头写大概率会踩进“边角料协议”的坑里。用官方Python SDK就好里面有一个FastMCP类装饰器一加普通Python函数直接变成MCP工具。处理Excel的选择其实没什么悬念pandas负责数据结构和复杂加工openpyxl负责xlsx的底层读写tabulate负责把表格转成Markdown给AI阅读。整套依赖就这几个。Python版本建议3.10以上因为后面代码里我会用str | None这种类型写法低版本跑不动。我也建议用虚拟环境隔离别把依赖直接装进系统Python后面换项目你会感谢这个决定。2.2 设计工具清单颗粒度决定AI的聪明程度动写代码之前我先把要暴露给AI的工具清单列出来。这一步很关键因为它决定了后面的服务端逻辑长什么样。工具名输入输出典型场景list_sheetsfile_path所有工作表名称列表AI先摸清文件结构read_excelfile_path, sheet, max_rowsMarkdown格式表格行列统计让AI看数据长什么样write_excelfile_path, sheet_name, rows写入行数把AI算好的结果落盘clean_excelfile_path, sheet, drop_duplicates, drop_na清洗前后行数对比去重、去空值merge_excel_filesfile_paths, output_path, use_sheet合并结果说明批量合并多个文件excel_to_markdownfile_path, sheet, max_rowsMarkdown表格文本用于继续对话或复制粘贴设计时的核心经验是工具颗粒度不要太粗也不要太细。如果一个工具叫“process_excel”输入参数只有file_pathAI拿到之后根本不知道你想让它干什么这就是太粗。反之如果你把“设置单元格背景色”“调整行高”“合并单元格”全做成独立工具AI执行一个简单任务就要来回调用十几次token烧得飞快而且容易出错。我的选择是围绕“结构查看、数据读取、数据写入、数据清洗、文件合并”这几个高频动作来切正好覆盖了办公场景里八成以上的需求。还有一条很重要工具的描述docstring本身就是AI的“使用说明书”。描述写得不清楚AI就会猜错工具或者漏传参数。我记得有一次没在read_excel的说明里写“默认只返回前50行”AI读到完整数据后发现数据量太大反而误以为数据只有这么多后面统计结果全是错的。这件事后面在避坑章节还会细说。2.3 传输模式选型为什么第一版先走stdioMCP的传输方式主要有两种stdio和SSEHTTP。stdio模式下客户端直接以子进程方式启动你的Python脚本通过标准输入输出和它通信。SSE模式则是把服务端跑成一个HTTP接口客户端通过网络去调用。特性stdioSSE/HTTP适用场景本地单机客户端和脚本同机远程共享多客户端接入数据暴露不外网适合敏感Excel走网络需额外鉴权调试难度低日志直接打在终端中要处理网络和权限问题端口/进程无需端口占用需要固定端口服务我第一版的选择推荐进阶再上我自己第一版坚决走stdio。原因很直接本地Excel操作本来就是文件系统的事完全没有必要把文件内容传一遍网络。而且stdio调试太舒服了代码里面随便print终端直接能看到输出。如果你一开始就搞远程服务既要解决鉴权又要解决并发很容易把“第一个MCP”变成“第一个劝退项目”。3. 核心实现一个几十行代码的Excel MCP服务端3.1 初始化环境我用一个专门的目录来放这个项目避免和别的Python项目搅在一起。mkdir excel-mcp cd excel-mcp python -m venv .venv source .venv/bin/activate pip install mcp[cli] pandas openpyxl tabulate这里我故意装了mcp[cli]因为后面要用到它自带的调试器mcp dev。熟练以后你可以只装mcp减少无关依赖。3.2 完整服务端代码下面这段代码我让它保持在一个文件里方便你直接跑起来。功能包括列工作表、读取数据、写入数据、清洗、合并。# excel_mcp_server.py from pathlib import Path import pandas as pd from mcp.server.fastmcp import FastMCP mcp FastMCP(excel-assistant) mcp.tool() def list_sheets(file_path: str) - list[str]: 读取Excel文件返回所有工作表名称用于AI在操作前先确认文件结构。 Args: file_path: xlsx文件的绝对路径 excel_file pd.ExcelFile(file_path, engineopenpyxl) return excel_file.sheet_names mcp.tool() def read_excel(file_path: str, sheet: str | None None, max_rows: int 50) - str: 读取Excel文件并返回Markdown格式表格方便AI查看数据结构和样例。 Args: file_path: xlsx文件的绝对路径 sheet: 工作表名称不传时读取第一个工作表 max_rows: 最多返回多少行默认50行防止数据量过大撑爆上下文 if sheet is None: df pd.read_excel(file_path, engineopenpyxl) else: df pd.read_excel(file_path, sheet_namesheet, engineopenpyxl) sample df.head(max_rows) summary f工作表共 {len(df)} 行{len(df.columns)} 列以下展示前 {len(sample)} 行 return summary \n sample.to_markdown(indexFalse) mcp.tool() def write_excel(file_path: str, sheet_name: str, rows: list[dict]) - str: 把一组字典数据写入Excel文件的指定工作表。文件不存在则新建表已存在则覆盖。 Args: file_path: 目标xlsx文件的绝对路径 sheet_name: 要写入的工作表名称 rows: 每行一条字典例如[{姓名: 张三, 分数: 90}] df pd.DataFrame(rows) if Path(file_path).exists(): with pd.ExcelWriter( file_path, engineopenpyxl, modea, if_sheet_existsreplace ) as writer: df.to_excel(writer, sheet_namesheet_name, indexFalse) else: df.to_excel(file_path, sheet_namesheet_name, indexFalse) return f已写入 {len(df)} 行到 {file_path} 的 {sheet_name} 工作表 mcp.tool() def clean_excel( file_path: str, sheet: str | None None, drop_duplicates: bool True, drop_na: bool False, ) - str: 清洗Excel工作表数据可去重、可去空行清洗结果覆盖写回原工作表。 Args: file_path: xlsx文件的绝对路径 sheet: 工作表名称不传时取第一个工作表 drop_duplicates: 是否去除完全重复的行 drop_na: 是否丢弃包含空值的行 xls pd.ExcelFile(file_path, engineopenpyxl) if sheet is None: sheet xls.sheet_names[0] df pd.read_excel(file_path, sheet_namesheet, engineopenpyxl) before len(df) if drop_duplicates: df df.drop_duplicates() if drop_na: df df.dropna() with pd.ExcelWriter( file_path, engineopenpyxl, modea, if_sheet_existsreplace ) as writer: df.to_excel(writer, sheet_namesheet, indexFalse) return f清洗完成{before} 行 - {len(df)} 行 mcp.tool() def merge_excel_files( file_paths: list[str], output_path: str, use_sheet: str | None None ) - str: 把多个Excel文件的指定工作表按行拼接输出到一个新文件。 Args: file_paths: 待合并的xlsx路径列表 output_path: 合并结果保存路径 use_sheet: 要读取的工作表名称默认取每个文件的第一个工作表 frames [] for fp in file_paths: df pd.read_excel(fp, sheet_nameuse_sheet, engineopenpyxl) frames.append(df) merged pd.concat(frames, ignore_indexTrue) merged.to_excel(output_path, indexFalse) return f合并完成{len(frames)} 个文件共 {len(merged)} 行 - {output_path} if __name__ __main__: mcp.run()运行入口就一句话mcp.run()。什么都不传的时候FastMCP默认走stdio传输正好符合我们第一版的设计。3.3 代码里的几个关键设计决策我特意在代码里做了几个容易被忽略的决策这里展开说说为什么。为什么read_excel默认只读50行因为大模型对话窗口是有限的。一张十万行的销售明细表全量转成文本塞进对话一次就把上下文占没了AI反而什么都干不了。我先给它一个“样例统计信息”它觉得不够自然会再次调用比如传max_rows1000。这个主动权交给AI比一股脑全给要聪明得多。为什么所有路径都要求绝对路径这是我在第一版踩的坑。MCP客户端的工作目录不一定是你Excel文件所在的目录如果你传相对路径大概率扑空。强制要求绝对路径配合后面要讲的路径白名单整个工具的行为就变得可预测。为什么write_excel用if_sheet_existsreplace如果表已存在默认的追加模式会把表头写到数据下面去产生“表头和数据错位”的灵异现象。直接覆盖这张表语义最干净。如果你真要做“追加新行”可以单独做一个append_sheet工具不要在一个工具里同时承担“覆盖”和“追加”两种语义。为什么工具出错时尽量抛异常而不是自己吞掉在服务端里工具返回一个友好的错误字符串或者直接raise ValueError这个错误会通过MCP协议传回客户端AI看到错误后可以自行调整参数再试。如果我在代码里面啥都不报错、返回一个空DataFrameAI就会误以为“文件里没有数据”逻辑直接跑偏。AI容错能力很强前提是你得把错误原原本本告诉它。3.4 本地验证用官方调试器mcp dev写完代码别急着接GUI客户端先用官方调试器做一次冒烟测试。mcp dev excel_mcp_server.py运行之后它会起一个本地调试面板里面能看到这个服务端暴露了哪些工具你可以像调用函数一样手动去调。我习惯按这个顺序测用list_sheets确认文件能被读通用read_excel看返回的Markdown表格对不对用一个临时文件测write_excel确认能写入再测一遍clean_excel确保覆盖写回不会破坏原文件结构。一个很容易误导人的点是python excel_mcp_server.py运行起来后终端是“没有任何反应”的一直黑屏。很多人以为代码卡死了其实不是它是在stdio模式下等客户端输入。看到这种“无事发生”的状态恰恰说明服务端已经正常启动了。4. 接入客户端实测让AI直接操作Excel4.1 客户端配置把本地服务端挂到AI上现在主流桌面AI客户端大多支持MCP了。配置方式大同小异本质都是告诉客户端“去启动哪个命令、参数是什么”。你只需要在客户端的MCP配置里加一段类似这样的JSON{ mcpServers: { excel-assistant: { command: uv, args: [run, --directory, /你的项目路径/excel-mcp, python, excel_mcp_server.py] } } }如果你不用uv用刚才的虚拟环境启动也行把command换成.venv/bin/pythonargs换成脚本路径。改完配置后一定要重启客户端大部分客户端不会热加载MCP服务。启动成功后客户端通常会显示“已连接工具”并列出我们设计的六个工具。4.2 实测场景一一句话完成统计报表我拿一个销售明细表做了测试。文件有“姓名”“产品”“销售额”“日期”四列共八百多行。我的需求是“读取 销售明细.xlsx统计每个人的总销售额按总销售额从高到低排序写入一个新文件 销售汇总.xlsx。”然后观察AI的实际行动路径大概是这样的调用list_sheets确认文件里有个叫“Sheet1”的工作表调用read_excel先看前50行长什么样发现数据量远超50行主动再次调用read_excel并传max_rows1000把数据完整拿到在对话内部用pandas逻辑算出“每个人总销售额”的结果其实是我在MCP环境里允许AI做本地计算得到结果DataFrame调用write_excel把结果写成新文件。整个过程我没有碰过一次Excel也没有复制粘贴任何数据。AI全自动完成了“看结构→读数据→算结果→写文件”的闭环。这就是“工作流重构”最直观的体感以前是我在操作用户现在是我在给AI派活。4.3 实测场景二多文件合并与去重另一个我反复演示的场景是批量合并。需求是“把 data 目录下的 一月份.xlsx、二月份.xlsx、三月份.xlsx 合并成一个文件去掉重复行结果存到 季度汇总.xlsx。”这里要注意一个细节MCP工具默认看不到你的文件目录列表。除非你额外做一个list_directory工具否则AI并不知道data目录下有哪些文件。我的做法是在对话里主动把三个文件名告诉它或者像进阶章节里说的补一个列目录的工具。AI拿到文件列表后先调用merge_excel_files再调用clean_excel对合并结果做一次去重。跑完之后它会读回结果文件确认行数然后才向你汇报。这一步“自我检查”的行为很有意思不是我们教的是它在重复调用工具的过程中逐渐形成的习惯。如果你发现AI做完一步就直接交差了可以在系统提示词里加一句“所有写操作完成后必须读回文件确认结果”效果会立竿见影。4.4 工作流重构后你的角色变了工具跑通以后最让我感慨的不是“省了多少时间”而是我对Excel工作的心智模型变了。以前做Excel任务我的精力分配是回忆操作步骤、找按钮、担心格式错位、核对每一步中间结果。现在变成把需求表述清楚、确认AI的理解、在最终结果处做抽检。判断力依然是人负责的但那些低级的“胡萝卜加大棒”操作已经交给AI了。当然别高兴太早。AI工具调用偶尔会传错参数甚至会在你没交代的情况下自作主张地覆盖文件。所以跑任何写入操作前务必先复制一份原始文件做备份。我的习惯是在项目目录里建一个backup/文件夹所有被写过的文件都留一份快照。这是唯一一条我希望你无论如何都要遵守的纪律。5. 调试与避坑把Excel MCP Server真正跑稳的经验5.1 调试三板斧面板、错误信息、日志第一板斧是mcp dev调试面板它能把工具调用过程可视化你能清楚看到AI读了什么、传了什么参数、返回了什么结果。很多“AI怎么乱来”的灵异事件在这个面板里都是肉眼可见的。第二板斧是工具内部的错误信息。再次强调永远不要返回“None”“[]”这类暧昧结果AI会把空结果当成“正常处理完了”。在你不知道该返回什么的时候抛一个异常或者返回一段包含当前上下文信息的报错文本。比如“读不到文件/xxx/yyy.xlsx请确认路径是否正确”AI看到后会自己修正路径重试。第三板斧是客户端日志。桌面客户端一般都会在设置目录里写详细日志里面能看到MCP子进程的启动命令、退出码、标准错误输出。当你的服务端启动直接崩了时这个日志是唯一的救命稻草。找日志的位置比你想的麻烦建议在第一次配置时就先故意把服务器路径写错一次然后顺着日志找到日志文件你就知道以后去哪看了。5.2 文件路径和中文文件名的坑我在测试阶段被路径问题折腾了整整一个下午所以必须单独写一段。本地stdio模式下MCP客户端启动你的脚本后脚本的工作目录往往是客户端的安装目录不是你Excel所在的业务目录。所以你绝对不能让AI去“猜文件路径”只能传绝对路径。更省心的做法是做一个路径白名单服务端启动时绑定一个工作根目录只允许访问这个目录下的文件。另外中文文件名在Windows上特别容易出问题。如果你用Python字符串直接拼路径遇到带空格的目录或者中文名目录轻则路径解析失败重则直接把文件写到一个“长得差不多”的错误目录里。我的建议是所有路径统一用pathlib.Path处理不要自己拼字符串在Windows上尽量用原始字符串rC:\xxx\yyy或者正斜杠C:/xxx/yyy可以少很多转义烦恼。还有权限问题。在macOS上如果你把Excel文件放在“桌面”或“文档”目录首次访问会触发系统授权弹窗在Windows上有些公司电脑的C盘受控目录也一样。这种问题通常表现为“服务端能起但一读文件就报错”。别慌看错误信息是不是Permission denied是的话去系统设置里给Python解释器授权或者在测的时候把文件放到一个专门建的工作目录里。5.3 大Excel文件和超时的坑MCP客户端对单次工具调用不是无限等待的很多客户端默认超时时间很短。如果你用merge_excel_files合并三个各十万行的文件pandas可能确实需要几十秒这时候客户端可能已经超时了表现就是“AI说它在处理然后突然断掉”或者“工具调用失败重试”。我的解法有三个层次。第一层是给merge类工具增加“数据量预检”在合并之前先读一遍每个文件的行数如果总行数超过阈值直接返回“文件太大建议分批处理”而不是闷头合并到最后超时。第二层是把结果写到一个临时文件然后只返回“已经写好了路径是xxx”这样即使客户端超时文件已经落盘了恢复后还能找到。第三层是接受现实第一版不要在同一个工具里做超大文件的复杂清洗分几步跑比一个工具干完全部要省心得多。还有一条和大表相关的建议当AI告诉你“这个表太大读不完”时你千万别马上加max_rows1000000。正确做法是做个get_sheet_summary工具只返回列名、行数、每列非空值数量和数据类型让AI先做“结构预判”再决定要不要全量读。这个工具在真实项目里比read_excel本身还常用。5.4 工具描述与参数设计的坑MCP工具能不能被用好一半取决于代码一半取决于描述文本。可以说工具的docstring就是你和AI之间的接口文档。我有一次把read_excel里的参数说明漏写了AI就真的不知道max_rows是干什么的全程不敢碰这个参数每次读取都拿默认50行统计永远做不对。所以每个描述都要回答三个问题这个工具适合什么场景每个参数是什么含义返回什么格式写的时候用TypeDoc风格分段写AI容易解析。参数的类型约束也要利用起来。比如清洗策略这种字段与其让AI传任意字符串不如用枚举类型约束死from typing import Literal mcp.tool() def clean_excel( file_path: str, strategy: Literal[drop_duplicates, drop_na, both] drop_duplicates, ) - str: 按指定策略清洗Excel工作表。 Args: strategy: drop_duplicates去重drop_na去空行both两者都做 这样AI就算想作妖参数也传不进非法值。它的选择空间被缩小到三个值行为自然就可控了。5.5 安全边界的坑别把整个文件系统暴露给AI最后这个问题很严肃。MCP工具本质上是AI能直接触达你电脑的能力通道如果你做一个“删除文件”的工具某天误操作可能就是灾难。我的原则是不做删除类工具。清洗、覆盖都有备份兜底删除不可逆路径必须白名单。服务端里搞一个ALLOW_DIR常量每次工具调用路径时先Path.resolve()再检查前缀是否在允许目录内覆盖写之前自动备份。在write_excel和clean_excel里如果目标文件已存在先copy成xxx.backup_时间戳.xlsx再动手。import shutil from datetime import datetime def _backup_if_exists(file_path: str): if Path(file_path).exists(): backup_name f{file_path}.backup_{datetime.now().strftime(%Y%m%d_%H%M%S)} shutil.copy(file_path, backup_name) return backup_name return None这个方法不复杂但能让你在AI偶尔“抽风”导致文件内容丢失时救回一天的工作量。我在实际使用中已经靠这个备份机制救了两次场一次是AI把“去重”理解成了“删掉所有行”另一次是写回时表头错位。备份就是最后的保险网。6. 进阶玩法从单机工具到组合工作流6.1 组合其他MCP Server让Excel能力融入更大流程第一个MCP跑通之后你会发现自己进入了一个更大的生态。现在已经有很多现成的MCP Server浏览器自动化、PDF解析、数据库查询、接口测试、流程图/思维导图等等。它们都是同一套协议所以可以同时挂到同一个客户端里让AI组合使用。想象一个真实的办公流你在网页上找到一个统计表格 → 浏览器自动化MCP把表格抓下来 → 你的Excel MCP Server把内容清洗成结构化数据 → 再调用图表工具生成报表。这在以前需要写一个专门的爬虫加数据处理脚本现在只是几个MCP Server之间的协同。需要注意的坑是当客户端挂载了多个MCP Server工具名可能会冲突。比如你的Server里有一个read_excel另一个PDF Server里也有一个read_filesAI在选工具时偶尔会张冠李戴。解决方式有两种一是给每个工具加清晰的前缀二是第一次使用时在系统提示词里把“哪些场景用哪个Server”说清楚。我实测下来给工具名加前缀是最省心的比如xlsx_read、xlsx_merge减少AI理解的歧义。6.2 与n8n、Coze这类编排平台的配合方式这里还有一个容易混淆的概念需要捋清楚。MCP解决的是“AI怎么调用工具”的问题而n8n、Coze这类流程编排平台解决的是“固定流程怎么自动跑”的问题。你可以这么理解编排平台是流水线MCP是给流水线旁边那个“AI工人”递工具的人。两者不是替代关系而是配合关系。实际项目中我会把复杂、固定的流程放进编排平台里跑比如定时抓取数据、定时发送报表而流程里如果有“让AI根据Excel内容做判断、再决定怎么处理”的环节就把我的Excel MCP Server作为能力插件供它调用。这样固定流程和灵活决策各干各的反而比全都塞给编排平台更清晰。6.3 把Excel MCP Server开放成远程服务如果你的团队其他人也想用这套能力你就可以考虑从stdio升级到SSE模式。改动很小if __name__ __main__: mcp.run(transportsse)这样服务端会变成一个HTTP接口其他机器通过网络就能接入。但我要泼三盆冷水第一鉴权一定要做。没有鉴权的SSE服务等于把你电脑上的Excel文件暴露给任何能访问到这个端口的人。最简单的做法是在服务端加一个Token校验每个请求都必须带Token。第二并发写文件是灾难。两个用户同时往同一个Excel文件写入pandas虽然能打开文件但写回的时候极可能互相覆盖。我目前的方案是加一个简单的文件锁或者要求远程用户都写到各自独立的结果目录里。第三数据隐私会急剧恶化。本地stdio模式下的Excel文件不会离开你的电脑但SSE模式下文件内容会通过网络往返。如果Excel里有身份证号、工资、客户名单这类敏感信息我强烈建议你直接放弃远程方案老老实实本地用。网上确实有一些公共MCP服务打着“免费接入”的旗号但你把自己的数据交给别人的服务器处理这风险自己掂量。6.4 再往下你的Excel工具箱还可以长这样工具池是越用越大的。我给自己列了一些马上想做的下一批工具markdown_to_excel把AI对话里输出的Markdown表格直接转成xlsx这个对日常写周报、整理会议纪要特别实用query_excel支持SQL式查询的Excel工具比如“从Sheet1里选姓名、销售额按销售额取前10”一个工具代替多次读取和分析省token也更直接excel_to_template按预设模板批量生成报表文件get_sheet_summary返回列名、数据类型、非空数量、唯一值数量是AI做数据预判的好帮手。# markdown_to_excel 的小片段给个思路 import io import pandas as pd mcp.tool() def markdown_to_excel(md_table: str, output_path: str) - str: 把Markdown格式表格写入Excel文件。 Args: md_table: 完整的Markdown表格文本 output_path: 输出的xlsx路径 df pd.read_markdown(io.StringIO(md_table)) df.to_excel(output_path, indexFalse) return f已写入 {len(df)} 行到 {output_path}你别小看这个工具它解决的是“AI最擅长输出表格文本、人最烦手动复制进Excel”的最后一公里问题。我跑通之后周报里的数据表格基本都走这条路了。最后再说一个真实的体会。写完这个MCP Server收获最大的不是代码本身而是你被迫重新审视了自己每天那些“Excel动作”。哪些是重复的、哪些参数是固定的、哪些数据流是脏的——这个过程本身就在帮你梳理工作流。很多同事看完演示问我会不会被AI替代我说不会被替代的是“手动重复”留下来的才是“判断需求到底要Excel给出什么答案”的能力。动原始数据前务必备份先从每天最烦人的那一两个动作开始让AI先学会做一件小事。第一个MCP能跑、能调、能用就已经赢了。