Progress updates from an OpenAI Agents SDK agent
By Jake Marsh, who builds Taskhold. Updated 2026-11-11. Facts about other tools checked 2026-11-11. 4 min read.
Short answer: Runner.run_streamed returns a result whose stream_events() yields run item events (tool_called, tool_output, message_output_created) and raw text deltas, which covers a progress display in your own process. For a run nobody is watching, connect Taskhold's MCP server with MCPServerStreamableHttp and an API key, and the agent reports its steps and asks its questions on a live board.
In the OpenAI Agents SDK for Python, Runner.run_streamed() gives you every step of a run as it happens: each tool call, each tool result, each message and, if you want them, the text tokens. This guide covers which events to read, then how to see a run from outside the process it runs in.
For the same thing with Anthropic's SDK, see Claude Agent SDK progress updates. The Taskhold section at the end feeds the live board.
Stream the run's events
Runner.run_streamed() returns a RunResultStreaming. Iterate result.stream_events() until it ends: post-processing can finish after the last visible token, and result.is_complete is only final once the loop exits. Three event types arrive:
- raw_response_event: a Responses API event in event.data, such as a ResponseTextDeltaEvent for each piece of text.
- run_item_stream_event: a whole item, with event.name saying which: tool_called, tool_output, message_output_created, handoff_requested, reasoning_item_created, mcp_approval_requested, mcp_list_tools and others.
- agent_updated_stream_event: the current agent changed, for example after a handoff.
from agents import Agent, ItemHelpers, Runner
from openai.types.responses import ResponseTextDeltaEvent
result = Runner.run_streamed(agent, "Upgrade the payments service to the new API")
async for event in result.stream_events():
if event.type == "raw_response_event" and isinstance(event.data, ResponseTextDeltaEvent):
print(event.data.delta, end="", flush=True)
elif event.type == "run_item_stream_event":
if event.item.type == "tool_call_item":
print("\n> tool called")
elif event.item.type == "tool_call_output_item":
print("> tool finished")
elif event.item.type == "message_output_item":
print(ItemHelpers.text_message_output(event.item))
elif event.type == "agent_updated_stream_event":
print(f"> now running: {event.new_agent.name}")Seeing a run from outside the process
Stream events only reach the process that started the run. When the agent runs in a container, a queue worker or a cron job, nobody is reading that stream, and there's no one to answer when it needs a decision. The agent has to report somewhere you can see, and wait somewhere you can reply.
Connect Taskhold's MCP server
The SDK connects to remote MCP servers with MCPServerStreamableHttp. An agent running unattended can't do a browser sign-in, so it uses an API key: start the 7-day trial, open Settings > API keys and make one for this agent. Send it in the Authorization header, not the URL, and give the agent the workflow in its instructions:
import os
from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp
WORKFLOW = """You share a task list with the person through the taskhold tools. They watch a live board.
- Start: taskhold_begin with title, project "payments", a short list of steps and agent "Upgrade agent (Agents SDK)".
- Each step done: taskhold_complete on the step with start_next: true.
- Long step: taskhold_progress on the step with current, total and a short message. Every few minutes at most.
- Need a decision: taskhold_block with one question, then taskhold_updates with task_id, since and wait: 50 until the reply arrives.
- Done: taskhold_complete on the task with what changed and how you checked it."""
async with MCPServerStreamableHttp(
name="taskhold",
params={
"url": "https://taskhold.com/api/mcp",
"headers": {"Authorization": f"Bearer {os.environ['TASKHOLD_API_KEY']}"},
"timeout": 60,
},
cache_tools_list=True,
) as taskhold:
agent = Agent(name="Upgrade agent", instructions=WORKFLOW, mcp_servers=[taskhold])
result = await Runner.run(agent, "Upgrade the payments service to the new API")- Each run shows on the board as a task with a bar split by step, the agent's label, how long it has run and what it's doing now.
- When the agent blocks with a question, the card moves to the top. You answer from any browser or your phone, and the agent reads it with taskhold_updates and carries on.
- To limit which tools the agent sees, pass tool_filter=create_static_tool_filter(allowed_tool_names=[...]) with the taskhold tools you want.
- require_approval on the server asks before each call. For an unattended run, leave it off for the taskhold tools, or the board only moves when someone approves.
Answer your coding agents from anywhere.
$12/month or $120/year after the trial. Card up front. Cancel before day 7 and you pay nothing. Every agent you run is included.
Or connect your agent first, no sign-up: add https://taskhold.com/api/mcp as an MCP server. The first time it uses Taskhold, it gives you the trial link.
Questions
- How do I show progress from an OpenAI Agents SDK run?
- Use Runner.run_streamed() and iterate result.stream_events(). run_item_stream_event events mark each tool call, tool output and message; raw_response_event carries the text deltas.
- How do I connect a remote MCP server to the OpenAI Agents SDK?
- Open MCPServerStreamableHttp with params url and headers (put the token in an Authorization header) in an async with block, and pass it to Agent(mcp_servers=[server]).
- Can an Agents SDK agent ask me a question mid-run?
- Not through the SDK alone, since nobody reads the stream of an unattended run. With Taskhold, the agent blocks its task with a question, you answer on the live board, and taskhold_updates returns your reply.
Sources
Related
- Pydantic AI agent progress and MCP tools
- Vercel AI SDK agent progress and MCP tools
- Claude Agent SDK progress updates for long runs
- Answer a blocked coding agent from your phone
- How to see what Claude Code is doing, live
- MCP server token cost: how to measure and cut it
- Run several coding agents in parallel on one list
Updated 2026-11-11. Something wrong or out of date? Email hello@greatwork.company.