news 2026/5/2 7:01:26

Python创建MCP服务

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python创建MCP服务

提到mcp,或许大家或多或少都已经有听说或使用过。Model Context Protocol简称MCP,即模型上下文协议。简单类比如笔记本的USB接口,为鼠标、键盘、打印机提供统一的接入标准。而MCP的出现,正是为了解决AI模型与外部世界沟通的“接口混乱”问题。它提供了一套标准化的协议,让AI大模型能够通过统一的方式安全、高效地调用外部工具、读取数据源。那么,一个标准的MCP服务是如何创建的,今天就基于一个类似服务器日志操作案例编写一个入门级的MCP服务,以及在大模型中调用后的实际效果。
MCP协议本身很强大,但直接实现它可能会比较复杂。本篇基于Python生态框架进行快速服务的构建,在本地创建一个Python项目后安装以下依赖:本项目基于Python3.8

一、安装依赖

pip install mcp fastmcp uvicorn

二、示例代码如下

创建项目后编写一个server.py文件

importjsonimportrefromdatetimeimportdatetimefrompathlibimportPathfromtypingimportDict,AnyfromfastmcpimportFastMCP# 初始化MCP服务器,Log Analyzer为服务器自定义名称mcp=FastMCP("Log Analyzer")# 日志文件路径(可以替换成真实的)LOG_FILE=Path("./server.log")# 如果未存在日志文件可进行模拟日志测试数据definit_mock_logs():"""生成模拟的系统日志"""ifnotLOG_FILE.exists():logs=["[2026-04-05 10:23:15] INFO - User login successful: admin@example.com","[2026-04-05 10:25:42] ERROR - Database connection timeout after 30s","[2026-04-05 10:26:01] WARNING - High memory usage detected: 85%","[2026-04-05 10:28:33] INFO - File upload completed: report.pdf","[2026-04-05 10:30:17] ERROR - API request failed: 500 Internal Server Error","[2026-04-05 10:32:45] INFO - Cache cleared successfully","[2026-04-05 10:35:22] WARNING - Slow query detected: SELECT * FROM users (took 5.2s)","[2026-04-05 10:38:09] ERROR - Disk space low: only 2.3GB remaining","[2026-04-05 10:40:55] INFO - Backup completed successfully","[2026-04-05 10:43:11] CRITICAL - Service crash detected, restarting...","[2026-04-05 10:45:30] INFO - Service restarted successfully","[2026-04-05 10:48:02] ERROR - Failed to send email: SMTP server unreachable"]withopen(LOG_FILE,'w',encoding='utf-8')asf:f.write('\n'.join(logs))#这是最核心的部分。通过@mcp.tool装饰器,将普通的Python函数变成AI可以理解和调用的工具。函数的文档字符串(docstring)是给AI看的“说明书”,一定要写得清晰明了# AI每次调用时进行记录工具,log_query默认为工具名称@mcp.tooldeflog_query(query:str,tool:str=""):"""记录 AI 查询(AI 应在执行任何查询前调用)"""withopen("log_query.log",'a',encoding='utf-8')asf:f.write(f"[{datetime.now()}]{tool}:{query}\n")return"记录成功"# 解析日志行defparse_log_line(line:str)->Dict[str,Any]:"""解析单行日志"""pattern=r'\[(.*?)\] (\w+) - (.*)'match=re.match(pattern,line)ifmatch:return{"timestamp":match.group(1),"level":match.group(2),"message":match.group(3)}return{"raw":line}# 获取最近N条日志@mcp.tooldefget_recent_logs(lines:int=50)->str:""" 获取最近的系统日志记录 Args: lines: 要获取的日志行数,默认50条 """init_mock_logs()withopen(LOG_FILE,'r',encoding='utf-8')asf:all_logs=f.readlines()recent_logs=all_logs[-lines:]returnjson.dumps({"total_lines":len(all_logs),"returned_lines":len(recent_logs),"logs":[parse_log_line(log.strip())forloginrecent_logs]},ensure_ascii=False,indent=2)# 按错误级别筛选日志@mcp.tooldeffilter_logs_by_level(level:str,limit:int=20)->str:""" 按日志级别筛选日志(ERROR, WARNING, INFO, CRITICAL等) Args: level: 日志级别,如 ERROR, WARNING, INFO, CRITICAL limit: 返回的最大条数,默认20 """init_mock_logs()withopen(LOG_FILE,'r',encoding='utf-8')asf:logs=f.readlines()filtered=[]forloginlogs:iff"{level}- "inlog:filtered.append(parse_log_line(log.strip()))iflen(filtered)>=limit:breakreturnjson.dumps({"level":level,"count":len(filtered),"logs":filtered},ensure_ascii=False,indent=2)# 搜索包含关键词的日志@mcp.tooldefsearch_logs(keyword:str,case_sensitive:bool=False)->str:""" 在日志中搜索特定关键词 Args: keyword: 要搜索的关键词 case_sensitive: 是否区分大小写,默认False """init_mock_logs()withopen(LOG_FILE,'r',encoding='utf-8')asf:logs=f.readlines()results=[]forloginlogs:log_text=log.strip()ifcase_sensitive:found=keywordinlog_textelse:found=keyword.lower()inlog_text.lower()iffound:results.append(parse_log_line(log_text))returnjson.dumps({"keyword":keyword,"case_sensitive":case_sensitive,"count":len(results),"logs":results},ensure_ascii=False,indent=2)# 获取日志统计摘要@mcp.tooldefget_log_summary()->str:""" 获取日志统计摘要,包括各级别日志数量和常见错误类型 """init_mock_logs()withopen(LOG_FILE,'r',encoding='utf-8')asf:logs=f.readlines()stats={"total":len(logs),"levels":{"INFO":0,"WARNING":0,"ERROR":0,"CRITICAL":0},"common_errors":[]}error_count={}forloginlogs:parsed=parse_log_line(log.strip())level=parsed.get("level","")iflevelinstats["levels"]:stats["levels"][level]+=1# 统计常见错误iflevel=="ERROR":msg=parsed.get("message","")# 提取错误类型error_type=msg.split(":")[0]if":"inmsgelsemsg[:30]error_count[error_type]=error_count.get(error_type,0)+1# 取前5个常见错误stats["common_errors"]=sorted(error_count.items(),key=lambdax:x[1],reverse=True)[:5]returnjson.dumps(stats,ensure_ascii=False,indent=2)if__name__=="__main__":# 初始化日志文件init_mock_logs()# 使用HTTP传输模式print("MCP Log Analyzer Server 启动中...")print(f"日志文件路径:{LOG_FILE.absolute()}")print("服务运行在: http://localhost:8000/mcp")# 运行HTTP服务器(端口8000)mcp.run(transport='http',host='0.0.0.0',port=8000)

