upAPI

Todas as operações públicas da upAPI como ferramentas MCP: busca na web, Google Maps, capturas de tela, PDF, OCR e mais.

Documentação

@upapi/mcp

Toda operação pública da upAPI como uma ferramenta MCP — busca na web, SERP, perfis sociais, consultas de ferramentas de desenvolvimento, dados geográficos/financeiros — para que um agente possa chamá-las diretamente.

Existem duas formas de conectar, e elas diferem apenas em como uma chamada é autenticada:

Local (stdio)Hospedado (HTTP)
Endpointnpx @upapi/mcphttps://app.upapi.io/api/mcp
Authsua chave de API upapi_entre com sua conta upAPI (OAuth)
Execuçãona sua máquinana upAPI
Melhor parascripts, CI, agentes auto-hospedadosClaude, IDEs, qualquer coisa que fale MCP remoto

Ambos expõem as mesmas ferramentas com os mesmos esquemas, e ambos cobram a mesma cota.

Hospedado — sem instalação

Aponte qualquer cliente MCP que suporte servidores remotos para:

https://app.upapi.io/api/mcp

Ele vai guiá-lo pelo login na upAPI em um navegador; não há chave para copiar. Com o Claude Code:

claude mcp add --transport http upapi https://app.upapi.io/api/mcp

Local — chave de API

Crie uma chave em app.upapi.io → API Keys, depois:

claude mcp add upapi -e UPAPI_API_KEY=upapi_xxx -- npx -y @upapi/mcp

Claude Desktop (claude_desktop_config.json), Cursor e Windsurf aceitam o mesmo em JSON:

{
  "mcpServers": {
    "upapi": {
      "command": "npx",
      "args": ["-y", "@upapi/mcp"],
      "env": { "UPAPI_API_KEY": "upapi_xxx" }
    }
  }
}
Variável
UPAPI_API_KEYobrigatóriauma chave upapi_
UPAPI_BASE_URLopcionalorigem do gateway, padrão é https://api.upapi.io
UPAPI_TOOL_MODEopcionalcompact (padrão), directory, claude ou full — veja Ferramentas

A chave nunca é validada localmente — apenas verificada quanto à presença, então uma chave ausente falha imediatamente com uma mensagem legível em vez de aparecer mais tarde como um 401 inexplicável dentro de uma chamada de ferramenta. Se uma chave é real, expirou ou está acima da cota é respondido no gateway, o único lugar que responde isso para cada chamada de máquina.

Ferramentas

O endpoint hospedado serve uma tabela compacta por padrão: duas meta-ferramentas mais algumas operações sempre ativas, alguns kilobytes no total.

FerramentaO que faz
search_opsEncontra operações por intenção — retorna slug, descrição, parâmetros e custo de cota
call_opExecuta uma operação por slug: { "slug": "github-repo.get", "input": { … } }

Uma tabela de ferramentas é reenviada como contexto a cada turno, então uma ferramenta por operação significa dezenas de kilobytes de JSON Schema por turno e uma tabela grande o suficiente para degradar mensuravelmente a seleção de ferramentas. search_ops + call_op permanece estável conforme o catálogo cresce. web-search.post, github-repo.get, e wikipedia-article.get permanecem na tabela como ferramentas completas para que o caso comum não precise de uma viagem de ida e volta de descoberta.

Existem outras duas tabelas. ?tools=full dá a cada operação sua própria ferramenta:

claude mcp add --transport http upapi 'https://app.upapi.io/api/mcp?tools=full'

