Progress from a Vercel AI SDK agent, and a board to watch it on
By Jake Marsh, who builds Taskhold. Updated 2026-11-11. Facts about other tools checked 2026-11-11. 4 min read.
Short answer: In the AI SDK, a multi-step run is one generateText or streamText call with stopWhen set, for example isStepCount(5). onStepEnd fires after each step with its stepNumber, text, toolCalls and toolResults, which covers a progress log in your own process. To watch a run from anywhere, connect Taskhold's MCP server with createMCPClient from @ai-sdk/mcp and an API key, and the agent reports steps and questions to a live board.
The Vercel AI SDK runs tool-calling agents in TypeScript: the model calls a tool, the SDK runs it, and the loop goes on until a stop condition. Each pass is a step, and the SDK tells you when every step ends. This guide covers that, then how to see a run from outside the process.
Current releases renamed two things older guides use: the step limit helper is isStepCount (it was stepCountIs) and the per-step callback is onStepEnd (it was onStepFinish). The Taskhold section at the end feeds the live board.
Run several steps and log each one
A step is one model generation plus the local tools it asked for. By default generateText and streamText stop after one step (isStepCount(1)), so set stopWhen to let the agent keep going. Other stop conditions are hasToolCall(...toolNames) and isLoopFinished().
import { generateText, isStepCount } from "ai";
const { text, steps } = await generateText({
model,
tools,
stopWhen: isStepCount(10),
prompt: "Upgrade the payments service to the new API",
onStepEnd({ stepNumber, toolCalls, toolResults, finishReason }) {
console.log(`step ${stepNumber + 1}: ${toolCalls.length} tool calls, ${toolResults.length} results (${finishReason})`);
},
});
const allToolCalls = steps.flatMap((step) => step.toolCalls);prepareStep runs before each step and can change the model, toolChoice, activeTools or messages for that step, for example to force a planning tool on step 0.
Seeing a run from outside the process
onStepEnd only runs in the process that started the agent. A run in a queue worker, a serverless function or a cron job has nobody reading its logs as it goes, and no way to ask you something and wait for the answer. It needs to report somewhere you can see. The same holds for agents built on the OpenAI Agents SDK or the Claude Agent SDK.
Connect Taskhold's MCP server
createMCPClient from @ai-sdk/mcp connects to remote servers over HTTP, which the docs recommend for production. A server-side agent 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.
import { createMCPClient } from "@ai-sdk/mcp";
import { generateText, isStepCount } from "ai";
const taskhold = await createMCPClient({
transport: {
type: "http",
url: "https://taskhold.com/api/mcp",
headers: { Authorization: `Bearer ${process.env.TASKHOLD_API_KEY}` },
},
});
try {
const { text } = await generateText({
model,
tools: { ...(await taskhold.tools()), ...myTools },
stopWhen: isStepCount(40),
system: WORKFLOW,
prompt: "Upgrade the payments service to the new API",
});
} finally {
await taskhold.close();
}- Each run shows as a task on the board, 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, it waits in taskhold_updates (up to 50 s per call) while you answer from any browser or your phone. Leave room in stopWhen for those waits. More on that in answering a blocked agent.
- tools({ schemas }) loads only the tools you list, if you want the agent to see fewer of Taskhold's.
- redirect defaults to error, so use the exact URL https://taskhold.com/api/mcp: the www host redirects.
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
- Is it stepCountIs or isStepCount in the AI SDK?
- Current docs use isStepCount, for example stopWhen: isStepCount(5). The per-step callback is onStepEnd, which older guides call onStepFinish.
- How do I connect a remote MCP server to the Vercel AI SDK?
- Call createMCPClient from @ai-sdk/mcp with transport { type: "http", url, headers }, pass await client.tools() to generateText or streamText, and close the client when the response ends.
- How do I see an AI SDK agent's progress while it runs on a server?
- Log onStepEnd for your own process. To watch from anywhere and answer its questions, connect Taskhold's MCP server so the agent reports each step to a live board.
Sources
Related
Updated 2026-11-11. Something wrong or out of date? Email hello@greatwork.company.