In [1]:
from dotenv import load_dotenv
load_dotenv()
Out[1]:
True
In [2]:
import os
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent
from langchain.messages import HumanMessage, AIMessage
from langchain.tools import tool
from typing import Dict, Any
from tavily import TavilyClient
from pprint import pprint
import sys
import asyncio
DEEPSEEK_MODEL = "deepseek-chat"
DEEPSEEK_BASE_URL = "https://api.deepseek.com"
def deepseek_model(model: str = DEEPSEEK_MODEL, max_tokens=1000, **kwargs):
return init_chat_model(
model=model,
# DeepSeek uses LangChain's OpenAI-compatible transport.
model_provider="openai",
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url=DEEPSEEK_BASE_URL,
max_tokens=max_tokens,
**kwargs,
)
In [3]:
# Fix for Windows issues in Jupyter notebooks
if sys.platform == "win32":
# 1. Use ProactorEventLoop for subprocess support
if not isinstance(asyncio.get_event_loop_policy(), asyncio.WindowsProactorEventLoopPolicy):
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
# 2. Redirect stderr to avoid fileno() error when launching MCP servers
if "ipykernel" in sys.modules:
sys.stderr = sys.__stderr__
In [4]:
from langchain_mcp_adapters.client import MultiServerMCPClient
In [5]:
client = MultiServerMCPClient(
{
"local_server": {
"transport":"stdio",
"command":"python",
"args":['resources/2.1_mcp_server.py']
},
"time": {
"transport":"stdio",
"command":"uvx",
"args":['mcp-server-time',"--local-timezone=Australia/Melbourne"]
}
}
)
In [6]:
# get tools from the server
tools = await client.get_tools()
# get resources
resources = await client.get_resources("local_server")
# get prompts
prompt = await client.get_prompt("local_server", "prompt")
prompt = prompt[0].content
In [7]:
pprint(tools)
print('----------------')
print(resources)
print('----------------')
print(await client.get_prompt("local_server", "prompt"))
[StructuredTool(name='search_web', description='Search the web for information', args_schema={'properties': {'query': {'title': 'Query', 'type': 'string'}}, 'required': ['query'], 'title': 'search_webArguments', 'type': 'object'}, response_format='content_and_artifact', coroutine=<function convert_mcp_tool_to_langchain_tool.<locals>.call_tool at 0x10ace2200>),
StructuredTool(name='get_current_time', description='Get current time in a specific timezones', args_schema={'type': 'object', 'properties': {'timezone': {'type': 'string', 'description': "IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'Australia/Melbourne' as local timezone if no timezone provided by the user."}}, 'required': ['timezone']}, response_format='content_and_artifact', coroutine=<function convert_mcp_tool_to_langchain_tool.<locals>.call_tool at 0x10d0316c0>),
StructuredTool(name='convert_time', description='Convert time between timezones', args_schema={'type': 'object', 'properties': {'source_timezone': {'type': 'string', 'description': "Source IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'Australia/Melbourne' as local timezone if no source timezone provided by the user."}, 'time': {'type': 'string', 'description': 'Time to convert in 24-hour format (HH:MM)'}, 'target_timezone': {'type': 'string', 'description': "Target IANA timezone name (e.g., 'Asia/Tokyo', 'America/San_Francisco'). Use 'Australia/Melbourne' as local timezone if no target timezone provided by the user."}}, 'required': ['source_timezone', 'time', 'target_timezone']}, response_format='content_and_artifact', coroutine=<function convert_mcp_tool_to_langchain_tool.<locals>.call_tool at 0x10cfdde40>)]
----------------
[Blob 4513505888]
----------------
[HumanMessage(content='\n You are a helpful assistant that answers user questions about LangChain, LangGraph and LangSmith.\n\n You can use the following tools/resources to answer user questions:\n - search_web: Search the web for information\n - github_file: Access the langchain-ai repo files\n\n If the user asks a question that is not related to LangChain, LangGraph or LangSmith, you should say "I\'m sorry, I can only answer questions about LangChain, LangGraph and LangSmith."\n\n You may try multiple tool and resource calls to answer the user\'s question.\n\n You may also ask clarifying questions to the user to better understand their question.\n ', additional_kwargs={}, response_metadata={})]
In [8]:
# get tools and prompt from MCP server
agent = create_agent(
model=deepseek_model(),
tools=tools,
system_prompt=prompt
)
In [12]:
question = HumanMessage(content="What time is it?")
response = await agent.ainvoke(
{"messages": [question]}
)
pprint(response)
{'messages': [HumanMessage(content='What time is it?', additional_kwargs={}, response_metadata={}, id='79ab1e20-4fbf-47fd-a3a1-5d0725f83454'),
AIMessage(content='I need to know your current timezone to give you an accurate answer. Let me check the current time in a common timezone, and I can also help convert if you let me know where you are.\n\nLet me start by getting the current time in my local timezone (Australia/Melbourne) and a few other common ones:', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 148, 'prompt_tokens': 707, 'total_tokens': 855, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 640}, 'prompt_cache_hit_tokens': 640, 'prompt_cache_miss_tokens': 67}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-flash', 'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402', 'id': '79cc6c16-4331-4d23-bcec-9a6eefd97f38', 'finish_reason': 'tool_calls', 'logprobs': None}, id='lc_run--019e23e7-325f-7f30-b489-1134cc81f260-0', tool_calls=[{'name': 'get_current_time', 'args': {'timezone': 'Australia/Melbourne'}, 'id': 'call_00_kWZfOBwYQG5HW7BcE4zF5647', 'type': 'tool_call'}, {'name': 'get_current_time', 'args': {'timezone': 'UTC'}, 'id': 'call_01_lhi7A1kGFh0Zios2qU4v9811', 'type': 'tool_call'}], invalid_tool_calls=[], usage_metadata={'input_tokens': 707, 'output_tokens': 148, 'total_tokens': 855, 'input_token_details': {'cache_read': 640}, 'output_token_details': {}}),
ToolMessage(content=[{'type': 'text', 'text': '{\n "timezone": "Australia/Melbourne",\n "datetime": "2026-05-14T10:33:36+10:00",\n "day_of_week": "Thursday",\n "is_dst": false\n}', 'id': 'lc_60007c77-ebc4-435a-b3b9-18e7b8c3570b'}], name='get_current_time', id='0ceaeebd-0614-4277-853a-f0d128a209c8', tool_call_id='call_00_kWZfOBwYQG5HW7BcE4zF5647'),
ToolMessage(content=[{'type': 'text', 'text': '{\n "timezone": "UTC",\n "datetime": "2026-05-14T00:33:36+00:00",\n "day_of_week": "Thursday",\n "is_dst": false\n}', 'id': 'lc_5ac2fd25-2a1f-49d9-ae72-689b2bd9d1c0'}], name='get_current_time', id='99a6d785-e41f-46dd-b0b4-5973e2ef2544', tool_call_id='call_01_lhi7A1kGFh0Zios2qU4v9811'),
AIMessage(content="Here's the current time in different timezones:\n\n| Timezone | Current Time |\n|---|---|\n| **UTC** | **00:33** (Thursday, May 14, 2026) |\n| **Australia/Melbourne** (my default) | **10:33** (Thursday, May 14, 2026) |\n\nIf you let me know **your timezone**, I can tell you the exact current time where you are! 😊", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 95, 'prompt_tokens': 975, 'total_tokens': 1070, 'completion_tokens_details': None, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 640}, 'prompt_cache_hit_tokens': 640, 'prompt_cache_miss_tokens': 335}, 'model_provider': 'openai', 'model_name': 'deepseek-v4-flash', 'system_fingerprint': 'fp_8b330d02d0_prod0820_fp8_kvcache_20260402', 'id': 'b93b9eb1-8210-4439-9e00-a6f42f62aab1', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019e23e7-3b33-7181-9d02-8851a1d8b008-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 975, 'output_tokens': 95, 'total_tokens': 1070, 'input_token_details': {'cache_read': 640}, 'output_token_details': {}})]}
In [13]:
print(response['messages'][-1].content)
Here's the current time in different timezones: | Timezone | Current Time | |---|---| | **UTC** | **00:33** (Thursday, May 14, 2026) | | **Australia/Melbourne** (my default) | **10:33** (Thursday, May 14, 2026) | If you let me know **your timezone**, I can tell you the exact current time where you are! 😊
In [ ]:
In [ ]: