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

MCP 协议客户端与服务端python demo

mcp server 端:

# -*- coding: utf-8 -*-
'''
@Date 2025-09-15
'''"""
MCP server服务端
需要安装mcp 包 "mcp[cli]"
pip install "mcp[cli]"
或者 uv add mcp[cli]
"""from mcp.server.fastmcp import FastMCP
from pathlib import Path
from typing import List
mcp = FastMCP("testmcp",stateless_http=False)@mcp.tool()
async def get_sum(a:int,b:int) -> int:"""Calculate the sum of two integersArgs:a intb int"""c = a+breturn c@mcp.tool()
async def get_files(path:str) -> List[str]:"""Obtain all the files in the path directoryArgs:path str query the path directory"""dir_path = Path(path)files = [file.name for file in dir_path.iterdir() if file.is_file()]return filesif __name__ == "__main__":# Initialize and run the server#transport = stdio|sse|streamable-httpmcp.run(transport='streamable-http')

mcp client端:

# -*- coding: utf-8 -*-
'''
@Date 2025-09-16
'''"""
MCP client客户端
"""import requests
import json
import randomclass StreamableHttpClient(object):"""mcp streamable-http 方式mcp协议 官网:https://modelcontextprotocol.comhttps://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle连接MCP 服务的时候必须先 "initialize"和"notifications/initialized"然后再进行功能操作"""def __init__(self,url):""""""self.url = urlself.session = requests.Session()self.random_id = random.randint(1,10)self.mcp_session_id = ""self.init_notification = Falsecode,resp,result = self.initialize()if code == 200:code,resp,result = self.notification_initialized()if code == 202:self.init_notification = Trueelse:print("notification_initialized error")def initialize(self):""""""client_name = "python-streamable-client"client_version = "1.0.0"payload = {"jsonrpc": "2.0","method": 'initialize',"id": self.random_id,"params": {"protocolVersion": "2025-06-18","capabilities": {"tools": {},"resources": {},"prompts": {},"sampling": {},"elicitation":{},"roots": {'listChanged':True}},"clientInfo": {"name": client_name,"version": client_version,'title':client_name}}}headers = {'Content-Type': 'application/json','Accept': 'application/json, text/event-stream'}self.random_id += 1self.session.headers.update(headers)resp = self.session.post(self.url,json=payload,stream=False)self.mcp_session_id = resp.headers.get('mcp-session-id',"")return self._pro_response(resp)def notification_initialized(self):"""notification 通知从客户端发送到服务器,或者从服务器发送到客户端,作为单向消息。接收方不得发送响应注意不需要 payload 中不需要参数"id"status_code == 202  不存在text和json()"""payload = {"jsonrpc": "2.0","method": 'notifications/initialized'}headers = {'Content-Type': 'application/json','Accept': 'application/json, text/event-stream'}headers['Mcp-Session-Id'] = self.mcp_session_idself.random_id += 1self.session.headers.update(headers)resp = self.session.post(self.url,json=payload,stream=False)return self._pro_response(resp)def tools_list(self):""""""if not self.init_notification:print("tools_list request error")return 111,None,{}payload = {"jsonrpc": "2.0","method": 'tools/list',"id": self.random_id,"params":{}}headers = {'Content-Type': 'application/json','Accept': 'application/json, text/event-stream','Mcp-Session-Id':self.mcp_session_id,}self.random_id += 1self.session.headers.update(headers)resp = self.session.post(self.url,json=payload,stream=True)return self._pro_response(resp)def tools_call(self,name:str,args:dict):""""""if not self.init_notification:print("tools_list request error")return 222,None,{}payload = {"jsonrpc": "2.0","method": 'tools/call',"id":self.random_id,"params":{'name':name,"arguments":args}}self.random_id += 1headers = {'Content-Type': 'application/json','Accept': 'application/json, text/event-stream','Mcp-Session-Id':self.mcp_session_id,}self.session.headers.update(headers)resp = self.session.post(self.url,json=payload,stream=True)return self._pro_response(resp)def _pro_response(self,resp):"""notification_initialized status_code == 202  不存在text和json()"""if resp.status_code != 200:return resp.status_code,resp,{}ct = resp.headers.get("content-type","").lower()if 'text/event-stream' in ct:result = json.loads(resp.text.strip().split("data: ")[1])elif 'application/json' in ct:result = resp.json()else:result = {}return resp.status_code,resp,resulturl = "http://127.0.0.1:8000/mcp"
c = StreamableHttpClient(url)
code,resp,result = c.tools_list()
print('tools_list',code,result)
code,resp,result = c.tools_call('get_sum',{"a":2,"b":3})
print('tools_call',code,result)


