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) | |
|---|---|---|
| Endpoint | npx @upapi/mcp | https://app.upapi.io/api/mcp |
| Auth | sua chave de API upapi_ | entre com sua conta upAPI (OAuth) |
| Execução | na sua máquina | na upAPI |
| Melhor para | scripts, CI, agentes auto-hospedados | Claude, 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_KEY | obrigatória | uma chave upapi_ |
UPAPI_BASE_URL | opcional | origem do gateway, padrão é https://api.upapi.io |
UPAPI_TOOL_MODE | opcional | compact (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.
| Ferramenta | O que faz |
|---|---|
search_ops | Encontra operações por intenção — retorna slug, descrição, parâmetros e custo de cota |
call_op | Executa 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 TypeScriptdeclare 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çõesexternal_*injetadas). Agrupe várias operações em uma única viagem de ida e volta comPromise.allem 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 chamadaexternal_*, ou por mais de 5 segundos no total em todos esses trechos, é interrompido comCPU_BUDGET_EXCEEDED: ..., porque o sandbox compartilha o loop de eventos do Node com todas as outras requisições que o processo atende. Precisa dequickjs-emscripten0.31.0(a versão exata que@mastra/quickjs0.1.1 resolve) instalado ao lado. Ambos são carregados na primeira chamadaexecute_typescript, então um servidor que nunca executa uma (ou usa a superfíciefull) 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:
| Valor | Anuncia | Quando usar |
|---|---|---|
codemode (padrão) | search_tools + execute_typescript | Qualquer modelo que possa escrever algumas linhas de TypeScript |
full | Uma ferramenta por operação — a tabela createUpapiTools de hoje | Interruptor de rollback, ou um cliente já construído para isso |
both | A união dos dois | Exercitando 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.