当前位置: 首页 > news >正文

mcp学习笔记

MCP(Model Context Protocol)是一种由Anthropic推出的开放协议,旨在统一大型语言模型(LLM)与外部数据源/工具之间的交互。其核心组件包括 ​MCP ClientMCP Server​ 和 ​Function Calling​ 机制,三者协同工作以扩展LLM的能力,使大模型能够调用外部工具。

MCP协议是提示词工程和Function calling技术发展的产物,将如何调用外部工具这个事进行规范和统一。本文使用Python实现了一个简单的mcp demo程序,可实现利用自然语言来操作数据库,发送手机验证码和邮件。

一、MCP基本概念和原理

首先需要了解MCP中几个重要的概念,可参考这里MCP 简介 - MCP 中文文档
mcp中几个要素的关系如下图所示,用户通过mcp client与大模型进行交互,mcp server提供为mcp client提供外部工具。

使用mcp协议调用外部工具的过程如下:

s1:用户向mcp client提出问题;

s2:mcp client将用户的问题和tools列表一同提交给大模型;

s3:大模型会根据用户的问题,从tools列表中取出最相关最适合的工具,构造好参数,向client返回工具名和参数,也有可能找不到;

s4:mcp client调用根据工具名和参数调用对应的接口,可以是本地的函数,也可以是web api,取决于mcp server如何实现;

s5:mcp client将工具的结果提交给大模型;

s6:大模型对工具返回的结果,来回答用户的原始问题;

s7: mcp client将大模型最终的回答呈现给用户。

二、Function calling

Function Calling 允许LLM根据用户请求生成结构化参数(如JSON格式),触发预定义的外部函数或API调用,从而获取实时数据或执行具体操作。例如用户询问天气时,模型提取参数(城市、日期)并调用天气API。