执行python server.py后启动服务,界面运行如下:

以上界面提示mcp服务启动成功,基于http协议,同时在命令行可看到该日志:
Starting MCP server ‘Log Analyzer’ with transport ‘http’ on http://0.0.0.0:8000/mcp

三、使用mcp服务

以上MCP服务创建后如何进行测试,本文章基于cline插件进行快速验证,关于cline的使用大家可自行网上搜索和配置使用对应的大模型,本文mcp服务环境是在本地运行,大家也可部署成在线服务线上访问。

cline中找到MCP Server,点击添加mcp服务:

服务信息填写完后点击AddServer

如图,在server.py中定义的5个工具都能被正确识别,大家勾选需要使用的工具即可,AI会根据工具名称和描述做调用。
接着,在cline交互面板中输入提问,结果如下:


大模型会根据问题自动调用工具并分析,也扩展了对应的能力边界。

四、总结

通过这个简单的日志分析器,从MCP服务的创建到使用,通过定义工具Tools的方式,将外部数据和服务的能力赋予AI。像高德地图等应用也开放一些在线MCP服务,大模型接入后就可以进行位置搜索等能力拓展了。
另外,MCP还支持资源(Resources)和提示词模板(Prompts)等更强大的功能,大家有兴趣可以自行了解,后续本文也会持续更新,有问题的欢迎大家一块交流!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/2 7:00:47

从六祖慧能口诀想到罗福莉访谈和DeepSeek V4

点击上方蓝字关注我们第一时间获取更新最近晨起阅读《六祖慧能金刚经口诀》,颇有收获。六祖解释“真如”时,说得极朴素:真者不变,如者不异,遇诸境界,心无变异,名日真如,亦云外不假日…

作者头像 李华
网站建设 2026/5/2 6:59:58

GraphLocator:基于图结构的智能问题定位技术解析

1. 项目背景与核心价值在软件工程领域,问题定位(Fault Localization)一直是开发周期中最耗时的环节之一。传统方法主要依赖日志分析、断点调试或覆盖率统计,这些手段在面对复杂系统时往往效率低下。我们团队开发的GraphLocator提出…

作者头像 李华
网站建设 2026/5/2 6:59:26

深度搜索代理在规则密集型系统中的应用与优化

1. 项目背景与核心价值在规则密集型系统中,分层规则的快速匹配与高效检索一直是个技术难点。HSCodeComp项目正是针对这一痛点提出的创新解决方案,它通过深度搜索代理技术重构了传统规则匹配的流程。我在处理海关编码系统时发现,现有方案要么牺…

作者头像 李华
网站建设 2026/5/2 6:55:24

从账单明细看 Taotoken 按 token 计费如何帮助项目厘清成本

从账单明细看 Taotoken 按 token 计费如何帮助项目厘清成本 1. 账单明细的核心价值 在项目管理中,资源消耗的透明化是成本控制的基础。Taotoken 提供的账单明细功能将每个 API Key 的调用记录按模型分类统计,精确到 token 粒度的计费方式让团队能够追溯…

作者头像 李华