Skip to main content
O UserKit fala Model Context Protocol, então um assistente compatível com MCP — Claude Desktop, Claude Code, Cursor e qualquer outro que leia uma configuração MCP — consegue responder perguntas sobre seus contatos, clientes, assinaturas e preços sem que você saia da ferramenta em que já estava. Não há nada para instalar. O servidor é um endpoint da API:
Ele é autenticado com uma chave de API comum (uk_sk_live_… / uk_sk_test_…), e há duas consequências disso que vale conhecer antes de colar uma chave em algum lugar.
A chave decide o ambiente, e nada mais decide. Nenhuma ferramenta aceita um argumento de ambiente. Uma chave uk_sk_test_… só consegue mostrar dados de teste — por isso conectar a chave de teste é a forma segura de experimentar, e isso não é uma configuração que alguém consiga convencer o modelo a mudar.
Uma chave de API é uma credencial de acesso total para todo o resto. A superfície MCP lê tudo e escreve só nos nove lugares listados abaixo, mas a mesma string funciona em qualquer endpoint de escrita em /v1. Trate o arquivo de configuração como qualquer outro lugar onde vive um segredo, e use uma chave criada para isso em vez da que seu backend usa — chaves são gratuitas, e uma chave por finalidade é uma chave que você revoga sozinha.

Conectar um cliente

No projeto onde o assistente vai trabalhar:
Isso escreve a configuração por você — e um AGENTS.md com as poucas regras do UserKit que compilam quando quebradas, escolhidas conforme o que o projeto é. Ele não escreve chave nenhuma: a configuração nomeia a variável USERKIT_API_KEY e lê do ambiente, então o arquivo pode ser commitado. Rodar de novo não muda nada, e ele é dono de um bloco delimitado em vez do arquivo — as suas próprias diretrizes e os seus outros servidores MCP ficam intactos. Escolha os clientes com --mcp: claude escreve .mcp.json, cursor escreve .cursor/mcp.json e vscode escreve .vscode/mcp.json. Para fazer à mão, todo cliente guarda os mesmos três fatos: um nome, a URL e o header. Dois detalhes mudam de um para o outro, e os dois falham em silêncio: o VS Code guarda os servidores sob servers onde os outros usam mcpServers, e só expande a sintaxe dele, ${env:NOME} — um ${NOME} puro é escrito literalmente, e o header carregaria os caracteres em vez da chave.
Reinicie o cliente e ele vai listar noventa ferramentas. Pergunte alguma coisa — “quantos contatos entraram no ambiente de teste?” — e ele escolhe uma.

O que ele faz

tools/list é o contrato, e quem responde é o servidor em execução — se alguma ferramenta aceitar um argumento que esta página não menciona, o cliente já sabe dele. Cada ferramenta também declara o formato da resposta, então o cliente pode entregar o resultado a um código em vez de reinterpretá-lo.

As nove coisas que ele muda

Um assistente escreve em exatamente nove lugares: a sua central de ajuda, o catálogo que você vende, os seus termos, o seu changelog, os seus funis, o seu onboarding, os seus pontos, os seus templates de mensagem e os papéis dentro dos seus clientes. Todo o resto responde perguntas.

A central de ajuda

