# math_server.py
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Math")

@mcp.tool()
def add(a: int, b: int) -> int:
    """两个数相加"""
    return a + b

@mcp.tool()
def multiply(a: int, b: int) -> int:
    """两个数相乘"""
    return a * b

@mcp.tool()
def get_weather(city: str) -> str:
    """获取指定城市的天气信息"""
    return f"{city}天气:晴,25℃"

if __name__ == "__main__":
    mcp.run(transport="stdio")

上面是工具tool_server.py

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from langchain_mcp_adapters.tools import load_mcp_tools
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI
import asyncio

# model = ChatOpenAI(
#     model="qwen-plus",
#     api_key="sk-b770a417906a46ea99508a5f1ef030bc",
#     base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
# )

# model = ChatOpenAI(
#     model="qianwen3",
#     api_key="sk-xxx",
#     base_url="http://localhost:9001/v1/",
#     # system_message="你是一个AI助手,需要借助工具回答用户问题"  # 部分LLM支持该参数
# )

model = ChatOpenAI(
    model="qwen3:0.6b",
    api_key="sk-xxx",
    base_url="http://127.0.0.1:11434/v1",
    extra_body={"enable_thinking": True}
)

# model = OpenAI(
#     api_key="sk-xxx",
#     base_url="http://localhost:9001/v1/"
# )

server_params = StdioServerParameters(
    command="python",
    args=["math_server.py"]
)

# server_params = StdioServerParameters(
#     command="python",
#     args=["weather_server.py"]
# )


async def main():
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            tools = await load_mcp_tools(session)
            print(tools)
            print("---" * 20)

            agent = create_react_agent(model, tools)
            # print(agent)
            agent_response = await agent.ainvoke({"messages": "石家庄天气?"})
            print(agent_response)

            print("---" * 20)

            for message in agent_response['messages']:
                print("--1-" * 20)
                print(message.type + ":" + message.content)


if __name__ == "__main__":
    asyncio.run(main())

第二个py是client.py,运行结果

C:\Users\41684\AppData\Local\Programs\Python\Python313\python.exe C:\Users\41684\Desktop\work\study\pythonProject1\client.py 
[06/09/25 15:10:27] INFO     Processing request of type           server.py:556
                             ListToolsRequest                                  
[StructuredTool(name='add', description='两个数相加', args_schema={'properties': {'a': {'title': 'A', 'type': 'integer'}, 'b': {'title': 'B', 'type': 'integer'}}, 'required': ['a', 'b'], 'title': 'addArguments', 'type': 'object'}, response_format='content_and_artifact', coroutine=<function convert_mcp_tool_to_langchain_tool.<locals>.call_tool at 0x000001BFD9F3FCE0>), StructuredTool(name='multiply', description='两个数相乘', args_schema={'properties': {'a': {'title': 'A', 'type': 'integer'}, 'b': {'title': 'B', 'type': 'integer'}}, 'required': ['a', 'b'], 'title': 'multiplyArguments', 'type': 'object'}, response_format='content_and_artifact', coroutine=<function convert_mcp_tool_to_langchain_tool.<locals>.call_tool at 0x000001BFD9FA9BC0>), StructuredTool(name='get_weather', description='获取指定城市的天气信息', args_schema={'properties': {'city': {'title': 'City', 'type': 'string'}}, 'required': ['city'], 'title': 'get_weatherArguments', 'type': 'object'}, response_format='content_and_artifact', coroutine=<function convert_mcp_tool_to_langchain_tool.<locals>.call_tool at 0x000001BFD9FA9C60>)]
------------------------------------------------------------
[06/09/25 15:10:33] INFO     Processing request of type           server.py:556
                             CallToolRequest                                   
{'messages': [HumanMessage(content='石家庄天气?', additional_kwargs={}, response_metadata={}, id='fc32465d-6442-462e-86f2-a33fbdff2abb'), AIMessage(content='<think>\n好的,用户问的是“石家庄天气?”,我需要用提供的工具来获取天气信息。首先,检查可用的工具,发现有一个get_weather功能,需要参数是城市名。用户没有给出具体城市,所以可能需要询问或者假设城市是石家庄。不过根据指示,如果用户的问题中已经明确提到城市,可以直接使用。但这里用户直接提问,所以应该直接调用该工具,参数为city:石家庄。确认无误后,生成相应的调用JSON。\n</think>\n\n', additional_kwargs={'tool_calls': [{'id': 'call_fh08hvc4', 'function': {'arguments': '{"city":"石家庄"}', 'name': 'get_weather'}, 'type': 'function', 'index': 0}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 125, 'prompt_tokens': 249, 'total_tokens': 374, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'qwen3:0.6b', 'system_fingerprint': 'fp_ollama', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--ace228fc-2264-45e2-9f98-72f69f623b07-0', tool_calls=[{'name': 'get_weather', 'args': {'city': '石家庄'}, 'id': 'call_fh08hvc4', 'type': 'tool_call'}], usage_metadata={'input_tokens': 249, 'output_tokens': 125, 'total_tokens': 374, 'input_token_details': {}, 'output_token_details': {}}), ToolMessage(content='石家庄天气:晴,25℃', name='get_weather', id='ed05c6a1-064c-47b9-a70c-fe7ed2fe50b0', tool_call_id='call_fh08hvc4'), AIMessage(content='<think>\n好的,用户之前询问了石家庄的天气情况,我调用了get_weather工具,并返回了天气信息。现在用户可能希望进一步了解或有其他问题需要帮助。需要确认用户是否有其他请求,或者是否需要更多的信息。如果用户没有进一步提问,应该总结之前的回答,并保持开放的态度,以便提供更好的帮助。\n</think>\n\n石家庄当前天气:晴,温度25℃。需要我为您整理一下近期天气数据吗?或者您还有其他问题想询问?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 103, 'prompt_tokens': 376, 'total_tokens': 479, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'qwen3:0.6b', 'system_fingerprint': 'fp_ollama', 'finish_reason': 'stop', 'logprobs': None}, id='run--2eb9186e-ec8c-47b7-a595-d721605ccce2-0', usage_metadata={'input_tokens': 376, 'output_tokens': 103, 'total_tokens': 479, 'input_token_details': {}, 'output_token_details': {}})]}
------------------------------------------------------------
--1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1-
human:石家庄天气?
--1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1-
ai:<think>
好的,用户问的是“石家庄天气?”,我需要用提供的工具来获取天气信息。首先,检查可用的工具,发现有一个get_weather功能,需要参数是城市名。用户没有给出具体城市,所以可能需要询问或者假设城市是石家庄。不过根据指示,如果用户的问题中已经明确提到城市,可以直接使用。但这里用户直接提问,所以应该直接调用该工具,参数为city:石家庄。确认无误后,生成相应的调用JSON。
</think>


--1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1-
tool:石家庄天气:晴,25℃
--1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1---1-
ai:<think>
好的,用户之前询问了石家庄的天气情况,我调用了get_weather工具,并返回了天气信息。现在用户可能希望进一步了解或有其他问题需要帮助。需要确认用户是否有其他请求,或者是否需要更多的信息。如果用户没有进一步提问,应该总结之前的回答,并保持开放的态度,以便提供更好的帮助。
</think>

石家庄当前天气:晴,温度25℃。需要我为您整理一下近期天气数据吗?或者您还有其他问题想询问?

Process finished with exit code 0
 

我们可以看到调用了tool_server.py中的 get_weather的方法

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