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)
Endpointnpx @upapi/mcphttps://app.upapi.io/api/mcp
Authtu clave de API de upapi_inicia sesión con tu cuenta de upAPI (OAuth)
Ejecuciónen tu máquinaen upAPI
Ideal parascripts, CI, agentes autoalojadosClaude, 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_KEYrequeridauna clave de upapi_
UPAPI_BASE_URLopcionalorigen de la puerta de enlace, por defecto https://api.upapi.io
UPAPI_TOOL_MODEopcionalcompact (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.

HerramientaQué hace
search_opsEncuentra operaciones por intención — devuelve slug, descripción, parámetros y costo de cuota
call_opEjecuta 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 TypeScript declare 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 funciones external_* inyectadas). Agrupa varias operaciones en un solo viaje de ida y vuelta con Promise.all en 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 a external_*, o por más de 5 segundos en total en todos esos tramos, se detiene con CPU_BUDGET_EXCEEDED: ..., porque el sandbox comparte el bucle de eventos de Node con cada otra solicitud que el proceso atiende. Necesita quickjs-emscripten 0.31.0 (la versión exacta que @mastra/quickjs 0.1.1 resuelve) instalado junto a él. Ambos se cargan en la primera llamada a execute_typescript, por lo que un servidor que nunca ejecuta una (o usa la superficie full) 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:

ValorAnunciaCuándo usarlo
codemode (predeterminado)search_tools + execute_typescriptCualquier modelo que pueda escribir unas líneas de TypeScript
fullUna herramienta por operación — la tabla createUpapiTools de hoyInterruptor de reversión, o un cliente ya construido para ello
bothLa unión de ambosEjercitar 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.