Nove ferramentas: create_help_collection, update_help_collection, delete_help_collection, create_help_article, save_help_article_version, update_help_article, publish_help_article, unpublish_help_article e delete_help_article.
Escrever um artigo e publicá-lo são chamadas separadas. Um artigo novo ou editado é um rascunho — ninguém fora da sua organização consegue ler até que publish_help_article nomeie uma versão para entrar no ar. Então um assistente que escreveu algo errado ainda não disse nada errado aos seus clientes, e a revisão é uma etapa de verdade em vez de um combinado.
Três coisas decorrem de como a central de ajuda é construída, e o assistente vai falar das três porque as próprias ferramentas dizem isso nas respostas. Todo save é uma versão nova, e nada é sobrescrito. O histórico é o registro inteiro do que um artigo já disse, “restaurar” é salvar um corpo antigo de novo, e mesmo apagar um artigo é um ato diferente de tirá-lo do ar — o unpublish_help_article guarda cada palavra e o publish_help_article devolve todas elas. A central de ajuda é da organização, não de um ambiente. Existe uma só, compartilhada por live e test — então, diferente de todas as outras ferramentas daqui, estas respondem scope: "organization" e não carregam environment. Não há uma segunda cópia para ir consertar. Publicar e despublicar entram na sua trilha de auditoria, no nome da chave de API que fez, e não no de uma pessoa. Em Configurações → Auditoria a entrada aparece como chave de API · <nome da chave>, e é por isso que vale criar uma chave para o assistente em vez de emprestar a que seu backend usa: a trilha só consegue ser tão específica quanto a credencial é. Mais nove ferramentas, para os planos, preços e recursos que você vende — não o plano em que você está com a UserKit: create_catalogue_plan, update_catalogue_plan, create_catalogue_price, reprice_catalogue_price, archive_catalogue_price, create_catalogue_feature, update_catalogue_feature, set_catalogue_plan_feature e remove_catalogue_plan_feature.
Isto é a sua página de preços. Diferente da central de ajuda, estas ferramentas mudam o que clientes reais veem cotado — no ambiente a que a sua chave pertence, então uma chave de teste só consegue tocar o catálogo de teste. Peça ao assistente que leia o get_catalogue e diga o que vai fazer antes de deixá-lo escrever.
Um preço nunca é editado, e é isso que torna seguro entregar isso a um assistente. Uma assinatura aponta para a linha do preço, e essa linha é o registro do que alguém concordou em pagar — o banco recusa qualquer alteração nela. Mudar quanto um plano custa é o reprice_catalogue_price, que arquiva a oferta antiga e cria a nova em um passo só — e quem já assina não é movido para o valor novo. Essas pessoas continuam no preço que aceitaram; mover alguém é uma troca de plano que ela consente no seu gateway de pagamento. Nada é apagado. Um plano ou um recurso é arquivado, o que tira do que está à venda e se desfaz com a mesma chamada e archived: false. Um preço é arquivado, e recolocar a oferta é criar uma nova. A única exceção é tirar um recurso de um plano, que remove aquela célula da matriz — recolocar significa declarar os termos de novo. Duas coisas são permanentes e pedir é recusado em vez de ignorado: a key de um plano e a de um recurso (a string que o seu próprio código compara) e como um recurso é medido. Um recurso medido de outro jeito é outro recurso. O que ele não alcança é o seu gateway de pagamento. Nenhuma ferramenta guarda, lê ou usa a credencial que cobra um cartão — conectar um provedor é só do owner e vive no painel — e nada aqui cria cobrança, faz reembolso ou mexe na assinatura de alguém. Toda escrita no catálogo entra na sua trilha de auditoria no nome da chave, exatamente como as da central de ajuda.

Os termos

Cinco ferramentas: create_legal_document, update_legal_document, save_legal_version, publish_legal_version e delete_legal_document, mais list_legal_documents, get_legal_document e get_legal_version. Escrever e publicar também são atos separados aqui, e a separação pesa mais do que em qualquer outro ponto desta superfície: um documento novo e todo save_legal_version são rascunhos, e nada muda para ninguém até publish_legal_version.
Uma versão publicada é congelada no banco e não pode ser editada nem retirada. Publicar é o ato: pode ser datado para a frente, e quem é perguntado de novo é decidido pela versão em vigor mais alta que declarou mudança material. delete_legal_document só funciona enquanto nada foi publicado — depois disso, tirar um documento de circulação é arquivá-lo.
Um documento marcado como required é reportado como bloqueante onde quer que os aceites da pessoa sejam lidos, e nada além disso — ele nunca desconecta ninguém e nunca bloqueia /v1/contact/token; o que fazer com isso é decisão do seu produto. Publicar termos precisa significar “todo mundo é perguntado”, nunca “todo mundo fica trancado do lado de fora”.

O changelog

Quatro ferramentas: create_changelog_post, update_changelog_post, publish_changelog_post e delete_changelog_post, mais as duas leituras da tabela acima. Escrever um post e anunciá-lo são chamadas separadas, como na central de ajuda — um post novo é um rascunho que ninguém fora da sua organização vê. O que é diferente aqui, e é a aresta mais afiada desta superfície inteira:
Não existe despublicar. O publish_changelog_post coloca o post na sua página pública de changelog — um documento que uma CDN pode guardar —, faz o badge de não lidos do widget contar, e entrega changelog_post.published para os seus webhooks. O único caminho de volta é o delete_changelog_post, que não desfaz nada disso e ainda leva junto o estado de leitura de todo mundo. Um assistente deve publicar porque você pediu que aquele release fosse anunciado, nunca para organizar uma lista de rascunhos.
Um post direcionado não vai para a página pública. O segment_id (ou o feedback_post_id, para quem votou num pedido) estreita a audiência, e um post estreitado só é alcançável por quem está logado no seu produto — o documento público não tem leitor para resolver, e responder um por identidade informada pelo chamador o transformaria num oráculo de quem está em qual segmento. Então um assistente que mira um post num segmento e depois olha a página pública vai, com razão, não ver nada lá. O list_segments é de onde esses ids saem, e ele leva a regra de cada segmento junto com o nome — então o assistente escolhe a audiência pelo que ela significa, e não pelo nome que ela tem. Todo o resto desta superfície continua sem mudar nada — veja abaixo.

