# How do I give a Mastra agent web access with UpRock?

Create an MCPClient from @mastra/mcp with UpRock's server URL and a timeout above the 60-second default, then pass the tools from listTools() to your Agent. They arrive prefixed with the server name, so crawl_fetch becomes uprock_crawl_fetch, and it loads a page on an opted-in device in the country you choose for $0.50 per 1,000 pages.

Updated 25 Oct 2026. Web page: https://uprock.ai/integrations/mastra

## On this page

- [What your agent gets](#what-your-agent-gets)
- [MCPClient settings for UpRock](#mcpclient-settings-for-uprock)
- [The code](#the-code)
- [What comes back](#what-comes-back)
- [FAQ](#faq)
- [Other use cases to explore](#explore)
- [Related articles](#related)
- [References](#references)
- [Get started](#get-started)

## What your agent 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). Name it `uprock` in MCPClient's `servers` map and `listTools()` returns these, prefixed with that name:

| Tool | What it does | Give it to the agent? |
|---|---|---|
| `uprock_crawl_fetch` | Loads a page in a real browser on a desktop or mobile device in the country you pass; returns a summary and links to the stored markdown and HTML | Yes |
| `uprock_resource_fetch` | Reads a stored result in full, such as that markdown | Yes, with crawl_fetch |
| `uprock_verify` | Loads one URL from several regions with status, timings and screenshots | For agents that check websites |
| `uprock_video_search` | Finds moments in public video by meaning | When answers may be in video |
| `uprock_video_moment` | Reads the time-stamped moments of one video | Use with care: it returned 502 "temporarily unavailable" when we tested on 25 Oct 2026 |
| `uprock_web_research` | Searches several engines from chosen countries | Use with care: on 25 Oct 2026, 4 of the 8 results for a query about the MCP spec were unrelated Wikipedia pages |

Get a key at uprock.ai/app/api-keys and set it as `UPROCK_API_KEY`.

## MCPClient settings for UpRock

Most of MCPClient's defaults suit UpRock. These are the ones worth knowing, checked against `@mastra/mcp` 2.5.0:

| Setting | Default | For UpRock |
|---|---|---|
| `timeout` | 60,000 ms | Set 300,000 on the server. A fresh fetch usually takes 10 to 40 seconds, and UpRock retries on fresh devices before it gives up |
| `onToolError` | `'throw'` | Keep it. An UpRock failure becomes a `MastraError` the model can read |
| `forwardInstructions` | `false` | Nothing to forward: UpRock's server doesn't send MCP instructions yet |
| `requireToolApproval` | off | Optional. UpRock marks every tool except `video_moment` as read-only, but each fetch uses a credit |
| `protocolVersion` | probes `2026-07-28` first | Leave it. UpRock answers the older handshake, and the probe added about 0.2 seconds in our test; `'legacy'` skips it |
| `id` | none | Set one if you create more than one client with the same servers, or MCPClient throws to prevent a leak |

The tool prefix comes from the server key (`uprock`), not from the URL.

## The code

The example makes a direct call first (no model involved), then lets a model choose the same two tools:

```ts
// npm i @mastra/core @mastra/mcp   (Node 22.13+)   env: UPROCK_API_KEY, ANTHROPIC_API_KEY
import { Agent } from "@mastra/core/agent";
import { MCPClient } from "@mastra/mcp";

const uprock = new MCPClient({
  id: "uprock",
  servers: {
    uprock: {
      url: new URL("https://mcp.uprock.ai/mcp"),
      requestInit: { headers: { Authorization: `Bearer ${process.env.UPROCK_API_KEY}` } },
      timeout: 300_000, // the default is 60 s; a fresh fetch can take 10 to 40 s
    },
  },
});

// A tool call returns the MCP result: { content: [text, resource links] }.
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.listTools(); // uprock_crawl_fetch, uprock_resource_fetch, ...
  const crawlFetch = tools.uprock_crawl_fetch;
  const resourceFetch = tools.uprock_resource_fetch;

  // 1. A direct call, no model involved: load a page on a device in Germany.
  // Outside an agent run, an empty execution context is enough.
  const ctx = {} as Parameters<NonNullable<typeof crawlFetch.execute>>[1];
  const page = JSON.parse(
    textOf(
      await crawlFetch.execute!({ url: "https://example.com", country: "DE" }, ctx),
    ),
  );
  const markdown = textOf(
    await resourceFetch.execute!({ uri: page.content.markdown.resource }, ctx),
  );
  console.log(page.meta.title, markdown.length, "chars of markdown");

  // 2. The same two tools, chosen by a model.
  const agent = new Agent({
    id: "web-reader",
    name: "Web reader",
    instructions:
      "When you need a web page as it looks in a specific country, or another fetch failed, " +
      "call uprock_crawl_fetch with the url and country, then uprock_resource_fetch on the " +
      "markdown resource it returns.",
    model: "anthropic/claude-sonnet-5-5",
    tools: { uprock_crawl_fetch: crawlFetch, uprock_resource_fetch: resourceFetch },
  });
  const result = await agent.generate(
    "What does https://example.com say when opened from Germany?",
    { maxSteps: 5 },
  );
  console.log(result.text);
} finally {
  await uprock.disconnect();
}
```

To give the agent every UpRock tool, pass `tools: await uprock.listTools()` as Mastra's docs do. Picking two keeps `web_research` and `video_moment` away from the model until they're fixed.

## What comes back

| Call | What you get |
|---|---|
| `uprock_crawl_fetch.execute(...)` | `{ content: [...] }`: a text block holding the JSON summary (status, title, the `crawl://` addresses of the markdown and HTML), then two resource links |
| `uprock_resource_fetch.execute(...)` | `{ content: [...] }` with one text block: the page as markdown |
| Any call UpRock rejects | A thrown `MastraError` (`MCP_CLIENT_TOOL_EXECUTION_FAILED`) with UpRock's message. A wrong key took 14 seconds to fail, because UpRock tried three times |

The direct calls above printed `Example Domain 958 chars of markdown`. When the agent calls the tools, Mastra passes the model the MCP result as JSON, summary included, and the instructions tell it to follow up with `uprock_resource_fetch`. Don't build logic on `meta.status_code`: when we fetched a page that answers 403, `status` said `success` and `status_code` was missing. A recently fetched page comes back in under half a second.

We ran this example on 25 Oct 2026 with @mastra/core 1.79.0, @mastra/mcp 2.5.0 and ai 7.0.153 on Node 25, against the live UpRock server, and type-checked it with `tsc --strict` (module NodeNext). The direct calls returned example.com's title and markdown. For the agent we swapped the Claude model for the AI SDK's MockLanguageModelV4, scripted to call `uprock_crawl_fetch`, then `uprock_resource_fetch` on the address it got back, then answer: the run took three steps and both tool calls went through UpRock. On 6 Nov 2026 we ran the direct calls again with an UpRock API key in an `Authorization` header.

## FAQ

### Why are the tools called uprock_crawl_fetch?

listTools() prefixes every tool with the key you gave the server in the servers map, so naming the server uprock gives uprock_crawl_fetch, uprock_resource_fetch and so on. The prefix comes from that key, never from the URL, so your API key stays out of the tool names.

### What timeout should I set?

MCPClient waits 60 seconds by default. A fresh UpRock fetch usually takes 10 to 40 seconds and can run longer while it retries on a fresh device, so the example sets timeout to 300,000 milliseconds on the uprock server.

### What happens when UpRock reports an error?

With the default onToolError setting ('throw'), the tool throws a MastraError with the code MCP_CLIENT_TOOL_EXECUTION_FAILED and UpRock's message, such as an invalid key. Inside an agent run the model sees that error as the tool's result. Set onToolError to 'return' to get the raw result instead.

### listTools() or listToolsets()?

listTools() for one shared key, passed to the Agent constructor as in the example. If each of your users brings their own UpRock key, create an MCPClient per request and pass listToolsets() to generate() or stream() as toolsets.

### What does it cost?

One credit per page fetched, $0.50 per 1,000 pages by card or USDC and $0.40 with UPT, prepaid. Video search is $1 per 1,000 searches.

## Other use cases to explore

- [Read a page as it looks in another country](https://uprock.ai/use-cases/page-from-another-country): prices, banners and search results change with the visitor's country; fetch from the one you need.
- [Retry a page your agent got a 403 on](https://uprock.ai/use-cases/agent-gets-403): which failures are worth a second network and which to leave alone.
- [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.
- [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 give a Vercel AI SDK app web access with UpRock?](https://uprock.ai/integrations/vercel-ai-sdk.md): Connect UpRock's MCP server with @ai-sdk/mcp, call its tools directly or let the model choose them in generateText, and avoid the timeout and key-logging traps, 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.
- [Integrations: all articles](https://uprock.ai/integrations.md)

## References

1. [Mastra docs, MCP (connect agents to MCP servers)](https://mastra.ai/docs/connections/mcp), checked 25 Oct 2026
2. [Mastra reference, MCPClient (options, listTools, errors, lifecycle)](https://mastra.ai/reference/tools/mcp-client), checked 25 Oct 2026
3. [Mastra reference, Agent.generate()](https://mastra.ai/reference/agents/generate), checked 25 Oct 2026
4. [@mastra/mcp on npm](https://www.npmjs.com/package/@mastra/mcp), checked 25 Oct 2026
5. [AI SDK reference, testing with mock models (MockLanguageModelV4)](https://ai-sdk.dev/docs/ai-sdk-core/testing), checked 25 Oct 2026
6. [UpRock, setup for every agent](https://uprock.ai/agents.md), checked 25 Oct 2026
7. [UpRock, everything in one file (API, CLI, MCP, pricing)](https://uprock.ai/llms-full.txt), checked 25 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
