What’s happening is that your tool is defined as an async generator (because of yield
inside async def
), so it doesn’t return a single value. Instead, it streams multiple values over time. On the client side, call_tool
doesn’t automatically unwrap and consume that stream for you — you need to iterate over it.
Here’s how you can consume the streamed tokens:
result_stream = await self.session.call_tool(
function_call.name,
arguments=dict(function_call.args)
)
# `result_stream` is async iterable — loop through it
async for event in result_stream:
for item in event.content:
if item.text:
print(item.text, end="", flush=True)
This way, each yielded chunk
from your MCP tool will show up on the client as a separate event, and you can print them in real time as they arrive.
If you just call result.content[0].text
, you’re only looking at the first chunk, which explains why you saw the async generator object string.