upAPI
Todas las operaciones públicas de upAPI como herramientas MCP: búsqueda web, Google Maps, capturas de pantalla, PDF, OCR y más.
Documentación
@upapi/mcp
Cada operación pública de upAPI como una herramienta de MCP — búsqueda web, SERP, perfiles sociales, consultas de herramientas de desarrollo, datos geo/financieros — para que un agente pueda llamarlas directamente.
Hay dos formas de conectarse, y solo se diferencian en cómo se autentica una llamada:
| Local (stdio) | Alojado (HTTP) | |
|---|---|---|
| Endpoint | npx @upapi/mcp | https://app.upapi.io/api/mcp |
| Auth | tu clave de API de upapi_ | inicia sesión con tu cuenta de upAPI (OAuth) |
| Ejecución | en tu máquina | en upAPI |
| Ideal para | scripts, CI, agentes autoalojados | Claude, IDEs, cualquier cosa que hable MCP remoto |
Ambos exponen las mismas herramientas con los mismos esquemas, y ambos facturan la misma cuota.
Alojado — sin instalación
Apunta cualquier cliente MCP que admita servidores remotos a:
https://app.upapi.io/api/mcp
Te guiará para iniciar sesión en upAPI en un navegador; no hay clave que copiar. Con Claude Code:
claude mcp add --transport http upapi https://app.upapi.io/api/mcp
Local — clave de API
Crea una clave en app.upapi.io → API Keys, luego:
claude mcp add upapi -e UPAPI_API_KEY=upapi_xxx -- npx -y @upapi/mcp
Claude Desktop (claude_desktop_config.json), Cursor y Windsurf aceptan lo mismo como JSON:
{
"mcpServers": {
"upapi": {
"command": "npx",
"args": ["-y", "@upapi/mcp"],
"env": { "UPAPI_API_KEY": "upapi_xxx" }
}
}
}
| Variable | ||
|---|---|---|
UPAPI_API_KEY | requerida | una clave de upapi_ |
UPAPI_BASE_URL | opcional | origen de la puerta de enlace, por defecto https://api.upapi.io |
UPAPI_TOOL_MODE | opcional | compact (predeterminado), directory, claude o full — ver Herramientas |
La clave nunca se valida localmente — solo se verifica su presencia, por lo que una clave faltante falla inmediatamente con un mensaje legible en lugar de aparecer más tarde como un 401 inexplicable dentro de una llamada de herramienta. Si una clave es real, está vencida o supera la cuota se responde en la puerta de enlace, el único lugar que lo responde para cada llamador de máquina.
Herramientas
El endpoint alojado sirve una tabla compacta por defecto: dos meta-herramientas más unas pocas operaciones siempre activas, unos pocos kilobytes en total.
| Herramienta | Qué hace |
|---|---|
search_ops | Encuentra operaciones por intención — devuelve slug, descripción, parámetros y costo de cuota |
call_op | Ejecuta una operación por slug: { "slug": "github-repo.get", "input": { … } } |
Una tabla de herramientas se reenvía como contexto en cada turno, por lo que una herramienta por operación significa decenas de
kilobytes de JSON Schema por turno y una tabla lo suficientemente grande como para degradar mediblemente la selección de herramientas.
search_ops + call_op se mantiene plana a medida que crece el catálogo. web-search.post, github-repo.get,
y wikipedia-article.get permanecen en la tabla como herramientas completas para que el caso común no necesite un viaje de ida y vuelta
de descubrimiento.
Hay otras dos tablas. ?tools=full le da a cada operación su propia herramienta:
claude mcp add --transport http upapi 'https://app.upapi.io/api/mcp?tools=full'
?tools=directory ofrece un conjunto curado de 11 herramientas nombradas para las operaciones insignia —
página a Markdown, captura de pantalla, HTML a PDF, texto PDF, OCR, transcripción, repositorio de GitHub, paquete
npm, Wikipedia, moneda — con herramientas de lectura y herramientas de escritura listadas por separado
y sin call_op. Esa es la forma que piden los criterios de revisión de directorios de IA (un despachador
comodín con un parámetro objetivo es un rechazo, y también lo es un listado que anuncia fuentes extraídas, que es
por lo que el trío de Maps y la búsqueda web permanecen invocables pero no se listan allí), y es lo que
la Extensión de Claude Desktop incluye. ?tools=claude tiene la misma forma sobre las 8 operaciones que upAPI
calcula por sí mismo (página a Markdown, captura de pantalla, HTML a PDF, texto PDF, OCR, transcripción y su
resultado, análisis de texto) — el listado del conector de Claude. El servidor stdio local usa los mismos nombres en UPAPI_TOOL_MODE,
con valor predeterminado compact — la misma forma de unos pocos kilobytes a la que el endpoint alojado se ajusta por defecto. full
permanece disponible (UPAPI_TOOL_MODE=full) como respaldo para un cliente ya configurado
contra la forma de una herramienta por operación a la que este servidor solía ajustarse por defecto.
Cada modo alcanza exactamente las mismas operaciones — el modo cambia lo que se anuncia, nunca
lo que se permite. Cada herramienta en cada modo lleva readOnlyHint, destructiveHint,
idempotentHint y openWorldHint, derivados de lo que hace el trabajador en lugar de la
terminación verbal del slug. Las operaciones se nombran según su slug con . y - reemplazados por _
(web-search.post → web_search_post), y cada una anuncia el JSON Schema real de la operación
(formatos, límites, valores predeterminados, nulabilidad), porque ese esquema se genera desde el propio modelo del
trabajador y se pasa sin modificar.
El servidor alojado alcanza todo el catálogo público en cada modo; desde 2026-09-26
no retiene ninguna categoría. El servidor local (stdio) y la Extensión de Desktop se ponen al día en la próxima
versión: el 0.2.0 publicado incluye 63 operaciones y aún retiene Redes Sociales y Utilidades en
modo directory.
El modo directory solo cambia lo que se ANUNCIA — el
conjunto insignia curado que muestra un listado público (como la Extensión de Claude Desktop).
Las descripciones llevan el costo de cuota, para que un agente pueda presupuestar:
Buscar en la web… operación de upAPI
web-search.post(Búsqueda). Cuesta 25 unidades de cuota mensual por llamada.
Una operación fallida regresa como un resultado de herramienta normal con isError: true y texto que comienza con
el código de error público de upAPI — RATE_LIMITED, INVALID_INPUT, UPSTREAM_UNREACHABLE. Un límite de velocidad
también indica la espera en segundos. Nada de una operación fallida rompe la sesión.
No se declara outputSchema, deliberadamente: MCP requiere que un servidor que declara uno devuelva
structuredContent coincidentes, y estas salidas describen cargas útiles de terceros en vivo. Un
null inesperado convertiría una llamada exitosa en un error de protocolo.
Úsalo desde Mastra
Las herramientas funcionan directamente en un agente de Mastra, sin un transporte MCP en el medio. @mastra/core y
@mastra/mcp son dependencias opcionales entre pares — instálalas tú mismo e importa los enlaces
desde el subpath /mastra. Nada más en este paquete toca Mastra, que es lo que mantiene un
npm i @upapi/mcp simple (y el paquete de la extensión de escritorio construido a partir de él) pequeño.
import { Agent } from '@mastra/core/agent';
import { createGatewayCaller } from '@upapi/mcp';
import { createUpapiTools } from '@upapi/mcp/mastra';
const agent = new Agent({
name: 'researcher',
instructions: 'Research topics using upAPI.',
model: /* … */,
tools: createUpapiTools({
caller: createGatewayCaller({ apiKey: process.env.UPAPI_API_KEY! }),
}),
});
Reduce la tabla con filter cuando un agente solo deba ver parte del catálogo:
createUpapiTools({
caller,
filter: (op) => op.category === 'Search',
});
createUpapiMcpServer — Modo Código por defecto
createUpapiMcpServer construye un MCPServer de Mastra (@mastra/mcp, también un par opcional). Su
superficie de herramientas predeterminada es el Modo Código: search_tools + execute_typescript en lugar de una herramienta
por operación — medido en el catálogo completo de 99 operaciones, tools/list baja de 111,016
bytes a 1,069 bytes (99 herramientas → 2), porque la tabla ya no crece con el catálogo en absoluto.
import { createGatewayCaller } from '@upapi/mcp';
import { createUpapiMcpServer } from '@upapi/mcp/mastra';
const server = createUpapiMcpServer({
caller: createGatewayCaller({ apiKey: process.env.UPAPI_API_KEY! }),
});
await server.startStdio();
search_tools({ query? })encuentra las operaciones que esta conexión puede alcanzar y las devuelve como firmas de TypeScriptdeclare function external_<name>(...).execute_typescript({ code })ejecuta un programa corto de TypeScript en un sandbox aislado de QuickJS (@mastra/quickjs, otro par opcional — sin binario nativo, sin acceso a sistema de archivos/red/procesos más allá de las funcionesexternal_*inyectadas). Agrupa varias operaciones en un solo viaje de ida y vuelta conPromise.allen lugar de una llamada de herramienta cada una. Se elimina después de 30 segundos. Un programa que calcula por más de 1.5 segundos sin esperar una llamada aexternal_*, o por más de 5 segundos en total en todos esos tramos, se detiene conCPU_BUDGET_EXCEEDED: ..., porque el sandbox comparte el bucle de eventos de Node con cada otra solicitud que el proceso atiende. Necesitaquickjs-emscripten0.31.0(la versión exacta que@mastra/quickjs0.1.1 resuelve) instalado junto a él. Ambos se cargan en la primera llamada aexecute_typescript, por lo que un servidor que nunca ejecuta una (o usa la superficiefull) no necesita tenerlos instalados.
Cada llamada a external_* resuelve exactamente al mismo objeto de herramienta createUpapiTools(options) que la
superficie full (abajo) llama — no hay una segunda ruta de autenticación. Una llamada de operación denegada o fallida
aparece dentro del sandbox como un Error("<CODE>: <message>") lanzado, para que el propio
try/catch del programa invitado pueda inspeccionar y ramificar según el código; los argumentos que fallan el esquema
de entrada de una operación lanzan INVALID_INPUT: <details> de la misma manera. Eso es separado de una
entrada de execute_typescript malformada, que falla la llamada en sí antes de que el sandbox siquiera comience.
Establece MCP_TOOL_SURFACE (o pasa surface) para cambiar lo que se anuncia:
| Valor | Anuncia | Cuándo usarlo |
|---|---|---|
codemode (predeterminado) | search_tools + execute_typescript | Cualquier modelo que pueda escribir unas líneas de TypeScript |
full | Una herramienta por operación — la tabla createUpapiTools de hoy | Interruptor de reversión, o un cliente ya construido para ello |
both | La unión de ambos | Ejercitar o migrar fuera de una superficie a mitad de transición |
MCP_TOOL_SURFACE=full node my-server.js # one tool per operation, the pre-Code Mode shape
createUpapiMcpServer({ caller, surface: 'full' }); // same thing, set in code instead of env
instructions en el servidor lleva el contrato del Modo Código automáticamente siempre que una
herramienta codemode esté en la tabla (codemode y both) — un modelo no fue instruido para escribir TypeScript contra
search_tools/execute_typescript de otra manera.
Construye tu propio servidor
caller es lo único que la tabla de herramientas no proporciona, que es lo que permite que las mismas herramientas se ejecuten
sobre diferentes transportes:
import { startUpapiStdioServer, type Caller } from '@upapi/mcp';
const caller: Caller = async (slug, input) => {
// resolve with the operation's output, or throw
// { code, message, status?, retryAfterSeconds? }
};
await startUpapiStdioServer({ caller, mode: 'directory' });
Para un servidor Request/Response estándar web (ruta de Next.js, Worker, Hono), importa el
manejador desde el subpath /http — así es como se construye app.upapi.io/api/mcp:
import { handleUpapiMcpRequest, type Caller } from '@upapi/mcp/http';
await handleUpapiMcpRequest(request, {
caller,
// mode defaults to the request's own `?tools=` parameter (compact unless `full`/`directory`)
canExecute: true, // false hides every executable tool and refuses a call to one
canSearch: true, // false hides `search_ops`
});
canExecute / canSearch son cómo un host proyecta su propia autorización sobre la tabla —
upAPI los mapea a los alcances ops:execute y ops:read del token de acceso. Ambos tienen como valor
predeterminado true, por lo que un host sin un modelo de alcances no se ve afectado.
Prefiere ese subpath sobre la raíz del paquete en una implementación empaquetada o con seguimiento de archivos: alcanza solo
el SDK de MCP, mientras que la entrada raíz también arrastra el servidor stdio. Ninguno alcanza Mastra — los
enlaces viven detrás de @upapi/mcp/mastra precisamente para que una compilación que nunca ejecuta un agente de Mastra
nunca vea @mastra/core.
Relacionados
@upapi/sdk— el cliente HTTP tipado, y el catálogo de operaciones del que se genera la tabla de herramientas de este paquete- upapi.io/docs — referencia de operaciones
Dónde ocurre el desarrollo
Este repositorio es el hogar publicado de @upapi/mcp: es lo que npm instala, y
los problemas y solicitudes de extracción son bienvenidos aquí. La tabla de herramientas se deriva del
catálogo de operaciones en @upapi/sdk,
que a su vez se genera desde las definiciones de operaciones privadas de upAPI y se sincroniza
automáticamente — por lo que el conjunto de herramientas cambia aguas arriba. El servidor, la fachada, el mapeo de
errores y las pruebas en estos archivos están escritos a mano y son el código a cambiar.