No output when using generateText with structured output and MCP tools

Hi,

I’m trying to use tools from the remote GitHub MCP server together with generateText and structured output.

If I pass tools to generateText, I’m getting NoOutputGeneratedError [AI_NoOutputGeneratedError]: No output generated. error. If I don’t pass tools it seems to work (as in I’m getting an output), though I assume it’s not using GitHub MCP server in this case.

Here’s the code I have (somewhat simplified, I hope I haven’t removed any important bits):

import 'dotenv/config';

import { generateText, Output } from 'ai';
import z from 'zod';
import { experimental_createMCPClient as createMCPClient } from '@ai-sdk/mcp';
import { openai } from '@ai-sdk/openai';

const transport = {
  type: 'http',
  url: 'https://api.githubcopilot.com/mcp/',
  headers: { Authorization: process.env.GITHUB_MCP_API_KEY ?? '' },
} as const;

const client = await createMCPClient({ transport });
const tools = await client.tools();

const model = openai('gpt-5')
const schema = z.object({
  repositories: z.array(z.object({ name: z.string })),
});

const githubProfileName = 'szimek';

await generateText({
  model,
  tools,
  output: Output.object({ schema }),
  prompt: `List all repositories owned by the GitHub user "${githubProfileName}" with at least 50 stars.`,
});

The code above throws NoOutputGeneratedError. If I comment out tools , it seems to work. The tools seem to be used correctly, as I can see the tool call result and see a response from GitHub API.

I’m using the following versions:

  • @ai-sdkai-sdkai-sdkai-sdk/mcp”: “1.0.0-beta.15”
  • @ai-sdk/openai”: “3.0.0-beta.57”
  • “ai”: “6.0.0-beta.98”

EDIT: Looks like generateText parses the output only when the last step is “stop”. In my case it’s “tool-calls". Updating the relevant if statement in ai library doesn’t solve the problem, as lastStep.text is empty, so parsing (outputSpecification.parseCompleteOutput) fails.

I’m having the same exact problem, except that I’m not using an MCP and we are building the tools ourselves.

Just like you describe, I can see that the last step executed is a tool call.

Any workaround or suggestion on how to fix it will be quite appreciated

Also, I was very confusing on why my promise that had an error handler attached was failing with such error… and it happens to be that the output is not just a property, but some kind of getter that can throw an error. Why would you do such obscure thing? Haven’t you read about the principle of least surprise? If my promise went well, and I had a result, the last thing I expect is getting an error thrown because I’m accessing an existing property!