Os funis

Três ferramentas: create_funnel, update_funnel e delete_funnel, mais as duas leituras da tabela acima. Um funil é uma pergunta salva — um nome, uma lista ordenada de nomes de evento e uma janela em dias — e não uma medição. Ele não guarda número nenhum: a queda entre um passo e o seguinte é recalculada a partir dos eventos crus toda vez que alguém abre o gráfico. É por isso que esta é a mais branda das quatro exceções: um delete_funnel errado destrói a pergunta, que você digita de novo, e nada do que alguém mediu. Duas coisas valem saber antes de pedir uma edição.
O funil é da organização, não do ambiente. Existe um só, live e test compartilham a definição, e só os números são por ambiente. Uma chave de teste editando um funil está editando o mesmo funil que o live lê — o que é o oposto do changelog, onde um post pertence a um ambiente e a chave do outro não o alcança.
Mexer nos passos reescreve o passado. Como não há histórico guardado para discordar da definição nova, mudar a ordem ou trocar um evento re-responde também os meses anteriores: um gráfico que alguém printou semana passada não vai mais reproduzir. O update_funnel troca a lista de passos inteira em vez de remendá-la, então leia o funil antes com o get_funnel. Os números em si não estão aqui: eles pedem um intervalo e um ambiente, e são o gráfico do painel. Nenhuma ferramenta desta superfície calcula um.

O onboarding

Seis ferramentas: create_checklist, update_checklist, delete_checklist, add_checklist_step, update_checklist_step e delete_checklist_step, mais as duas leituras da tabela acima. Esta é a exceção cuja falha é a mais silenciosa, e as ferramentas são de propósito mais estreitas que o painel por isso. Um post de changelog escrito errado está errado numa página que alguém lê; um passo escrito errado não produz nada — um tipo de evento que ninguém publica é um passo que nunca fica verde, e você descobre semanas depois numa taxa de conclusão que não explica.
Nada aqui liga um checklist. O create_checklist cria um desligado, e nenhuma ferramenta aceita active. Ligar é o momento em que a medição começa para o público inteiro de uma vez, e isso continua sendo coisa que uma pessoa faz no painel, depois de olhar os passos.
Um passo event nomeia um fato nosso e um nome errado é recusado. Um passo product_event nomeia um seu — o que o seu produto manda pelo track() — e esse vocabulário é aberto, então nada pode recusar um nome por não existir. O list_checklists traz sightings para esses: um zero quer dizer que este ambiente nunca recebeu aquele evento, o que quase sempre é erro de digitação. Passos são adicionados e removidos, nunca reapontados. O que satisfaz um passo — o tipo, o evento, a feature — não é editável aqui nem no painel: as pessoas já têm progresso gravado contra ele, e mudar o que ele significa deixaria linhas dizendo que alguém fez algo que nunca foi pedido. Um passo esperando o fato errado se apaga e se cria de novo, o que perde exatamente o progresso que deve perder. E nada satisfaz um passo, tampouco. Nenhuma ferramenta desta superfície marca o onboarding de alguém como feito, porque nenhuma existe em lugar nenhum: um passo é satisfeito por um fato que chega no bus ou por um direito do plano. O update_checklist também carrega o formato do guia — unlocks_after põe um checklist atrás de outro, e selectable faz dele uma escolha que a pessoa faz por si. Dois checklists esperando um pelo outro são recusados: nenhum dos dois abriria nunca. O snooze_days é quanto tempo um fechar dura: sete por padrão, 0 para o checklist que é mesmo uma oferta única. Quem dispensa um guia de setup em geral quer dizer “agora não”, então o cartão volta — e mudar o número nunca mexe num adiamento em curso. Tanto o checklist quanto o passo aceitam hint_pending e hint_done: o que a linha diz no hover antes e depois, porque a mesma linha quer dizer coisas diferentes nos dois estados. O checklist aceita um terceiro, o hint_locked — um cadeado diz ao leitor qual porta, não por que ela existe. Um passo não tem estado travado, então não tem o terceiro. O passo também aceita action_url, um caminho do app do inquilino ou uma URL http(s) absoluta, que faz a linha inteira virar link. Pôr um em quase todo passo é a melhoria mais barata que um guia tem: uma checklist que nomeia o trabalho e esconde a porta faz o leitor navegar duas vezes.

