# 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 21 Oct 2026. Web page: https://uprock.ai/integrations/vercel-ai-sdk

## On this page

- [What the model gets](#what-the-model-gets)
- [The code](#the-code)
- [What comes back](#what-comes-back)
- [Good to know](#good-to-know)
- [FAQ](#faq)
- [Other use cases to explore](#explore)
- [Related articles](#related)
- [References](#references)
- [Get started](#get-started)

## 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:

| Tool | What it does |
|---|---|
| `crawl_fetch` | Loads 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_fetch` | Reads a stored result in full (`uri`), such as that markdown |
| `video_search` | Finds moments in public video by meaning (`query`) |
| `video_moment` | Describes what happens in a stretch of one video (`url`, `start_s`, `end_s`) |
| `verify` | Loads one URL from several regions with status and timings |
| `web_research` | Multi-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:

```ts
// npm i ai @ai-sdk/mcp @ai-sdk/anthropic   (Node 18+)   env: UPROCK_API_KEY, ANTHROPIC_API_KEY
import { 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:

```json
{
  "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

- [See a page as it looks in another country](https://uprock.ai/use-cases/page-from-another-country): one store page from five countries, with five prices, two languages and a cookie banner in one country only.
- [Don't let a cache hide a failed fetch](https://uprock.ai/compare/parallel#the-cache-fallback-trap): a provider that quietly serves an older copy when a live fetch fails, and the setting that stops it.
- [Cap what a single page can cost](https://uprock.ai/compare/scrapingbee#what-a-page-costs-in-credits): one provider's credit table, from 1 to 75 credits a page, and how to stop before the expensive tiers.
- [Search public video by moment](https://uprock.ai/video-semantic-search): find the second something is shown or said, across platforms.

## Related articles

- [How do I give Claude Code live web access with UpRock?](https://uprock.ai/integrations/claude-code.md): Add UpRock's MCP server to Claude Code with the key kept out of your repo, check it's connected, tell Claude when to use it, and know the output limits that matter for big pages.
- [How do I add UpRock to Cursor?](https://uprock.ai/integrations/cursor.md): Add UpRock's MCP server to Cursor with the key read from your environment, turn it on, pre-approve the fetch tools, add a rule for when to use it, and run it from Cursor's command-line agent.
- [How do I use UpRock as a LangChain tool?](https://uprock.ai/integrations/langchain.md): Load UpRock's MCP tools into LangChain in Python or JavaScript, call them directly or from an agent, and handle the result format, with code we ran against the live server.
- [How do I fetch web pages from a chosen country in n8n?](https://uprock.ai/integrations/n8n.md): Install UpRock's verified n8n node, add your key, import a two-node workflow we ran in n8n 2.44, and read the page's markdown in the next step, or give the node to an AI Agent as a tool.
- [How do I add UpRock to OpenAI's Codex CLI?](https://uprock.ai/integrations/codex.md): Add UpRock's MCP server to Codex with one command, keep the API key in an environment variable, raise the 60-second tool timeout, and add your own rules in AGENTS.md.
- [How do I give a CrewAI agent web access with UpRock?](https://uprock.ai/integrations/crewai.md): Load UpRock's MCP tools into CrewAI with MCPServerAdapter and the key in a header, why it beats the mcps field's 30-second limit, and how to read what the tools return, with tested code.
- [How do I give a Mastra agent web access with UpRock?](https://uprock.ai/integrations/mastra.md): Connect UpRock's MCP server with MCPClient from @mastra/mcp, raise its 60-second timeout, and call the tools directly or from an Agent, with tested code.
- [Integrations: all articles](https://uprock.ai/integrations.md)

## References

1. [AI SDK docs, MCP tools](https://ai-sdk.dev/docs/ai-sdk-core/mcp-tools), checked 21 Oct 2026
2. [AI SDK reference, createMCPClient](https://ai-sdk.dev/docs/reference/ai-sdk-core/create-mcp-client), checked 21 Oct 2026
3. [@ai-sdk/mcp on npm](https://www.npmjs.com/package/@ai-sdk/mcp), checked 21 Oct 2026
4. [AI SDK docs, Anthropic provider](https://ai-sdk.dev/providers/ai-sdk-providers/anthropic), checked 21 Oct 2026
5. [UpRock, setup for every agent](https://uprock.ai/agents.md), checked 21 Oct 2026
6. [UpRock, everything in one file (API, CLI, MCP, pricing)](https://uprock.ai/llms-full.txt), checked 21 Oct 2026

## Get started

Get an API key: https://uprock.ai/app/api-keys

Paste this into your agent:

```text
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.
```

Setup for every client (MCP, skill, CLI): https://uprock.ai/agents.md
