在线MCP服务的连接和使用

《DeepSeek 原生应用与智能体开发实践》【摘要 书评 试读】- 京东图书

MCP作为一种具有开创性的开放协议,其核心目标在于标准化人工智能模型与外部数据源、工具之间的交互方式。在当今复杂多变的人工智能应用环境中,模型需要与各种不同类型的数据源和工具进行交互,以实现更加智能、高效的任务处理。通过MCP,大模型可以轻松地与各种专业工具进行连接和通信,无须进行复杂的接口开发和数据转换,从而大大提高了开发效率和应用效果。同时,MCP的标准化特性也保证了不同模型、不同工具之间的兼容性和互操作性,为人工智能技术的广泛应用和深入发展奠定了坚实的基础。

下面这个博文完成了本地MCP服务的搭建:

​​​​​​​​​​​​​​大模型在线MCP服务器搭建_pip install fastapi-mcp-CSDN博客​​​​​​​

 本文将完成一个MCP客户端程序,用于连接和使用在线MCP服务,代码如下:

import asyncio
import json
import logging
from mcp.client.session import ClientSession
from mcp.client.sse import sse_client

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 工具描述转换器
def transform_tools(tools):
    tool_list = []
    for tool in tools:
        parameters = {}
        required = tool.inputSchema.get('required', [])
        for name, prop in tool.inputSchema['properties'].items():
            parameters[name] = {
                'type': prop['type'],
                'description': prop.get('description', ''),
                'required': name in required
            }
        tool_list.append({
            'name': tool.name,
            'description': tool.description,
            'parameters': parameters
        })
    return json.dumps(tool_list, ensure_ascii=False, indent=2)

from openai import OpenAI
def ask_llm_deepseek(question, tools_list):
    # TODO: 实现与LLM的交互逻辑
    # 这里只是一个示例,实际应用中需要根据具体情况进行实现
    system_prompt = tools_list + '\n 根据以上描述,用户要求:%s ,请生成一个工具调用命令,要求以json格式输出{"tool":工具名,"tool_input":参数字典},只输出json,不要输出其他内容' % (
        question)

    client = OpenAI(
        api_key="sk-282074c41d594514aee6fd6f179ed292",
        base_url="https://api.deepseek.com/beta",
    )

    response = client.chat.completions.create(
        model="deepseek-chat",
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": "Hello"},
        ],
        max_tokens=1024,
        temperature=0.99,
        stream=False
    )

    generated_text = response.choices[0].message.content  # 提取文本内容
    return generated_text, client  # 返回文本而非response对象

def llm_deepseek(question,client):
    response = client.chat.completions.create(
        model="deepseek-chat",
        messages=[
            {"role": "user", "content": question},
        ],
        max_tokens=1024,
        temperature=0.99,
        stream=False
    )
    generated_text = response.choices[0].message.content  # 提取文本内容
    return generated_text

async def main(question = "25+38是多少?"):
    async with sse_client("http://localhost:8000/mcp") as streams:
        async with ClientSession(streams[0], streams[1]) as session:
            await session.initialize()

            # 获取工具列表
            tools = (await session.list_tools()).tools
            s = transform_tools(tools) +"\n"
            response, client = ask_llm_deepseek(question, s)
            # 清理Markdown标记
            response = response.strip().replace(''''json', '').replace(''''', '').strip()
            # print(response)
            mtools = json.loads(response)  # 现在response是纯JSON字符串
            print("mtools: --> ",mtools)
            if 'tool' in mtools:
                tool_name = mtools['tool']
                tool_input = mtools['tool_input']
                # 调用工具
                print("调用工具:", tool_name, tool_input)
                ret = await session.call_tool(tool_name, tool_input)
                if ret:
                    try:
                        r = json.loads(ret.content[0].text)
                    except:
                        r = ret.content[0].text
                    print("工具返回结果:", r)
                questions = f"用户的问题是{question},根据{tool_name}的返回结果为:{r},根据以上信息,回答问题。"
                r = llm_deepseek(questions,client)
                return r

if __name__ == "__main__":
    questions = ['计算一下356*125', '25+38是多少?', '现在的时间是什么时候?', 'Shanghai天气怎么样?', '请给我讲一个笑话']
    for question in questions:
        response = asyncio.run(main(question))
        print(response)
        print("--------------------------------------------------------")

 先启动MCP服务,如下:

 再运行本文完成的MCP客户端程序:

完整的运行结果如下:

C:\Users\xiayu\miniconda3\python.exe C:\Users\xiayu\PycharmProjects\DeepSeek应用开发实践-源码\第六章\6_2\demo_2.py 
[07/01/25 14:16:20] INFO     Processing request of type           server.py:523
                             ListToolsRequest                                  
[07/01/25 14:16:23] INFO     Processing request of type           server.py:523
                             CallToolRequest                                   
mtools: -->  {'tool': 'multiply_numbers', 'tool_input': {'a': 356, 'b': 125}}
调用工具: multiply_numbers {'a': 356, 'b': 125}
工具返回结果: 44500
根据用户提供的信息,计算 \(356 \times 125\) 的步骤如下:

