Integrations

How do I give a Vercel AI SDK app web access with UpRock?

Create an MCP client with createMCPClient from @ai-sdk/mcp pointed at UpRock's server, pass its tools to generateText or streamText, and the model can load pages on an opted-in device in the country it picks. Give tool calls an abort signal, because they have no default timeout, and close the client when the run ends.

Updated · Read as markdown

What the model gets

UpRock's MCP server runs over streamable HTTP at https://mcp.uprock.ai/mcp, with your API key in an Authorization: Bearer header (clients that can't send headers can use https://mcp.uprock.ai/<API_KEY>/mcp instead). client.tools() returns an object you can pass straight to generateText, with these keys:

ToolWhat it does
crawl_fetchLoads a page in a real browser on a device in the country you pass (url, country, device_type); returns a summary and links to the stored markdown and HTML
resource_fetchReads a stored result in full (uri), such as that markdown
video_searchFinds moments in public video by meaning (query)
video_momentDescribes what happens in a stretch of one video (url, start_s, end_s)
verifyLoads one URL from several regions with status and timings
web_researchMulti-engine search from chosen countries. Use with care: when we tested on 21 Oct 2026 it returned empty or off-topic results from some countries

To expose only some tools to the model, pick them out of the object, for example { crawl_fetch: tools.crawl_fetch, resource_fetch: tools.resource_fetch }.

The code

The example makes a direct call first (no model involved), then lets Claude choose the tools in generateText. Set UPROCK_API_KEY (from uprock.ai/app/api-keys) and ANTHROPIC_API_KEY, or swap in any other provider:

// npm i ai @ai-sdk/mcp @ai-sdk/anthropic   (Node 18+)   env: UPROCK_API_KEY, ANTHROPIC_API_KEYimport { createMCPClient } from "@ai-sdk/mcp";import { anthropic } from "@ai-sdk/anthropic";import { generateText, isStepCount } from "ai";​const uprock = await createMCPClient({  transport: {    type: "http",    url: "https://mcp.uprock.ai/mcp",    headers: { Authorization: `Bearer ${process.env.UPROCK_API_KEY}` },  },});​type Block = { type: string; text?: string };const textOf = (result: unknown) =>  (result as { content: Block[] }).content.find((b) => b.type === "text")?.text ?? "";​try {  const tools = await uprock.tools(); // crawl_fetch, resource_fetch, video_search, ...​  // 1. A direct call, no model involved: load a page on a device in Germany. Tool calls have  // no default timeout, so pass one.  const options = {    toolCallId: "1",    messages: [],    context: {},    abortSignal: AbortSignal.timeout(300_000),  };  const page = JSON.parse(    textOf(      await tools.crawl_fetch.execute!(        { url: "https://example.com", country: "DE" },        options,      ),    ),  );  const markdown = textOf(    await tools.resource_fetch.execute!(      { uri: page.content.markdown.resource },      options,    ),  );  console.log(page.meta.title, markdown.length, "chars of markdown");​  // 2. The same tools, chosen by a model.  const { text } = await generateText({    model: anthropic("claude-sonnet-5-5"),    tools,    stopWhen: isStepCount(5),    system:      "When you need a web page as it looks in a specific country, or another fetch failed, call " +      "crawl_fetch with the url and country, then resource_fetch on the markdown resource it returns.",    prompt: "What does https://example.com say when opened from Germany?",  });  console.log(text);} finally {  await uprock.close(); // after generateText resolves; with streamText, close in onFinish}

Calling execute yourself returns the raw MCP result, { content, isError }. In the AI SDK 7 types, its options need toolCallId, messages and context; abortSignal is optional but worth passing.

What comes back

The first text block of a crawl_fetch result is a JSON summary, small on purpose:

{  "status": "success",  "meta": { "url": "https://example.com", "title": "Example Domain", "content_type": "text/html" },  "content": { "markdown": { "resource": "crawl://…/markdown", "size_bytes": 1342 } }}

When the model calls the tool, the AI SDK turns text into text and everything else, including resource links, into JSON text, so the model sees this summary and the resource address. The system prompt in the example tells it to follow up with resource_fetch, which returns the page as markdown. Don't rely on meta.status_code: it isn't always present.

Good to know

  • No default timeout. Pass an abortSignal on direct calls; for model-driven calls, pass one to generateText.
  • Close the client after generateText resolves, or in onFinish with streamText.
  • The key is in a header. Keep it in an environment variable, and don't log the client's config or MCPClientError objects whole.
  • Cost. One credit per page fetched: $0.50 per 1,000 pages by card or USDC, $0.40 with UPT. Cap the agent's steps (isStepCount) and say in the system prompt when to ask before fetching many pages.

We ran this example on 21 Oct 2026 with ai 7.0.148 and @ai-sdk/mcp 2.0.81 against the live UpRock server. The direct calls returned example.com's title and markdown. For the generateText part we used the AI SDK's own mock model, scripted to call crawl_fetch and then answer, in place of Claude: the loop ran two steps and the tool call went through UpRock. On 6 Nov 2026 we ran the direct calls again with an UpRock API key in an Authorization header.

FAQ

Is it createMCPClient or experimental_createMCPClient?

createMCPClient, from @ai-sdk/mcp, in AI SDK 7. experimental_createMCPClient is still exported but marked deprecated, and the ai package itself no longer exports an MCP client.

Do I need to close the client?

Yes. With generateText, close it in a finally block after the call resolves, as in the example. With streamText, close it in onFinish, after the stream is done; closing earlier cuts off tool calls still running.

Why pass an abortSignal?

MCP tool calls in the AI SDK have no default timeout. A fresh UpRock fetch takes 10 to 40 seconds, so the example gives each direct call five minutes. When the model calls the tools, generateText's own abortSignal applies.

What does the model see when it calls crawl_fetch?

The AI SDK passes text content through and turns other content, including resource links, into JSON text. The model reads a short JSON summary with the page's title and a link to its stored markdown, and calls resource_fetch when it wants the full page.

Is my API key safe in logs?

Be careful, because the key is part of the server URL, and the AI SDK's docs warn not to log the url or responseBody of an MCPClientError. Keep the key in an environment variable and log error messages, not the error objects.

Other use cases to explore

References

  1. AI SDK docs, MCP tools, checked 21 Oct 2026
  2. AI SDK reference, createMCPClient, checked 21 Oct 2026
  3. @ai-sdk/mcp on npm, checked 21 Oct 2026
  4. AI SDK docs, Anthropic provider, checked 21 Oct 2026
  5. UpRock, setup for every agent, checked 21 Oct 2026
  6. UpRock, everything in one file (API, CLI, MCP, pricing), checked 21 Oct 2026

Get started

Add UpRock in one paste.

Paste this into Claude Code, Codex, Cursor or any agent with a terminal. It reads our docs, sets up the MCP server or CLI, and tells you the cost before it spends anything.

Set up UpRock for me: read https://uprock.ai/agents.md, connect the UpRock MCP server, and run one test crawl. Tell me what it costs before you spend anything.

How do I give a Vercel AI SDK app web access with UpRock? | UpRock AI