Os pontos

Doze ferramentas: create_point_rule, update_point_rule, delete_point_rule, create_point_level, update_point_level, delete_point_level, create_achievement, update_achievement, delete_achievement, create_gamification_metric, update_gamification_metric e delete_gamification_metric, mais as seis leituras da tabela acima. Uma métrica é uma unidade sua ao lado do saldo de pontos — cursos concluídos, e-mails enviados —, creditada pelas mesmas regras através do mesmo extrato. Criar uma não muda nada sozinha: uma métrica que nenhuma regra credita fica em zero para todo mundo, então a ordem que funciona é métrica, depois regra, depois nível.
Nenhuma delas dá pontos a alguém. Conceder é o POST /v1/points, um ato deliberado do seu back-end com uma request_key obrigatória. Nenhuma ferramenta daqui aceita contact_id, external_id ou amount — configurar o que o produto recompensa é um rascunho que alguém revisa; pagar alguém não é.
O award_limit é obrigatório e recusado na própria ferramenta, não só no banco. É a diferença entre esta exceção e as outras oito: “recompense quem usa o app” é uma frase que parafraseia direto numa regra apontada para o evento mais frequente do seu produto, e uma regra sem teto escreve uma linha de extrato por acontecimento, para sempre. Regra e conquista nascem desligadas — mas, ao contrário do checklist, o update_point_rule e o update_achievement conseguem ligar. A assimetria é a retroatividade: ligar um checklist começa a medir um público contra passos que parte dele já pode ter satisfeito, enquanto uma regra não paga o passado — ligar começa a contar fatos que ainda não aconteceram, e desligar não tira nada do que já foi ganho. Um nível não tem interruptor nenhum: ele não dispara, ele é o que um saldo quer dizer. O que uma regra escuta e o que uma conquista exige não mudam. key, kind e event_type de um lado; kind, rule_id, threshold e segment_id do outro — recusados com uma frase, nunca ignorados em silêncio. As linhas já escritas dizem “você ganhou isto por X”, e a medalha na estante de alguém diz “você fez isto”. Repreçar é permitido e nunca é retroativo. Os três apagares são diferentes entre si, e cada resposta diz qual é qual. Apagar uma regra guarda o extrato — cada linha carrega o nome que a regra tinha na hora — e a resposta traz ledger_kept; é recusado enquanto uma conquista contar aquela regra, e o erro diz quantas. Apagar um nível só perde o registro de quem foi parabenizado por alcançá-lo. Apagar uma conquista é o único que tira algo das pessoas: as liberações vão junto, e a resposta traz unlocks_removed com o número — lido antes de apagar, porque depois não há mais o que contar.

Os templates de mensagem

Seis ferramentas: list_message_templates, get_message_template, create_message_template, update_message_template, restore_message_template_version e archive_message_template. São as palavras que o seu produto manda — o texto que o cliente lê. Por isso elas só existem aqui desde que uma edição virou uma versão: o que estava no ar continua guardado, e restore_message_template_version traz de volta. Uma paráfrase infeliz é um restore de distância, e não uma frase perdida. Escrever um template não manda nada. Uma notificação sai quando o seu backend chama /v1/notifications nomeando a key; uma campanha sai quando alguém a arma. Nenhuma ferramenta daqui faz as duas coisas, e essa é a porta que fica fechada: um assistente que escrevesse o texto e o disparasse colocaria uma paráfrase na frente de uma audiência. update_message_template substitui o corpo inteiro, então leia com get_message_template antes — uma edição feita sem ler descarta o que ela não sabia que existia. Os campos omitidos vêm da versão em uso, então mudar só o assunto mantém o corpo. Não existe apagar. Um template nomeia o que as pessoas receberam, então sair do seletor é archive_message_template e a linha continua resolvendo o histórico. E os templates da plataforma — a sequência de cobrança — são recusados: aquela sequência não pode ser pausada, e o texto dela também não é seu para reescrever por aqui.

