All public upAPI operations as MCP tools: web scraping, search, screenshots, PDF, OCR and more.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Every public upAPI operation as an MCP tool β web search, SERP, social profiles, dev-tool lookups, geo/finance data β so an agent can call them directly.
There are two ways to connect, and they differ only in how a call is authenticated:
| Local (stdio) | Hosted (HTTP) | |
|---|---|---|
| Endpoint | npx @upapi/mcp | https://app.upapi.io/api/mcp |
| Auth | your upapi_ API key | sign in with your upAPI account (OAuth) |
| Runs | on your machine | on upAPI |
| Best for | scripts, CI, self-hosted agents | Claude, IDEs, anything that speaks remote MCP |
Both expose the same tools with the same schemas, and both bill the same quota.
Point any MCP client that supports remote servers at:
It will walk you through signing in to upAPI in a browser; there is no key to copy. With Claude Code:
Create a key at app.upapi.io β API Keys, then:
Claude Desktop (claude_desktop_config.json), Cursor, and Windsurf take the same thing as JSON:
| Variable | ||
|---|---|---|
UPAPI_API_KEY | required | an upapi_ key |
UPAPI_BASE_URL | optional | gateway origin, defaults to https://api.upapi.io |
The key is never validated locally β only checked for presence, so a missing one fails immediately with a readable message instead of surfacing later as an unexplained 401 inside a tool call. Whether a key is real, expired, or over quota is answered at the gateway, the single place that answers it for every machine caller.
The hosted endpoint serves a compact table by default: two meta-tools plus a few always-on operations, a few kilobytes in total.
| Tool | What it does |
|---|---|
search_ops | Find operations by intent β returns slug, description, parameters, and quota cost |
call_op | Run one operation by slug: { "slug": "github-repo.get", "input": { β¦ } } |
A tool table is re-sent as context on every turn, so one tool per operation means tens of
kilobytes of JSON Schema per turn and a table large enough to measurably degrade tool selection.
search_ops + call_op stays flat as the catalog grows. web-search.post, github-repo.get,
and wikipedia-article.get stay on the table as full tools so the common case needs no discovery
round-trip.
Want every operation as its own tool instead? Add ?tools=full:
Both modes reach exactly the same operations β the mode changes what is advertised, never what is
allowed. Operations are named after their slug with . and - replaced by _
(web-search.post β web_search_post), and each advertises the operation's real JSON Schema
(formats, bounds, defaults, nullability), because that schema is generated from the worker's own
model and passed through untouched.
The local (stdio) server always serves one tool per operation, and the whole catalog: it is installed deliberately, with your own key, into a client you chose.
Descriptions carry the quota cost, so an agent can budget:
Search the web⦠upAPI operation
web-search.post(Search). Costs 25 units of monthly quota per call.
A failed operation comes back as a normal tool result with isError: true and text leading with
upAPI's public error code β RATE_LIMITED, INVALID_INPUT, UPSTREAM_UNREACHABLE. A rate limit
also states the wait in seconds. Nothing about a failing operation breaks the session.
No outputSchema is declared, deliberately: MCP requires a server that declares one to return
matching structuredContent, and these outputs describe live third-party payloads. One
unexpected null would turn a successful call into a protocol error.
The tools work in a Mastra agent directly, without an MCP transport in between:
Narrow the table with filter when an agent should only see part of the catalog:
caller is the only thing the tool table does not supply, which is what lets the same tools run
over different transports:
For a web-standard Request/Response server (Next.js route, Worker, Hono), import the
handler from the /http subpath β this is how app.upapi.io/api/mcp is built:
canExecute / canSearch are how a host projects its own authorization onto the table β
upAPI maps them to the access token's ops:execute and ops:read scopes. Both default to
true, so a host without a scope model is unaffected.
Prefer that subpath over the package root in a bundled or file-traced deployment. The root
entry re-exports the Mastra bindings, so importing the handler from it pulls @mastra/core
and @mastra/mcp into a build that never runs a Mastra agent; @upapi/mcp/http reaches
only the MCP SDK.
@upapi/sdk β the typed HTTP client, and the operation catalog this package's tool
table is generated fromThis repository is the published home of @upapi/mcp: it is what npm installs, and
issues and pull requests are welcome here. The tool table is derived from the
operation catalog in @upapi/sdk,
which is itself generated from upAPIβs private operation definitions and synced
automatically β so the set of tools changes upstream. The server, facade, error
mapping and tests in these files are hand-written and are the code to change.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/upapi)<a href="https://allmcps.com/mcp/upapi"><img src="https://allmcps.com/api/badge/upapi?style=directory" alt="UpAPI on AllMCPs" /></a>