When running a ChatAgent that includes MCP-based tools inside DevUI, the app cannot serialize streamed events and the web UI crashes.
Symptoms
-
Agent + MCP tools run fine in a console app (asyncio-based loop).
-
Using DevUI:
Direct use of serve(entities=[agent], ...) fails because MCP tools require asynchronous setup (async with).
Manually running via uvicorn keeps the tool connected but causes runtime errors:
Error in streaming execution: Unable to serialize unknown type: <class 'agent_framework._types.TextContent'>
The browser UI then goes black. Console shows:
Uncaught TypeError: can't access property "replace", e.type is undefined
Reproduce it using MCPStreamableHTTPTool
import asyncio, os, uvicorn
from dotenv import load_dotenv
from agent_framework import ChatAgent, MCPStreamableHTTPTool
from agent_framework.openai import OpenAIChatClient
from agent_framework_devui import DevServer
load_dotenv()
async def main():
chat_client = OpenAIChatClient(
base_url=os.getenv("OPENAI_API_BASE", "http://localhost:12434/engines/llama.cpp/v1"),
api_key=os.getenv("OPENAI_API_KEY", "none"),
model_id=os.getenv("MODEL_ID", "ai/gpt-oss:latest"),
)
async with MCPStreamableHTTPTool(
name="Local Gateway",
url="http://localhost:8811/mcp",
chat_client=chat_client,
) as mcp:
agent = ChatAgent(
chat_client=chat_client,
name="ResearchAgent",
instructions="Sense → Plan → Act → Reflect using available MCP tools.",
tools=list(mcp.functions),
)
server = DevServer(host="0.0.0.0", port=8000, ui_enabled=True)
server.register_entities([agent])
app = server.get_app()
config = uvicorn.Config(app, host="0.0.0.0", port=8000, log_level="info", loop="asyncio")
await uvicorn.Server(config).serve()
if __name__ == "__main__":
try:
loop = asyncio.get_event_loop()
if loop.is_running():
loop.create_task(main())
else:
loop.run_until_complete(main())
except RuntimeError:
asyncio.run(main())
A simple request, that involves tool usage results in serialization errors (in the response event, not the function call) and a blank UI.
Root Cause
After digging a bit I've found that:
-
DevServer._stream_execution() assumes that every event yielded by executor.execute_streaming() is either:
- a
dict, or
- an object with
.model_dump_json() or .to_json()
Which, at the end, means it cannot handle native content types like TextContent, FunctionResultContent, etc.
-
MCP tools emit those structured Content objects directly in the stream --> so serialization fails.
-
The frontend then receives malformed Server-Sent Events, crashes at e.type.replace(...).
Expected Behavior
DevUI should gracefully serialize all official agent_framework._types.* content classes emitted during streaming (TextContent, FunctionCallContent, FunctionResultContent, etc.).
- MCP-based tools (
MCPStdioTool, MCPStreamableHTTPTool) should be usable within DevUI just like any other tool.
- The documented entrypoint,
serve(entities=[agent], port=8000, auto_open=True), should work even when the agent requires asynchronous MCP tool initialization.
Workarounds Attempted
- Wrapping MCP initialization in
async with and manually launching a Uvicorn server allows the MCP tool to connect, but the DevUI stream, as shown in the above repro sample, but it still fails with:
Error in streaming execution: Unable to serialize unknown type: <class 'agent_framework._types.TextContent'>
-
I attempted to patch _stream_execution() with a custom serializer to handle known content classes, with something like:
if isinstance(event, TextContent):
payload = json.dumps({"type": "text", "text": event.text})
and later with more complete version, similar to:
class DevUIPatch:
@staticmethod
async def stream_execution(self, executor, request):
async for event in executor.execute_streaming(request):
payload = json.dumps(DevUIPatch.safe_json(event))
yield f"data: {payload}\n\n"
However, this still fails, as even with recursive handling, TextContent objects remain non-serializable under Pydantic’s internal JSON logic:
serialization failed: Object of type TextContent is not JSON serializable
The browser console confirms the client receives malformed SSE messages, triggering:
Uncaught TypeError: can't access property "replace", e.type is undefined
This effectively means DevUI doesn’t support MCP workflows yet, even though they work correctly in pure console agents.
No.
Do not ask if it’s a misinterpretation — that weakens the signal. You’ve done the groundwork, reproduced it cleanly, and traced the cause. This is clearly an unhandled type serialization defect and a missing async-init path.
The correct closing tone for this issue should be confident but collaborative. Add only a short final section like:
Question / Clarification
Could you confirm whether MCP-based tools are currently expected to work within agent_framework_devui?
From the behavior and _stream_execution implementation, it seems MCP support isn’t yet integrated into DevUI’s streaming or serialization flow.
I’m happy to provide a minimal repro repo or patch proposal if this is indeed a missing feature.
When running a
ChatAgentthat includes MCP-based tools inside DevUI, the app cannot serialize streamed events and the web UI crashes.Symptoms
Agent + MCP tools run fine in a console app (
asyncio-based loop).Using DevUI:
Direct use of
serve(entities=[agent], ...)fails because MCP tools require asynchronous setup (async with).Manually running via
uvicornkeeps the tool connected but causes runtime errors:Error in streaming execution: Unable to serialize unknown type: <class 'agent_framework._types.TextContent'>The browser UI then goes black. Console shows:
Uncaught TypeError: can't access property "replace", e.type is undefinedReproduce it using MCPStreamableHTTPTool
A simple request, that involves tool usage results in serialization errors (in the response event, not the function call) and a blank UI.
Root Cause
After digging a bit I've found that:
DevServer._stream_execution()assumes that every event yielded byexecutor.execute_streaming()is either:dict, or.model_dump_json()or.to_json()Which, at the end, means it cannot handle native content types like
TextContent,FunctionResultContent, etc.MCP tools emit those structured
Contentobjects directly in the stream --> so serialization fails.The frontend then receives malformed Server-Sent Events, crashes at
e.type.replace(...).Expected Behavior
DevUIshould gracefully serialize all officialagent_framework._types.*content classes emitted during streaming (TextContent,FunctionCallContent,FunctionResultContent, etc.).MCPStdioTool,MCPStreamableHTTPTool) should be usable withinDevUIjust like any other tool.serve(entities=[agent], port=8000, auto_open=True), should work even when the agent requires asynchronous MCP tool initialization.Workarounds Attempted
async withand manually launching aUvicornserver allows the MCP tool to connect, but the DevUI stream, as shown in the above repro sample, but it still fails with:Error in streaming execution: Unable to serialize unknown type: <class 'agent_framework._types.TextContent'>I attempted to patch
_stream_execution()with a custom serializer to handle known content classes, with something like:and later with more complete version, similar to:
However, this still fails, as even with recursive handling,
TextContentobjects remain non-serializable under Pydantic’s internal JSON logic:serialization failed: Object of type TextContent is not JSON serializableThe browser console confirms the client receives malformed SSE messages, triggering:
Uncaught TypeError: can't access property "replace", e.type is undefinedThis effectively means DevUI doesn’t support MCP workflows yet, even though they work correctly in pure console agents.
No.
Do not ask if it’s a misinterpretation — that weakens the signal. You’ve done the groundwork, reproduced it cleanly, and traced the cause. This is clearly an unhandled type serialization defect and a missing async-init path.
The correct closing tone for this issue should be confident but collaborative. Add only a short final section like:
Question / Clarification
Could you confirm whether MCP-based tools are currently expected to work within
agent_framework_devui?From the behavior and
_stream_executionimplementation, it seems MCP support isn’t yet integrated into DevUI’s streaming or serialization flow.I’m happy to provide a minimal repro repo or patch proposal if this is indeed a missing feature.