Os papéis dentro dos seus clientes

Seis ferramentas: list_customer_roles, list_customer_role_versions, create_customer_role, update_customer_role, restore_customer_role_version e delete_customer_role. São os papéis que as pessoas dos times dos seus clientes têm, por ambiente. owner e member são semeados em todo ambiente e não podem ser apagados nem renomeados; tudo ao lado deles é vocabulário seu. A lista de permissões de um papel guarda dois desses vocabulários. Uma permissão que começa com $ precisa ser uma das quatro capacidades reservadas que o UserKit avalia — $team.manage, $billing.manage, $keys.manage e $webhooks.manage — e qualquer outra coisa nesse namespace é recusada em vez de armazenada. Tudo sem prefixo é seu: guardado, carregado no JWT do contato, e nunca lido por nós.
Uma edição é uma versão nova, nunca uma sobrescrita, que é o que torna isto admissível aqui. O update_customer_role substitui o conjunto inteiro de permissões e move a cabeça do papel para uma versão imutável nova, então o conjunto que você substituiu continua em list_customer_role_versions e o restore_customer_role_version o traz de volta numa chamada.
Duas edições são recusadas com uma frase. O papel owner não pode abrir mão de $team.manage — a guarda que mantém um time administrável roda quando uma associação muda, então tirar isso aqui deixaria todo time do ambiente sem ninguém que consiga administrá-lo. E um papel que alguém tem no momento não pode ser apagado. A key é imutável pelo motivo da key de um plano: é a string que o seu próprio código compara e a que o JWT carrega, então renomeá-la quebraria o seu portão sem erro nenhum em lugar nenhum. Renomear para exibição é o name, que muda à vontade.

Prompts, que são o trabalho e não o dado

O servidor também serve prompts: as tarefas que as pessoas de fato trazem para esta API, escritas uma vez. Clientes que suportam isso desenham cada uma como algo que você escolhe — o Claude Code mostra como slash command. Eles são renderizados a cada chamada em vez de serem texto fixo, e é essa a razão de morarem no servidor em vez de num plugin que você instala. O integrate_userkit já sabe quais chaves o ambiente tem e se o segredo de identidade já foi lido, então o assistente é orientado a ligar um boot assinado em vez de inventar uma tela de sign-in que esta API não responde. O plan_go_live diz em voz alta se a chave que você conectou consegue enxergar o ambiente sobre o qual você está perguntando. Nenhum deles carrega chave, pelo motivo da seção logo abaixo.

O que ele deliberadamente não faz

Não muda nada fora dos nove lugares acima. Nenhuma ferramenta cria, atualiza, apaga ou funde um contato, um cliente ou uma assinatura, e nenhuma muda configuração. Isso não é uma etapa do trabalho: quem chama é um modelo agindo sobre uma frase que alguém digitou, e “dá uma limpada nos contatos duplicados” está a uma paráfrase de uma fusão que não tem volta. Os atos continuam todos na API comum, onde uma pessoa escreveu a chamada. As exceções são admitidas pelo que uma chamada errada consegue destruir. A central de ajuda toca prosa e um ponteiro: toda edição é uma versão nova em vez de uma sobrescrita, e o pior resultado alcançável é texto numa página de ajuda. O catálogo descreve o que você vende sem conseguir reescrevê-lo: preços são imutáveis, planos e recursos são arquivados em vez de apagados, e o que um cliente concordou em pagar está fora de alcance por construção. O changelog é prosa de novo, com o único ato que não tem oposto — e é por isso que publicar diz isso na própria ferramenta e criar sempre escreve um rascunho. O funil é uma pergunta salva sobre dados que ele não pode tocar: apagar um custa a definição, nunca a medição. Os templates de mensagem e os papéis de cliente estão aqui pelo mesmo motivo um do outro: uma edição escreve uma versão imutável nova e move um ponteiro, então o que estava no ar fica a um restore de distância em vez de perdido. Os termos são os mais estritos dos nove, e é publicar que pesa — escrever é sempre rascunho, uma versão publicada nunca pode ser editada nem retirada, e a ferramenta diz isso antes de agir. Todas passam pelo mesmo teste de permissão, que é o que mantém isto honesto: criar uma chave de API precisa de owner ou admin, e cada uma dessas escritas já estava ao alcance de quem tem esses papéis. Uma ferramenta que desse a quem tem chave alguma coisa que a sessão não daria não entra aqui — é exatamente por isso que a trilha de auditoria, que é só do owner, fica de fora. Não manda nada para a caixa de entrada de ninguém. Publicar uma nota de versão não envia e-mail para os seus usuários: a página de changelog e o badge do widget são coisas que eles vêm ler. Nenhuma ferramenta desta superfície envia e-mail. Não move dinheiro. Nenhuma cobrança, nenhum reembolso, nenhuma troca de plano na assinatura de alguém e nenhum acesso às credenciais do seu gateway de pagamento — conectar um provedor é só do owner e fica no painel, onde uma pessoa colou a chave. Não lê a sua trilha de auditoria. audit:read é só do owner — o registro do que um administrador fez não é do administrador — e uma chave de API não carrega papel nenhum. Servir a trilha aqui levaria registros exclusivos do owner para fora através de uma credencial que qualquer pessoa capaz de criar chaves já tem. Não responde com credencial. Nenhuma chave secreta, nenhuma chave publicável, nenhuma sessão, nenhum token de uso único. Uma conversa com um assistente é armazenada, resumida e renderizada onde quer que o cliente rode, o que faz dela o último lugar onde uma credencial deveria ser impressa.

