TanStack AI Tutorial: Build a Tool-Calling Agent
A 1.0-era TanStack AI tutorial: install adapters, stream chat(), wire tool calling with maxIterations, connect MCP, and test with fakeText().

What TanStack AI is, as of November 2026
TanStack AI is the AI layer of the TanStack family of open-source JavaScript libraries. According to the TanStack AI docs, its core libraries are framework-agnostic and provider-agnostic, so you can use them with React, Vue, Svelte, Solid, Angular or plain vanilla JavaScript. TanStack libraries are MIT licensed, self-hostable and, per tanstack.com, have no paid tiers.
The platform states 18.4B total downloads and 176.7M weekly downloads, and TanStack describes its tools as built to work "reliably for agents." TanStack AI reached 1.0 on Oct 23, 2026, with stable core APIs, rewritten docs and an experimental agent harness, and its docs were still being updated on Nov 2, 2026 with MCP managed and manual pages. New adapters keep landing — OpenRouter, Cloudflare Workers AI, Azure OpenAI, TypeSafe, Ollaya and others — which is why the adapter and tool-calling parts of the docs are the freshest.
What is verified: the streaming chat() pattern, per-provider adapter packages, an agentLoopStrategy with maxIterations(20), server-sent-event response helpers, MCP tool support pages, five new sandbox providers (Blaxel, Upstash Box, E2B, boxd and Railway) and a no-network test helper called fakeText(). What you should confirm in the current docs: the exact package versions, whether agentLoopStrategy behaviour is identical for every provider, how stable the experimental harness packages are beyond being on 0.x, and whether all five modalities (image, video, audio, TTS, transcription) are stable in 1.0. No pricing page is shown anywhere, so do not assume a hosted or paid TanStack AI service exists.
Step 1: install the packages
A chat app needs three kinds of package: the framework-agnostic core, a UI binding for your framework, and one adapter per provider. The TanStack AI quick start on GitHub illustrates the pattern with @tanstack/ai, @tanstack/ai-react and @tanstack/ai-openai installed via npm, pnpm or yarn.
npm install @tanstack/ai @tanstack/ai-react @tanstack/ai-openai
# or, for the OpenRouter adapter
npm install @tanstack/ai @tanstack/ai-react @tanstack/ai-openrouterThat split is the architectural change worth understanding before you copy any snippet: adapters are imported per provider and per modality, not from one giant adapter object. The latest API docs on GitHub show openaiText coming from @tanstack/ai-openai and openRouterText from @tanstack/ai-openrouter, then passed in as the adapter option. OpenRouter reports its TanStack AI integration gives access to 400+ models across providers through one unified API, which makes it a reasonable first adapter if you expect to switch providers later.
Step 2: a streaming chat() server route
TanStack AI provides a chat() function that streams from a server route, plus a hook for your framework to render tokens as they arrive. The docs show a helper, toServerSentEventsResponse, that sets Content-Type: text/event-stream and the correct cache-control headers so the browser treats the response as an event stream.
import { chat, toServerSentEventsResponse } from "@tanstack/ai";
import { openaiText } from "@tanstack/ai-openai";
export async function POST(request: Request) {
const stream = await chat({
adapter: openaiText({ apiKey: process.env.OPENAI_API_KEY }),
messages: await request.json(),
});
return toServerSentEventsResponse(stream);
}Two caveats before you ship that: confirm the exact argument shape for chat() and your adapter in the current API reference, because the docs were revised at 1.0, and keep model and provider identifiers in environment variables rather than hard-coding a name the docs may outgrow.
Step 3: give the agent a real tool, not a toy one
Here is where most tutorials stop and most real builds begin. Tool calling only earns its keep when the tool returns data the model cannot otherwise know. Trend data is a good test case: it is time-sensitive, the model has no memory of it, and a wrong answer is visibly wrong.
TrendsAGI is a real-time trend intelligence platform that detects topics gaining attention on social platforms, measures velocity (posts per hour from stored snapshots) and growth, explains each topic with AI insights, and turns them into recommendations, crisis alerts and watchlist alerts. The REST API base URL is https://api.trendsagi.com; authenticate with X-API-Key: <key> or Authorization: Bearer <key>, and create keys in your account profile.
Be precise about what those numbers mean when the agent quotes them back: velocity is a measured snapshot rate, not a forecast or a unique-user count, and recommendation confidence measures evidence completeness, not probability of success. Say that in the tool description so the model does not overstate it.
// tools/get-trends.ts
export const getTrends = {
name: "get_trends",
description:
"List topics gaining attention right now. Returns measured snapshot velocity " +
"(posts per hour), not a forecast or unique-user count.",
parameters: {
type: "object",
properties: {
category: { type: "string" },
sort_by: { type: "string", enum: ["velocity", "growth", "volume"] },
limit: { type: "number" },
},
required: ["category"],
},
execute: async ({ category, sort_by = "velocity", limit = 5 }) => {
const params = new URLSearchParams({
category,
sort_by,
limit: String(limit),
});
const res = await fetch(
`https://api.trendsagi.com/api/trends?${params}`,
{ headers: { "X-API-Key": process.env.TRENDSAGI_API_KEY } },
);
if (!res.ok) throw new Error(`TrendsAGI ${res.status}`);
return res.json();
},
};Two more tools make the agent genuinely useful without widening your surface area: GET /api/trends/{id}/ai-insights for a summary, key themes, sentiment, audience and marketing angles, and GET /api/trends/{id}/analytics?period=7d when the reader asks whether a spike is holding. Registering both lets the model move from "what is moving" to "what does it mean" in one turn.
Step 4: the agent loop and maxIterations
A single tool call is a request-response pair. An agent is a loop: the model asks for a tool, your code runs it, the result goes back, the model decides whether to call another or answer. TanStack AI exposes that loop through the agentLoopStrategy option; the latest GitHub API docs example uses maxIterations(20).
import { chat, toServerSentEventsResponse, maxIterations } from "@tanstack/ai";
import { openaiText } from "@tanstack/ai-openai";
import { getTrends } from "./tools/get-trends";
export async function POST(request: Request) {
const { messages } = await request.json();
const stream = await chat({
adapter: openaiText({ apiKey: process.env.OPENAI_API_KEY }),
messages,
tools: [getTrends],
agentLoopStrategy: maxIterations(20),
});
return toServerSentEventsResponse(stream);
}maxIterations is your ceiling on how many model-tool round trips one request may take. Too low and a legitimate multi-step question — find the trend, pull insights, check the seven-day analytics — gets truncated mid-investigation. Too high and a confused model can burn time and tokens circling. Start at 20 as the docs suggest, then watch your logs: if most requests finish in two or three iterations, a ceiling of 8–10 is safer for production. The docs do not state whether this behaviour is identical across all providers, so verify it against the adapter you actually deploy.
Step 5: MCP tools, managed versus manual
TanStack AI's docs cover MCP server tools in three parts: managed MCP with chat(), manual MCP, and MCP type generation. The practical split is whether the framework handles the server connection for you or you hold the client yourself. Use managed MCP when you want the tool list injected into the chat call with minimal glue; use manual MCP when you need control over transport, lifecycle or per-user authorisation. Type generation exists so the MCP tool signatures reach your TypeScript code with real types rather than any — run it as a build step, not at runtime.
TrendsAGI speaks MCP in two ways that fit this step. The hosted MCP server at https://api.trendsagi.com/mcp uses Streamable HTTP with OAuth 2.1 sign-in or an API key as a Bearer token, and exposes read-only tools; each connection is its own API key and each tool call counts as one API request. Locally, pip install "trendsagi[mcp]" then trendsagi mcp with TRENDSAGI_API_KEY set gives you the same tools over stdio, and --allow-writes adds write tools. The hosted tools include list_trends, get_trend_ai_insights, get_trend_analytics, list_recommendations, list_crisis_events, list_watchlist and find_capability, which answers whether TrendsAGI can do a task and which tool or page does it.
If your app is plain JavaScript rather than Python, the REST endpoints map one-to-one onto the tool names above, so wrap them as in Step 3 and skip the MCP client entirely until you need it.
Step 6: test the tool-calling loop with no network
This is the step almost every TanStack AI tutorial skips. 1.0 includes fakeText(), which lets you test chat(), tools and middleware with no network and no API key. That means you can assert the loop behaves — the model requests get_trends, your executor runs, the result is fed back — inside CI, deterministically, for free.
For the tools themselves, separate the executor from the transport: call getTrends.execute({ category: "Technology" }) directly against a recorded response and assert it throws on a non-OK status. Then use fakeText() to script the model side. What you cannot fake is the evidence: your TrendsAGI branch should also run one scheduled check against the live API with a real key, because velocity only means something measured against real snapshots.
When not to use TanStack AI
It is MIT licensed, self-hostable and vendor-neutral, which is exactly what a team already on TanStack Start or React wants — no new vendor lock-in, one fewer runtime in the stack. The honest trade-offs: the adapters are young and unevenly documented across providers, the agent harness is experimental and its packages stay on 0.x, and the docs are still being revised (MCP pages landed Nov 2, 2026). If you need a vendor-managed agent runtime with a support SLA, this is not that product, and the docs do not describe support channels. If you need a single stable harness API today, pin your versions and read the changelog before each upgrade.
Frequently asked questions
Which packages do I install for @tanstack/ai with a specific provider adapter and a UI framework?
Install the framework-agnostic core @tanstack/ai, a binding for your framework such as @tanstack/ai-react, and one adapter package per provider such as @tanstack/ai-openai or @tanstack/ai-openrouter. The GitHub quick-start docs show the three-package pattern installed via npm, pnpm or yarn.
How do I wire a streaming chat() server route and return it as server-sent events?
Call chat() in a server route with your adapter and messages, then pass the returned stream to toServerSentEventsResponse. Per the API docs, that helper sets Content-Type: text/event-stream and the appropriate cache-control headers for you.
How do I define tools and make the model actually call them in an agent loop?
Define each tool with a name, description, parameter schema and an executor, pass the array as the tools option to chat(), and set an agentLoopStrategy. The loop is what keeps feeding tool results back to the provider so the model can request another call or produce a final answer.
What does agentLoopStrategy / maxIterations(20) control and how do I tune it?
It caps how many model-and-tool round trips a single request may take before the loop stops. The latest API docs use maxIterations(20) as the example; tune downward based on observed iteration counts in your logs, and confirm per-provider behaviour in the current reference.
How do I connect MCP servers (managed vs manual) and generate types for MCP tools?
Use managed MCP with chat() when you want the framework to handle the server connection, and manual MCP when you need control over transport or authorisation. The docs also cover MCP type generation, which produces typed tool signatures for your codebase.
How do I test the agent without network calls or an API key?
Use fakeText(), added in 1.0, which per TanStack supports testing chat(), tools and middleware with no network and no API key. Pair it with direct calls to your tool executors using recorded responses.
How we researched this
Prepared by TrendsAGI Research. Facts checked on 4 November 2026 against the sources listed below.
We read the official TanStack AI documentation listed below. The TrendsAGI steps and code use its documented REST API and Python SDK; confirm the TanStack AI side against its current documentation, since third-party products change.
| Claim | Applies to | Source |
|---|---|---|
| TanStack AI's core libraries are framework-agnostic and provider-agnostic, usable across React, Vue, Svelte, Solid, Angular and vanilla. | all | tanstack.com |
| TanStack AI provides a chat() function that streams from a server route and a hook for your framework to render tokens. | latest docs | tanstack.com |
| Installing TanStack AI for a chat app uses @tanstack/ai, @tanstack/ai-react and @tanstack/ai-openai via npm, pnpm or yarn. | quick-start (older docs revision) | github.com |
| Provider adapters are imported per provider, e.g. openaiText from @tanstack/ai-openai or openRouterText from @tanstack/ai-openrouter, and passed as the adapter option. | latest API docs | github.com |
| chat() supports an agentLoopStrategy option such as maxIterations(20). | latest API docs | github.com |
| toServerSentEventsResponse sets Content-Type to text/event-stream and cache-control headers for streaming responses. | latest API docs | github.com |
| The OpenRouter adapter gives access to 400+ AI models from various providers through a single unified API. | @tanstack/ai-openrouter | openrouter.ai |
| TanStack AI 1.0 shipped stable core APIs, rewritten docs and an experimental agent harness, with experimental harness packages staying on 0.x. | 1.0 | tanstack.com |
| TanStack AI docs cover MCP server tools, managed MCP with chat(), manual MCP and MCP type generation. | latest docs (updated 2026-11-02) | tanstack.com |
| TanStack AI 1.0 added five new sandbox providers: Blaxel, Upstash Box, E2B, boxd and Railway. | 1.0 | tanstack.com |
| TanStack AI 1.0 includes fakeText() to test chat(), tools and middleware with no network and no API key. | 1.0 | tanstack.com |
| TanStack libraries are MIT licensed, self-hostable and have no paid tiers. | all | tanstack.com |
Sources
- Quick Start | TanStack AI Docs — tanstack.com
- @tanstack/ai API docs (GitHub (TanStack)) — github.com
- TanStack AI Integration - OpenRouter SDK Support — openrouter.ai