原理:

  1. 开发者注册函数名称、参数类型及描述(类似JSON Schema),要符合json schema规范。

  2. 模型解析用户请求,匹配适用的函数。

  3. 提取关键信息并格式化为结构化参数(如{"location":"北京"}

  4. 外部系统调用函数后,结果返回模型生成最终回答。

Function calling功能需要对模型进行微调训练,使模型能够理解json schema格式语法,为函数构造正确的json格式参数。

目前支持Function calling功能的模型有

  • OpenAI GPT系列​:从GPT-3.5开始集成此功能,2023年就有了

  • Anthropic Claude​:支持与外部服务深度集成。

  • 国产模型​:阿里Qwen、DeepSeek v3等通过微调实现类似能力

三、Function calling示例

下面我们使用python写一个示例程序,来演示如何使用function calling功能,实现利用自然语言来操作数据库和访问第三方接口。这里我们使用的模型是qwen3-32b。

python如何调用通义模型可参考阿里百炼的官方API文档。

下面是阿里官方的例子,可作为参考。

import os
from openai import OpenAIclient = OpenAI(# 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx",api_key=os.getenv("DASHSCOPE_API_KEY"),base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",  # 填写DashScope SDK的base_url
)tools = [# 工具1 获取当前时刻的时间{"type": "function","function": {"name": "get_current_time","description": "当你想知道现在的时间时非常有用。","parameters": {}  # 因为获取当前时间无需输入参数,因此parameters为空字典}},  # 工具2 获取指定城市的天气{"type": "function","function": {"name": "get_current_weather","description": "当你想查询指定城市的天气时非常有用。","parameters": {  "type": "object","properties": {# 查询天气时需要提供位置,因此参数设置为location"location": {"type": "string","description": "城市或县区,比如北京市、杭州市、余杭区等。"}},"required": ["location"]}}}
]
messages = [{"role": "user", "content": "杭州天气怎么样"}]
completion = client.chat.completions.create(model="qwen-plus",  # 此处以qwen-plus为例,可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/modelsmessages=messages,tools=tools
)print(completion.model_dump_json())

1.获取阿里百炼的api key

这步比较简单不再展开,现在可领取100万的免费tokens额度。

2.mcp_client

代码如下,功能见注释。

import json
import os
from openai import OpenAI
from mcp_server import *# 模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
MODEL = "qwen3-32b"  # 模型名称def main():# 参考https://bailian.console.aliyun.com/?tab=api#/api/?type=model&url=https%3A%2F%2Fhelp.aliyun.com%2Fdocument_detail%2F2712576.html&renderType=iframeclient = OpenAI(# 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx",api_key=os.getenv("Bailian_API_Key"),base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",)messages=[{"role": "system", "content": "You are a helpful assistant."}]while True:query = input("请输入问题:")if query == "exit":breakelif query == "clear":os.system("cls")continueelif query == "reset":messages = [{"role": "system", "content": "You are a helpful assistant."}]continueelse:messages.append({"role": "user", "content": query})completion = client.chat.completions.create(model=MODEL,messages=messages,extra_body={"enable_thinking": False},tools = json.load(open("tools.json", "r", encoding="utf-8")),# 这里加载工具列表# Qwen3模型通过enable_thinking参数控制思考过程(开源版默认True,商业版默认False)# 使用Qwen3开源版模型时,若未启用流式输出,请将下行取消注释,否则会报错# extra_body={"enable_thinking": False},)# 将大模型的结果保存到文件# 这里使用了model_dump_json()方法,返回的是一个json字符串res  = completion.model_dump_json()json.dump(completion.dict(), open("response1.json", "w", encoding="utf-8"), ensure_ascii=False, indent=4)#若大模型的结果中有tool_calls字段,则表示调用了工具if completion.choices[0].finish_reason == 'tool_calls':# 取出tool_calls字段中的第一个工具调用tool_call = completion.choices[0].message.tool_calls[0]py_code = 'ret = ' +  tool_call.function.name + "(**" + tool_call.function.arguments + ")" # ret = func_name(**args) 的方式传递参数exec(py_code,globals()) # 执行代码,将ret变量映射到当前程序的全局变量空间中# 将function calling的结果加入messages中messages.append(completion.choices[0].message.model_dump())# 将工具调用的结果加入messages中messages.append({'role':'tool','content':  str(ret),'tool_call_id': tool_call.id,})  # 提交给大模型completion = client.chat.completions.create(model=MODEL,messages=messages,extra_body={"enable_thinking": False})# 将大模型的结果保存到文件json.dump(completion.dict(), open("response2.json", "w", encoding="utf-8"), ensure_ascii=False, indent=4)# 输出大模型的最终回答if completion.choices[0].message.content:print(completion.choices[0].message.content)messages.append({"role": "assistant", "content": completion.choices[0].message.content})        main()

2. mcp_server

在mcp_server中我们提供了三类接口,具体见附件

一是访问本地sqlite数据库的接口

  • execute_query(sql, params=None) 执行SQL查询并返回结果

  • get_all_table_structures 获取SQLite数据库中所有表的结构信息

二是获取本地公网IP和运营商信息的接口

  • get_public_ip 获取当前公网IP地址

  • get_ip_details(ip: str) 获取IP详细信息(含城市、运营商)

三是发送信息的接口

  • send_verification_code(phone_number: str, code: str) 向指定手机号发送短信验证码

  • sent_email(to,subject,body) 发送邮件

3. 接口说明

这里的所有的接口的函数和参数描述为json_schema格式,保存为tools.json,这个tools描述要提交给大模型接口。json schema语法可参考JSON Schema reference。


[{"type": "function","function": {"name": "execute_query","description": "执行SQL查询并返回结果","parameters": {"type": "object","properties": {"sql": {"type": "string","description": "要执行的SQL语句"},"params": {"type": "array","description": "SQL语句的参数","items": {"type": "string"}}},"required": ["sql","params"]}}},{"type": "function","function": {"name": "get_all_table_structures","description": "获取所有表的结构信息","parameters": {}}},{"type": "function","function": {"name": "get_public_ip","description": "获取当前公网IP地址","parameters": {}}},{"type": "function","function": {"name": "get_ip_details","description": "获取IP详细信息(含城市、运营商)","parameters": {"type": "object","properties": {"ip": {"type": "string","description": "要查询的IP地址"}},"required": ["ip"]}}}, {"type": "function","function": {"name": "send_verification_code","description": "发送短信验证码","parameters": {"type": "object","properties": {"phone_number": {"type": "string","description": "手机号"},"code": {"type": "string","description": "验证码(需为6位数字)","pattern": "^\\d{6}$","minLength": 6,"maxLength": 6}},"required": ["phone_number","code"]}}},{"type": "function","function": {"name": "sent_email","description": "发送电子邮件","parameters": {"type": "object","properties": {"to": {"type": "string","description": "收件人邮箱地址"},"subject": {"type": "string","description": "邮件主题"},"body": {"type": "string","description": "邮件正文"}},"required": ["to","subject","body"]}}}
]

四、测试

为了测试数据操作,在本地创建了一个sqlite数据库,并创建了两个表students和scores,用来存储学生的个人信息和成绩,填充了一些假数据。

students表

scores表

1.测试数据库接口

读取表结构

select操作

提问和回答如下,获得的数据完全正确。

看一下response1.json内容,如下所示,可以看到function calling的响应中,大模型建议调用execute_query函数,并给出了正确的sql语句。

{"id": "chatcmpl-e0d887bb-3954-9585-9594-ae39ccbe5f75","choices": [{"finish_reason": "tool_calls","index": 0,"logprobs": null,"message": {"content": "","refusal": null,"role": "assistant","audio": null,"function_call": null,"tool_calls": [{"id": "call_ca7257e92b9a412d8c1553","function": {"arguments": "{\"sql\": \"SELECT * FROM scores WHERE 学号 = (SELECT 学号 FROM students WHERE 姓名 = ?)\", \"params\": [\"张晓萌\"]}","name": "execute_query"},"type": "function","index": 0}],"reasoning_content": ""}}],"created": 1747480960,"model": "qwen3-32b","object": "chat.completion","service_tier": null,"system_fingerprint": null,"usage": {"completion_tokens": 49,"prompt_tokens": 1319,"total_tokens": 1368,"completion_tokens_details": null,"prompt_tokens_details": null}
}

update操作

这个问题client也是调用execute_query函数。

在navicat中查看数据库,可以看到数据直接的被修改了。

2. web接口测试

如下图所示,这两个问题也完全正确,分别调用get_public_ip和get_ip_details函数。

3.信息发送接口

提问如下 ,大模型回复都完成了。

这里我填写的是本人的手机号和邮箱,手机收到了短信。

收到了邮件

五、如何在通义灵码中使用mcp

可参考配置 MCP 服务_通义灵码_智能编码助手_智能编码助手通义灵码(Lingma)-阿里云帮助中心。

需要在vscode中安装通义灵码插件,具体怎么配置和登陆不再展开,可参考上面的官方文档。

我从MCP广场中添加了几个mcp server,比如MCP 中文趋势聚合,感觉就是个爬虫。

提供的工具还挺多。

测试一下它的功能,感觉很准确。

总结

本文使用python写了一个最简单的mcp demo,没有严格的按照mcp协议来,本质上还是使用function calling功能来调用函数。

现在互联网上有很多mcp_server市场,比如阿里百炼mcp市场,还有魔搭社区MCP 广场 。

很多服务提供端也提供了自己的mcp server 如百度、高德、支付宝等,以后估计会越来越多。

mcp_client有Claude Desktop**、Cursor、阿里通义灵码等,cursor和通义灵码可vscode的插件市场中安装。

安全领域奇安信也发布了自己的威胁情况MCP server。

看来拥抱mcp已经成为大势所趋。

参考资料

  • MCP 简介 - MCP 中文文档
  • JSON Schema reference
  • 百炼API参考
  • 配置 MCP 服务_通义灵码_智能编码助手_智能编码助手通义灵码(Lingma)-阿里云帮助中心

相关文章:

  • JSP链接MySQL8.0(Eclipse+Tomcat9.0+MySQL8.0)
  • 西门子 Teamcenter13 Eclipse RCP 开发 1.2 工具栏 开关按钮
  • 在线教育本地化分发:代理IP实现区域访问控制与内容适配
  • MySQL表的约束(上)
  • 嵌入式学习笔记 - STM32定时器的输入通道与时钟源
  • Vue+Vite学习笔记
  • C语言查漏补缺
  • 2025年渗透测试面试题总结-安恒[实习]安全工程师(题目+回答)
  • 中级网络工程师知识点4
  • 灵光一现的问题和常见错误2
  • 芯片生态链深度解析(二):基础设备篇——人类精密制造的“巅峰对决”
  • 劳特巴赫trace32负载率测试
  • [YOLO模型](4)YOLO V3的介绍
  • 新的节能技术和一体化解决方案,推动工厂智能升级和产业转型
  • 开源RTOS(实时操作系统):nuttx 编译
  • MyBatis 核心组件源码分析
  • 车载诊断架构 --- 核心网关流控制机制需求
  • 一个指令,让任意 AI 快速生成思维导图
  • 【单机版OCR】清华TH-OCR v9.0免费版
  • Win11下轻松搭建wiki.js,Docker.desktop部署指南(mysql+elasticsearch+kibana+wiki.js)
  • 英国6月初将公布对华关系的审计报告,外交部:望英方树立正确政策导向
  • 商务部召开全国离境退税工作推进会:提高退税商店覆盖面,扩大入境消费
  • 获派驻6年后,中国驻厄瓜多尔大使陈国友即将离任
  • 严打金融黑灰产,今年来上海警方破获各类经济犯罪案件690余起
  • 工商银行杭州金融研修院原院长蒋伟被“双开”
  • 押井守在30年前创造的虚拟世界何以比当下更超前?