Lendo as respostas

Três coisas costumam surpreender, e as três são deliberadas. search_docs responde seções, não páginas, e responde lista vazia quando não acha nada. Essa lista vazia é uma resposta de verdade — quer dizer que esta documentação não cobre a pergunta, o que vale ouvir em vez de ser preenchido pela memória que o assistente tem da API de auth de outro produto. Ele busca em uma árvore de idioma por vez (en por padrão, pt-br sob pedido), e o índice que ele lê viaja junto com o deploy, então o que ele diz vale para a API com a qual você está falando. run_doctor tem um terceiro status, e ele não é aprovação. Cada verificação responde ok, attention ou unknown, e unknown quer dizer que não deu para saber — o conjunto de chaves é servido por CDN, então uma busca respondida por um cache nunca chegou até nós, e “nunca vimos” não é “nunca foi buscado”. Uma verificação que não se aplica a este ambiente fica de fora da lista em vez de responder ok. Assistentes resumem, e o resumo a vigiar é o que transforma quatro ok e dois unknown em “está tudo funcionando”. active_contacts_usage responde zero em ambiente de teste, com counted: false ao lado. Contatos de teste nunca são medidos, então esse zero é uma afirmação sobre cobrança e não sobre os seus usuários. Aponte o assistente para uma chave live quando a pergunta for “quantos usuários ativos temos”. Os valores estão em unidades menores. Um preço traz amount_minor e currency_exponent, então 1000 é R$10,00 e também ¥1000. O assistente tem os dois números; peça que ele formate, não que divida por cem.

Conferindo a conexão sem um cliente

O MCP Inspector fala com o endpoint direto, então ele responde “é meu ou é deles” antes de você ir procurar no log de um editor:
Conecte com transporte Streamable HTTP, a URL https://api.userkit.dev/mcp e um header Authorization de Bearer uk_sk_test_…. Se as ferramentas aparecerem lá e não no seu editor, o problema é o arquivo de configuração do editor; se não aparecerem em nenhum dos dois, é a chave.

Quando não funciona

O cliente conecta e não lista ferramenta nenhuma. Quase sempre é o header. O endpoint responde 401 com o envelope de erro de sempre quando a credencial falta ou não é uma chave uk_sk_… — uma chave publicável ou uma sessão do painel são recusadas aqui, e a mensagem diz qual das duas você mandou. Está tudo vazio. Confira qual chave você colou. Uma resposta vazia vinda de uma chave de teste é a fronteira de ambiente funcionando, não uma leitura quebrada; as ferramentas dizem em toda resposta para qual ambiente responderam. O assistente diz que bateu no limite. O endpoint MCP carrega o mesmo limite por chave do resto da API — 1000 requisições por minuto por chave, com um teto de 3000 por minuto no ambiente inteiro. Um agente percorrendo uma lista grande em laço é exatamente o chamador que encontra esse limite. Faça uma pergunta mais estreita, ou dê ao agente uma chave própria para que uma varredura longa não gaste a cota do seu backend.