?tools=directory dá um conjunto curado de 11 ferramentas nomeadas para as operações principais — página-para-Markdown, captura de tela, HTML-para-PDF, texto de PDF, OCR, transcrição, repositório GitHub, pacote npm, Wikipedia, moeda — com ferramentas de leitura e ferramentas de escrita listadas separadamente e sem call_op. Essa é a forma que os critérios de revisão de diretórios de IA pedem (um despachante pega-tudo com um parâmetro de destino é uma rejeição, e também é uma rejeição uma listagem que anuncia fontes raspadas, que é por que o trio de Maps e a busca na web permanecem chamáveis mas não são listados lá), e é o que a Extensão do Claude Desktop acompanha. ?tools=claude é a mesma forma sobre as 8 operações que a upAPI computa por si mesma (página-para-Markdown, captura de tela, HTML-para-PDF, texto de PDF, OCR, transcrição e seu resultado, análise de texto) — a listagem do conector do Claude. O servidor stdio local aceita os mesmos nomes em UPAPI_TOOL_MODE, padronizando para compact — a mesma forma de alguns kilobytes que o endpoint hospedado usa por padrão. full permanece disponível (UPAPI_TOOL_MODE=full) como o rollback para um cliente já configurado contra a forma de uma-ferramenta-por-operação que este servidor costumava usar por padrão.

Cada modo alcança exatamente as mesmas operações — o modo muda o que é anunciado, nunca o que é permitido. Cada ferramenta em cada modo carrega readOnlyHint, destructiveHint, idempotentHint e openWorldHint, derivados do que o worker faz em vez do sufixo de verbo do slug. As operações são nomeadas após seu slug com . e - substituídos por _ (web-search.post → web_search_post), e cada uma anuncia o JSON Schema real da operação (formatos, limites, padrões, nulabilidade), porque esse schema é gerado a partir do modelo do próprio worker e passado sem alterações.

O servidor hospedado alcança todo o catálogo público em cada modo; desde 2026-09-26 ele não retém nenhuma categoria. O servidor local (stdio) e a Extensão do Desktop alcançam na próxima versão: o 0.2.0 publicado agrupa 63 operações e ainda retém Mídias Sociais e Utilitários no modo directory.

O modo directory só muda o que é ANUNCIADO — o conjunto principal curado que uma listagem pública (como a Extensão do Claude Desktop) mostra.

As descrições carregam o custo de cota, para que um agente possa fazer orçamento:

Pesquisar na web… operação upAPI web-search.post (Pesquisa). Custa 25 unidades da cota mensal por chamada.

Uma operação com falha retorna como um resultado de ferramenta normal com isError: true e texto começando com o código de erro público da upAPI — RATE_LIMITED, INVALID_INPUT, UPSTREAM_UNREACHABLE. Um limite de taxa também informa o tempo de espera em segundos. Nada sobre uma operação com falha quebra a sessão.

Nenhum outputSchema é declarado, deliberadamente: o MCP exige que um servidor que declare um retorne structuredContent correspondente, e essas saídas descrevem payloads ao vivo de terceiros. Um null inesperado transformaria uma chamada bem-sucedida em um erro de protocolo.

Use com Mastra

As ferramentas funcionam em um agente Mastra diretamente, sem um transporte MCP no meio. @mastra/core e @mastra/mcp são dependências pares opcionais — instale-as você mesmo, e importe os bindings do subcaminho /mastra. Nada mais neste pacote toca o Mastra, que é o que mantém um npm i @upapi/mcp simples (e o bundle da extensão de desktop construído a partir dele) pequeno.

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! }),
  }),
});

Reduza a tabela com filter quando um agente deve ver apenas parte do catálogo:

createUpapiTools({
  caller,
  filter: (op) => op.category === 'Search',
});

createUpapiMcpServer — Modo Código por padrão