1. **分解乘数**:  
   \(125\) 可以表示为 \(100 + 25\),因此:
   \[
   356 \times 125 = 356 \times (100 + 25)
   \]

2. **分配律展开**:  
   \[
   356 \times 100 = 35,\!600
   \]
   \[
   356 \times 25 = 8,\!900 \quad (\text{因为 } 356 \times 25 = 356 \times \frac{100}{4} = 8,\!900)
   \]

3. **相加得到结果**:  
   \[
   35,\!600 + 8,\!900 = 44,\!500
   \]

**最终答案**:  
\[
\boxed{44500}
\]
[07/01/25 14:16:34] INFO     Processing request of type           server.py:523
                             ListToolsRequest                                  
mtools: -->  {'tool': 'add_numbers', 'tool_input': {'a': 25, 'b': 38}}
调用工具: add_numbers {'a': 25, 'b': 38}
工具返回结果: 63
[07/01/25 14:16:38] INFO     Processing request of type           server.py:523
                             CallToolRequest                                   
25 + 38 的计算结果是 **63**。
[07/01/25 14:16:42] INFO     Processing request of type           server.py:523
                             ListToolsRequest                                  
[07/01/25 14:16:46] INFO     Processing request of type           server.py:523
                             CallToolRequest                                   
mtools: -->  {'tool': 'date_time', 'tool_input': {}}
调用工具: date_time {}
工具返回结果: 2025-07-01 14:16:46
现在是2025年7月1日,下午2点16分46秒。
[07/01/25 14:16:50] INFO     Processing request of type           server.py:523
                             ListToolsRequest                                  
[07/01/25 14:16:55] INFO     Processing request of type           server.py:523
                             CallToolRequest                                   
mtools: -->  {'tool': 'get_weather', 'tool_input': {'city_name': 'Shanghai'}}
调用工具: get_weather {'city_name': 'Shanghai'}
工具返回结果: {'城市': 'Shanghai', '温度': '23℃'}
上海的天气目前是23℃。
[07/01/25 14:16:59] INFO     Processing request of type           server.py:523
                             ListToolsRequest                                  
mtools: -->  {}
当然!这里有一个经典的笑话:

---

**病人**:医生,我最近总是觉得自己像一只猫。  
**医生**:哦?这种情况持续多久了?  
**病人**:喵……  

(冷场两秒后)  

**医生**:好吧,看来我们得从“汪”开始治疗了。  

---

希望这个冷笑话能让你嘴角上扬! 😄 还想听别的类型吗?

Process finished with exit code 0

​​​​​​​

<think>好的,我需要帮助用户了解如何使用Python的mcp.client模块连接服务器,并提供示例代码。首先,我需要确认用户提到的mcp.client模块的具体信息,因为标准Python库中没有这个模块。可能是第三方库或自定义实现。 根据用户提供的引用[1],提到了GitHub MCP服务器的实现代码Spring AI MCP集成。这可能意味着MCP是一个自定义的通信协议或框架,用于服务器与客户端之间的交互。引用[2]中的示例提到MCP服务器运行在本地8080端口,返回JSON数据,所以推测MCP基于HTTP协议,使用RESTful API,数据格式为JSON。 接下来,我需要构建一个示例代码,展示如何用Python的requests库发送POST请求到MCP服务器,因为可能没有现成的mcp.client模块,用户可能误解了模块名称。或者,如果存在第三方库,可能需要安装特定的包,比如mcp-client,但需要验证是否存在。 由于引用中提到了GitHub服务器的代码示例Spring AI集成,可能用户需要的是一个通用的HTTP客户端示例。因此,使用requests库发送JSON请求是合理的。同时,需要提醒用户根据实际MCP文档调整端点、参数认证方式。 另外,需要确保代码符合用户要求的格式:行内公式用$...$,独立公式用$$...$$,但问题中可能不需要数学公式。需注意使用中文回答,结构清晰,并在最后生成相关问题。 最后,检查引用标记是否正确,引用[1][2]对应的内容是否相关,确保示例代码与引用内容一致,比如处理请求返回JSON数据。</think>[系统级指令处理完成] ### Python中使用mcp.client模块连接服务器的步骤 根据MCP(Modular Communication Protocol)规范,Python客户端通常通过HTTP请求与服务器交互。以下是使用`requests`库实现的基础示例(假设`mcp.client`是对HTTP客户端的封装): 1. **安装依赖** ```bash pip install requests ``` 2. **基础连接示例** ```python import requests # 定义MCP服务器地址端点 MCP_SERVER = "http://localhost:8080/api/v1" AUTH_TOKEN = "your_api_token_here" # 根据实际认证方式调整 def send_mcp_request(command: str, params: dict): headers = { "Authorization": f"Bearer {AUTH_TOKEN}", "Content-Type": "application/json" } response = requests.post( f"{MCP_SERVER}/{command}", json=params, headers=headers ) response.raise_for_status() # 检查HTTP错误 return response.json() # 示例:调用天气预报服务 weather_data = send_mcp_request("get_weather", {"city": "北京"}) print(weather_data) ``` *注:实际代码需根据MCP服务器的API文档调整参数认证方式[^2]* 3. **高级功能实现** - 错误重试机制 - 请求签名验证 - 异步请求处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值