-
Notifications
You must be signed in to change notification settings - Fork 818
Description
Prerequisites
- Search the current open issues
Question
I'm encountering an error when trying to use the ToolboxClient from toolbox_langchain in an async application with LangGraph and LangChain.
Why am I getting the error that 'ToolboxClient' object does not support the asynchronous context manager protocol?
Configuration:
OS: Windows
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x000001EC998FEF90>
Traceback (most recent call last):
File "d:\2025.7\mcp toolbox\langchain_.py", line 55, in
asyncio.run(run_application())
File "D:\Program Files\miniconda\envs\langchain\Lib\asyncio\runners.py", line 195, in run
return runner.run(main)
File "D:\Program Files\miniconda\envs\langchain\Lib\asyncio\runners.py", line 118, in run
return self.loop.run_until_complete(task)
File "D:\Program Files\miniconda\envs\langchain\Lib\asyncio\base_events.py", line 725, in run_until_complete
return future.result()
File "d:\2025.7\mcp toolbox\langchain.py", line 44, in run_application
async with ToolboxClient("http://127.0.0.1:5000") as client:
TypeError: 'ToolboxClient' object does not support the asynchronous context manager protocol
Code
My tools.yaml configuration:
sources:
my-mysql-source:
kind: mysql
host: 127.0.0.1
port: 3306
database: tool
user: root1
password: 2152911111
tools:
search-hotels-by-name:
kind: mysql-sql
source: my-mysql-source
description: Search for hotels based on name.
parameters:
- name: name
type: string
description: The name of the hotel.
statement: SELECT * FROM hotels WHERE name LIKE CONCAT('%', ?, '%');
search-hotels-by-location:
kind: mysql-sql
source: my-mysql-source
description: Search for hotels based on location.
parameters:
- name: location
type: string
description: The location of the hotel.
statement: SELECT * FROM hotels WHERE location LIKE CONCAT('%', ?, '%');
book-hotel:
kind: mysql-sql
source: my-mysql-source
description: Book a hotel by its ID.
parameters:
- name: hotel_id
type: string
description: The ID of the hotel to book.
statement: UPDATE hotels SET booked = 1 WHERE id = ?;
update-hotel:
kind: mysql-sql
source: my-mysql-source
description: Update a hotel's check-in and check-out dates by its ID.
parameters:
- name: hotel_id
type: string
description: The ID of the hotel to update.
- name: checkin_date
type: string
description: The new check-in date of the hotel.
- name: checkout_date
type: string
description: The new check-out date of the hotel.
statement: UPDATE hotels SET checkin_date = DATE(?), checkout_date = DATE(?) WHERE id = ?;
cancel-hotel:
kind: mysql-sql
source: my-mysql-source
description: Cancel a hotel by its ID.
parameters:
- name: hotel_id
type: string
description: The ID of the hotel to cancel.
statement: UPDATE hotels SET booked = 0 WHERE id = ?;
toolsets:
my-toolset:
- search-hotels-by-name
- search-hotels-by-location
- book-hotel
- update-hotel
- cancel-hotel
Additional Details
code:
import os
import asyncio
from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import MemorySaver
from toolbox_langchain import ToolboxClient
from langchain_openai import ChatOpenAI
prompt = """
You're a helpful hotel assistant. You handle hotel searching, booking and
cancellations. When the user searches for a hotel, mention it's name, id,
location and price tier. Always mention hotel ids while performing any
searches. This is very important for any operations. For any bookings or
cancellations, please provide the appropriate confirmation. Be sure to
update checkin or checkout dates if mentioned by the user.
Don't ask for confirmations from the user.
"""
queries = [
"Find hotels in Basel with Basel in it's name.",
"Can you book the Hilton Basel for me?",
"Oh wait, this is too expensive. Please cancel it and book the Hyatt Regency instead.",
"My check in dates would be from April 10, 2024 to April 19, 2024.",
]
async def run_application():
model = ChatOpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1 ",
model="qwen-plus",
)
async with ToolboxClient("http://127.0.0.1:5000") as client:
tools = await client.aload_toolset()
agent = create_react_agent(model, tools, checkpointer=MemorySaver())
config = {"configurable": {"thread_id": "thread-1"}}
for query in queries:
inputs = {"messages": [("user", prompt + query)]}
response = agent.invoke(inputs, stream_mode="values", config=config)
print(response["messages"][-1].content)
asyncio.run(run_application())