createUpapiMcpServer constrói um MCPServer do Mastra (@mastra/mcp, também um par opcional). Sua superfície de ferramentas padrão é o Modo Código: search_tools + execute_typescript em vez de uma ferramenta por operação — medido no catálogo completo de 99 operações, tools/list cai de 111.016 bytes para 1.069 bytes (99 ferramentas → 2), porque a tabela não cresce mais com o catálogo.

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? }) encontra as operações que esta conexão pode alcançar e as retorna como assinaturas TypeScript declare function external_<name>(...).
  • execute_typescript({ code }) executa um programa TypeScript curto em um sandbox QuickJS isolado (@mastra/quickjs, outro par opcional — sem binário nativo, sem acesso a sistema de arquivos/rede/processo além das funções external_* injetadas). Agrupe várias operações em uma única viagem de ida e volta com Promise.all em vez de uma chamada de ferramenta cada. Encerrado após 30 segundos. Um programa que computa por mais de 1,5 segundos sem aguardar uma chamada external_*, ou por mais de 5 segundos no total em todos esses trechos, é interrompido com CPU_BUDGET_EXCEEDED: ..., porque o sandbox compartilha o loop de eventos do Node com todas as outras requisições que o processo atende. Precisa de quickjs-emscripten 0.31.0 (a versão exata que @mastra/quickjs 0.1.1 resolve) instalado ao lado. Ambos são carregados na primeira chamada execute_typescript, então um servidor que nunca executa uma (ou usa a superfície full) não precisa tê-los instalados.

Cada chamada external_* resolve para exatamente o mesmo objeto de ferramenta createUpapiTools(options) que a superfície full (abaixo) chama — não há um segundo caminho de autenticação. Uma chamada de operação negada ou com falha aparece dentro do sandbox como um Error("<CODE>: <message>") lançado, para que o próprio try/catch do programa convidado possa inspecionar e ramificar no código; argumentos que falham no schema de entrada de uma operação lançam INVALID_INPUT: <details> da mesma forma. Isso é separado de uma entrada execute_typescript malformada, que falha a própria chamada antes mesmo de o sandbox iniciar.

Defina MCP_TOOL_SURFACE (ou passe surface) para mudar o que é anunciado:

ValorAnunciaQuando usar
codemode (padrão)search_tools + execute_typescriptQualquer modelo que possa escrever algumas linhas de TypeScript
fullUma ferramenta por operação — a tabela createUpapiTools de hojeInterruptor de rollback, ou um cliente já construído para isso
bothA união dos doisExercitando ou migrando de uma superfície no meio da transição
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 no servidor carrega o contrato do Modo Código automaticamente sempre que uma ferramenta codemode está na tabela (codemode e both) — um modelo não foi instruído a escrever TypeScript contra search_tools/execute_typescript de outra forma.

Construa seu próprio servidor

caller é a única coisa que a tabela de ferramentas não fornece, que é o que permite que as mesmas ferramentas rodem 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 um servidor Request/Response padrão da web (rota Next.js, Worker, Hono), importe o handler do subcaminho /http — é assim que app.upapi.io/api/mcp é construído:

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 são como um host projeta sua própria autorização na tabela — a upAPI os mapeia para os escopos ops:execute e ops:read do token de acesso. Ambos padronizam para true, então um host sem um modelo de escopo não é afetado.

Prefira esse subcaminho em vez da raiz do pacote em uma implantação empacotada ou com rastreamento de arquivos: ele alcança apenas o SDK do MCP, enquanto a entrada raiz também puxa o servidor stdio. Nenhum alcança o Mastra — os bindings ficam atrás de @upapi/mcp/mastra precisamente para que uma build que nunca executa um agente Mastra nunca veja @mastra/core.

Relacionados

  • @upapi/sdk — o cliente HTTP tipado, e o catálogo de operações do qual a tabela de ferramentas deste pacote é gerada
  • upapi.io/docs — referência de operações

Onde o desenvolvimento acontece

Este repositório é o lar publicado de @upapi/mcp: é o que o npm instala, e issues e pull requests são bem-vindos aqui. A tabela de ferramentas é derivada do catálogo de operações em @upapi/sdk, que é ele próprio gerado a partir das definições privadas de operações da upAPI e sincronizado automaticamente — então o conjunto de ferramentas muda a montante. O servidor, a fachada, o mapeamento de erros e os testes nestes arquivos são escritos à mão e são o código a mudar.