文章转载自:

http://KHuu66Z2.mnbcj.cn
http://4kVXXCZl.mnbcj.cn
http://decLr21L.mnbcj.cn
http://IOdN4EhH.mnbcj.cn
http://VaNMyOdC.mnbcj.cn
http://Wb23HwQY.mnbcj.cn
http://tA1trM44.mnbcj.cn
http://qOyTf0Uj.mnbcj.cn
http://uGLjTrkJ.mnbcj.cn
http://x82G1Ga3.mnbcj.cn
http://uc95c8L9.mnbcj.cn
http://c6qwBjKo.mnbcj.cn
http://yP5zgb1z.mnbcj.cn
http://B6aBuW0K.mnbcj.cn
http://dptcsbHA.mnbcj.cn
http://H1ALRKWc.mnbcj.cn
http://BfsnJrSj.mnbcj.cn
http://BcCNKqpS.mnbcj.cn
http://HYGlPqnZ.mnbcj.cn
http://rOItogbU.mnbcj.cn
http://ljv6lbEV.mnbcj.cn
http://JXQpxEsk.mnbcj.cn
http://vdQosKEP.mnbcj.cn
http://VfsQE9Fg.mnbcj.cn
http://1b70hZG9.mnbcj.cn
http://vte0CfIw.mnbcj.cn
http://y2KauKe5.mnbcj.cn
http://buE7uIAW.mnbcj.cn
http://blLRgSek.mnbcj.cn
http://XoGZKlJp.mnbcj.cn
http://www.dtcms.com/a/386555.html

相关文章:

  • 【Nginx开荒攻略】从命令到实战:Nginx服务启动、停止与重载完全指南
  • Ubuntu系统中在线安装MySQL到指定目录
  • C++工程实战入门笔记16-智能指针
  • 【深度学习新浪潮】什么是太空算力中心?
  • 容器化部署之dockercompose08
  • 卷积神经网络搭建实战(一)——torch云端的MNIST手写数字识别(全解二)
  • [deepseek]Visual Studio 2022创建和使用DLL教程
  • k8s节点网络失联后会发生什么
  • 3分钟掌握C++/Lua双向通信:一个高性能内核 + N个动态脚本
  • Spring MVC小点
  • SpringBoot的自动配置原理
  • 动力电池组半自动生产线:效率与灵活性的平衡之道|深圳比斯特自动化
  • 前端开发编辑器有哪些?常用前端开发编辑器推荐、前端开发编辑器对比与最佳实践分析
  • 【Linux】自动化构建工具——make/Makefile
  • Playwright MCP浏览器自动化教程
  • Linux 内存管理章节十四:多核世界的交通规则:深入Linux内存屏障与并发控制
  • .NET Core 中生成 JWT(JSON Web Token)
  • webRTc 为何深受直播实现的青睐?
  • iOS App 卡顿与性能瓶颈排查实战 如何定位CPU内存GPU帧率问题、优化耗电与网络延迟(uni-app开发性能优化全流程指南)
  • Tomcat的基本配置
  • Delphi6中实现PDF文件打印功能
  • 工作笔记-----基于FreeRTOS的lwIP网络任接收过程,从MAC至协议栈
  • ZipVoice小米语音合成-MacOS可运行
  • 技术驱动学术论文写作创新:以智能工具高效生成论文提纲为例
  • (笔记)进程间通讯
  • 电力行业数字化——解读麦肯锡企业数据架构数据治理架构设计规划【附全文阅读】
  • 如何搭建redis集群(docker方式非哨兵)
  • AWS Free Tier 2.0深度技术解析与实战指南
  • 深度学习-PyTorch基本使用
  • 飞书智能查询机器人搭建说明文档