How do I use UpRock as a LangChain tool?
Connect UpRock's MCP server with LangChain's MCP adapter (langchain.mcp in Python, built into LangChain 1.4, or @langchain/mcp-adapters in JavaScript), and its tools load as regular LangChain tools you can call directly or hand to an agent. crawl_fetch loads a page on an opted-in device in the country you choose, and resource_fetch reads the full markdown it stored.
Updated · Read as markdown
What your LangChain 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). LangChain's MCP adapter turns each of its tools into a LangChain tool:
| Python name | JavaScript name | What it does |
|---|---|---|
crawl_fetch | uprock_crawl_fetch | Loads a page in a real browser on a device in the country you pass; returns a summary and links to the stored markdown and HTML |
resource_fetch | uprock_resource_fetch | Reads a stored result in full, such as that markdown |
video_search | uprock_video_search | Finds moments in public video by meaning |
video_moment | uprock_video_moment | Describes what happens in a stretch of one video |
verify | uprock_verify | Loads one URL from several regions with status and timings |
web_research | uprock_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 |
Get a key at uprock.ai/app/api-keys and set it as UPROCK_API_KEY.
Python
MCP support lives in LangChain itself since 1.4, as langchain.mcp (the separate langchain-mcp-adapters package is no longer maintained). The example makes a direct call first, which needs no model, then gives the same tools to an agent:
# pip install "langchain[mcp]" langchain-anthropic env: UPROCK_API_KEY, ANTHROPIC_API_KEYimport asyncioimport jsonimport osfrom langchain.agents import create_agentfrom fastmcp.client.transports import StreamableHttpTransportfrom langchain.mcp import MCPAdapter # in beta as of LangChain 1.4UPROCK = StreamableHttpTransport( "https://mcp.uprock.ai/mcp", headers={"Authorization": f"Bearer {os.environ['UPROCK_API_KEY']}"},)MODEL = "anthropic:claude-sonnet-5-5" # any chat model LangChain supportsSYSTEM = ( "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 to read the full page.")async def main() -> None: async with MCPAdapter(UPROCK) as uprock: tools = ( await uprock.list_tools() ) # crawl_fetch, resource_fetch, video_search, ... by_name = {tool.name: tool for tool in tools} # 1. A direct call, no model involved: load a page on a device in Germany. blocks = await by_name["crawl_fetch"].ainvoke( {"url": "https://example.com", "country": "DE"} ) page = json.loads( blocks[0]["text"] ) # a JSON summary, then crawl:// resource links uri = page["content"]["markdown"]["resource"] markdown = await by_name["resource_fetch"].ainvoke({"uri": uri}) print(page["meta"]["title"], len(markdown[0]["text"]), "chars of markdown") # 2. The same tools in an agent. agent = create_agent(MODEL, tools, system_prompt=SYSTEM) question = "What does https://example.com say when opened from Germany?" result = await agent.ainvoke( {"messages": [{"role": "user", "content": question}]} ) print(result["messages"][-1].content)asyncio.run(main())MCPAdapter opens a short session for each tool call, so the tools keep working after the async with block. Called with plain arguments, a tool returns its content blocks; called with a tool-call dict, it returns a ToolMessage with the MCP result in .artifact.
JavaScript
@langchain/mcp-adapters 2.0 replaced MultiServerMCPClient with MCPAdapter, and prefixes tool names with the server name:
// npm i @langchain/mcp-adapters @langchain/core (Node 20.10+) env: UPROCK_API_KEYimport { MCPAdapter } from "@langchain/mcp-adapters";const uprock = new MCPAdapter({ servers: { uprock: { url: "https://mcp.uprock.ai/mcp", headers: { Authorization: `Bearer ${process.env.UPROCK_API_KEY}` }, }, }, defaultToolTimeout: 300_000, // a fresh fetch can take 10 to 40 seconds});// A tool returns its content blocks, or a plain string when there's a single text block.type Block = { type: string; text?: string };const textOf = (out: unknown) => typeof out === "string" ? out : ((out as Block[]).find((b) => b.type === "text")?.text ?? "");try { // The adapter prefixes tool names with the server name: uprock_crawl_fetch, uprock_resource_fetch, ... const tools = await uprock.listTools(); const tool = (name: string) => tools.find((t) => t.name === `uprock_${name}`)!; // A direct call, no model involved: load a page on a device in Germany. const page = JSON.parse( textOf( await tool("crawl_fetch").invoke({ url: "https://example.com", country: "DE" }), ), ); const uri = page.content.markdown.resource; const markdown = textOf(await tool("resource_fetch").invoke({ uri })); console.log(page.meta.title, markdown.length, "chars of markdown"); // For an agent, pass `tools` to createAgent from "langchain" while the adapter is open.} finally { await uprock.close();}To use the tools in an agent, pass tools to createAgent from langchain and keep the adapter open until the agent finishes, then call close().
Working with the results
crawl_fetch deliberately returns a small summary instead of the whole page:
{ "status": "success", "meta": { "url": "https://example.com", "title": "Example Domain", "content_type": "text/html" }, "content": { "markdown": { "resource": "crawl://…/markdown", "size_bytes": 1342 }, "html": { "resource": "crawl://…/html", "size_bytes": 2358 } }}The adapter passes the crawl:// resource links on as file blocks, which model providers can't open. So tell the agent, as the Python example's system prompt does, to call resource_fetch with the markdown resource when it needs the page's text. Two smaller things: meta.status_code isn't always present, so don't build logic on it, and a fresh fetch takes 10 to 40 seconds, so give tool calls a generous timeout.
We ran both examples against the live UpRock server on 21 Oct 2026 (langchain 1.4.6 in Python, @langchain/mcp-adapters 2.0.1 in JavaScript): the direct calls returned example.com's title and markdown. We ran the Python agent with a scripted test model in place of Claude, to check the tool loop end to end without a model key; it called crawl_fetch through UpRock and finished. On 6 Nov 2026 we ran the direct calls in both examples again with an UpRock API key in an Authorization header.
FAQ
Should I still use langchain-mcp-adapters in Python?
No. Its repository says it's no longer actively maintained and that MCP support moved into LangChain under the langchain.mcp namespace, from langchain 1.4 (install langchain[mcp]). It's marked beta and prints a LangChainBetaWarning. The JavaScript package, @langchain/mcp-adapters, is current at 2.0.
Why are the tools called uprock_crawl_fetch in JavaScript?
MCPAdapter in @langchain/mcp-adapters 2.0 prefixes every tool with its server name by default, even when there's only one server. The Python adapter doesn't prefix tools when there's a single server, so there it's crawl_fetch.
What does crawl_fetch return?
A JSON summary (status, the page's URL and title, and links to the stored markdown and HTML) followed by resource links. Models can't open crawl:// links themselves, so the agent should call resource_fetch with the markdown resource when it needs the full page.
How long does a call take?
A fresh fetch takes 10 to 40 seconds and a recently fetched page about a second. In JavaScript, set defaultToolTimeout high enough; the example uses 300 seconds.
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
- Add a fallback to a crawler you run: hand the requests Crawlee gives up on to a device in the country you choose.
- See a page as it looks in another country: one store page from five countries, with five prices, two languages and a cookie banner in one country only.
- Decide which failed pages are worth retrying: a diagnosis table from status code to the legitimate fix, and when to stop.
- Search public video by moment: find the second something is shown or said, across platforms.
References
- LangChain docs, MCP in LangChain (Python), checked 21 Oct 2026
- LangChain docs, Migrating from langchain-mcp-adapters (Python), checked 21 Oct 2026
- LangChain docs, MCP in LangChain (JavaScript), checked 21 Oct 2026
- LangChain docs, Migrating to MCPAdapter (JavaScript), checked 21 Oct 2026
- @langchain/mcp-adapters on npm, checked 21 Oct 2026
- UpRock, setup for every agent, checked 21 Oct 2026
- 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.