Guia para desenvolvedores · Model Context Protocol

Crie um pipeline de conteúdo automatizado com o servidor MCP da Endata

A Endata expõe todo o seu fluxo editorial como ferramentas MCP: perguntas, pesquisa, rascunhos, aprovações, publicação e compartilhamento. Este guia conecta um agente a ela e monta um pipeline que transforma a pergunta de um cliente em uma resposta publicada e com fontes, com uma pessoa confirmando a etapa que vai ao ar.

Pela equipe da EndataAtualizado em 10 min de leitura

A Endata tem dois servidores MCP. De qual você precisa?

Servidor do espaço de trabalhoServidor da publicação

Quase todo este guia trata do servidor do espaço de trabalho. O servidor da publicação não exige nenhuma configuração: ele passa a existir no momento em que você publica e é anunciado em /.well-known/mcp.json.

Passo 1 2 minutos

Crie uma chave de API com escopos

Em Configurações → Desenvolvedor → Chaves de API, crie uma chave apenas com os escopos de que o pipeline precisa.

As chaves pertencem a um projeto e começam com fsk_. Um proprietário as cria, e cada uma tem escopos. As ferramentas fora dos escopos da chave nem aparecem para o agente, então uma chave restrita também resulta em uma lista de ferramentas mais curta e clara.

EscopoO que permite

Para este pipeline, conceda editorial:read, editorial:write e publishing:manage. Deixe administration:manage e organization:manage desativados, a menos que o agente realmente gerencie domínios, integrações ou membros da equipe.

Passo 2 2 minutos

Conecte o seu cliente MCP

Adicione o servidor ao Claude Code, ao Codex ou a qualquer cliente que fale Streamable HTTP.

Claude Code

json
{
  "mcpServers": {
    "endata": {
      "type": "http",
      "url": "https://app.endata.com/mcp",
      "headers": { "Authorization": "Bearer ${ENDATA_API_KEY}" }
    }
  }
}
No .mcp.json, na raiz do seu projeto. Defina ENDATA_API_KEY no seu shell.

Codex

bash
[mcp_servers.endata]
url = "https://app.endata.com/mcp"
bearer_token_env_var = "ENDATA_API_KEY"
No ~/.codex/config.toml.

Seu próprio código

O servidor é Streamable HTTP sem estado e aceita apenas POST, então o SDK oficial se conecta sem nenhum tratamento de sessão. O pequeno auxiliar call abaixo é usado em todas as etapas seguintes.

javascript
// npm install @modelcontextprotocol/sdk
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from
  "@modelcontextprotocol/sdk/client/streamableHttp.js";

const publicationId = process.env.ENDATA_PUBLICATION_ID;
const client = new Client({ name: "answer-pipeline", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(
  new URL("https://app.endata.com/mcp"),
  { requestInit: { headers: {
    Authorization: `Bearer ${process.env.ENDATA_API_KEY}`,
  } } },
));

// Every tool takes { publicationId, input } and returns JSON as text.
async function call(name, input = {}, extra = {}) {
  const result = await client.callTool({
    name,
    arguments: { publicationId, input, ...extra },
  });
  const value = JSON.parse(result.content[0].text);
  if (result.isError) throw new Error(`${name}: ${value.message}`);
  return value;
}

Passo 3 1 minuto

Encontre as perguntas que valem uma resposta

Chame questions_list com o filtro to-answer ou adicione uma pergunta com question_create.

Uma pergunta é a unidade de trabalho: algo que um cliente pergunta e para o que o negócio deveria ter a melhor resposta. As perguntas vêm das sugestões da própria Endata, das lacunas do seu relatório de visibilidade em IA ou de você.

javascript
// Questions still waiting for an answer, highest priority first.
const { questions } = await call("questions_list", {
  filter: "to-answer",
  limit: 10,
});

// Or add one of your own: a gap from your AI Visibility report, say.
const added = await call("question_create", {
  text: "How much cyber insurance does a 40-person firm need?",
  customers: "Owners of professional services firms",
});

questions_list retorna questions, counts por status e um summary. Os filtros incluem to-answer, needs-update (respondida, mas as notícias mudaram ou a resposta ficou desatualizada), open e all. discovery_read dá a visão mais ampla: que parcela das perguntas dos clientes você já respondeu e o que responder em seguida.

Passo 4 Alguns minutos, sem supervisão

Pesquise e redija a resposta

Chame question_research para reunir evidências e escrever um rascunho com citações.

A pesquisa busca nos últimos 30 dias de notícias e fontes da web sobre aquela pergunta, guarda até oito evidências e escreve uma resposta que as cita. Ela roda em segundo plano e consome a cota mensal de respostas pesquisadas do plano.

javascript
// Research the question and draft its answer. This runs in the
// background and counts against the plan's monthly answers.
const question = questions[0];
await call("question_research", { questionId: question.id });

// Optional: add what only the business knows, attributed to it.
await call("question_perspective", {
  questionId: question.id,
  text: "We size cover from the client's largest single contract, not headcount.",
});

question_perspective é a etapa que a maioria dos pipelines pula e não deveria. Ela acrescenta a visão do próprio negócio, atribuída a um autor identificado, o que faz a resposta ser mais do que um resumo das páginas de outras pessoas.

Passo 5 2 minutos

Leia o rascunho e suas evidências

Chame question_read e answer_read e guarde o draftRevision que você revisou.

javascript
// When research is done ("question.researched" webhook, or poll),
// read the draft and the evidence behind it.
const detail = await call("question_read", { questionId: question.id });
const answer = await call("answer_read", { questionId: question.id });

console.log(answer.content);        // the draft
console.log(answer.pending);        // true: readers do not see it yet
console.log(answer.draftRevision);  // the exact revision you reviewed

É aqui que um agente mostra seu valor. Peça que ele confira o rascunho com as evidências retornadas por question_read, sinalize qualquer afirmação sem fonte e salve um rascunho melhorado com answer_update, que recebe o conteúdo e o expectedRevision em que se baseou, para que dois editores não sobrescrevam um ao outro. answer_preview retorna a página como ela seria publicada.

Passo 6 1 minuto

Publique, com uma pessoa no circuito

Chame prepare_action, mostre o resumo a uma pessoa e depois chame answer_publish com o token de confirmação.

Publicar, despublicar, compartilhar e fazer mudanças administrativas são ações marcadas como consequentes. Por padrão, a Endata não deixa uma chave sem supervisão executá-las. Há dois caminhos, e você deve escolher com critério:

Confirmar cada ação

prepare_action retorna um resumo e um token vinculado àquela entrada exata e ao estado atual, válido por 10 minutos. Mostre o resumo a uma pessoa; passe o token quando ela concordar.

Conceder escopos sem supervisão

Um proprietário pode permitir explicitamente que uma chave aja sem supervisão. Use isso em um pipeline em que você confia de ponta a ponta e mantenha os escopos da chave restritos.

javascript
// Publishing is consequential. Prepare the exact action first:
const prepared = await client.callTool({
  name: "prepare_action",
  arguments: {
    publicationId,
    operation: "answer_publish",
    input: { questionId: question.id, revisionId: answer.draftRevision },
  },
});
const { confirmationToken } = JSON.parse(prepared.content[0].text);

// Show the summary to a person. Once they agree, within 10 minutes:
const live = await call(
  "answer_publish",
  { questionId: question.id, revisionId: answer.draftRevision },
  { confirmationToken, requestKey: `publish-${answer.draftRevision}` },
);

requestKey torna a chamada idempotente: uma nova tentativa com a mesma chave e a mesma entrada retorna o primeiro resultado e não publica duas vezes. A resposta vai ao ar na hora em /questions/<slug> na publicação, e answer.url no resultado é o endereço dela.

Passo 7 Opcional

Compartilhe artigos e escute eventos

Use article_share para postar artigos nas redes conectadas e webhooks para reagir quando algo for ao ar.

O compartilhamento funciona com artigos, as matérias de notícias que a Endata escreve sobre os seus temas, e não com respostas. connections_list retorna as contas conectadas; article_share recebe um articleId, um connectionId, o seu commentary e quando enviar (now, at um horário ou quando published). É uma ação consequente, então vale a mesma regra de confirmação.

Os webhooks fecham o ciclo. Até 10 endpoints HTTPS por projeto recebem eventos assinados, como question.answered, question.updated, article.approved e share.sent. A entrega é pelo menos uma vez, com oito tentativas ao longo de cerca de 22 horas, então torne o receptor idempotente e verifique a assinatura:

javascript
import { createHmac, timingSafeEqual } from "node:crypto";

// Pass the exact, unmodified UTF-8 request body and request headers.
function verifyWebhook(rawBody, headers, secret) {
  const timestamp = headers.get("Webhook-Timestamp");
  const signature = headers.get("Webhook-Signature");
  if (!timestamp || !/^\d+$/.test(timestamp)) return false;
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
  if (!/^v1=[a-f0-9]{64}$/.test(signature || "")) return false;

  const expected = createHmac("sha256", secret)
    .update(timestamp + "." + rawBody, "utf8")
    .digest();
  const received = Buffer.from(signature.slice(3), "hex");
  return timingSafeEqual(expected, received);
}
// After verification, parse and validate the event.
// Atomically persist it with a unique constraint on Webhook-Id.
// Return 2xx after persistence; duplicate events should also return 2xx.
// Process asynchronously and reconcile current state through the API.

Deixe outros agentes lerem as suas respostas

Tudo o que você publica fica imediatamente disponível para qualquer agente, sem chave e sem trabalho de integração. Cada publicação serve um servidor MCP somente leitura com quatro ferramentas: search_answers, get_answer, list_questions e list_changes.

javascript
// No key. Any newsroom: yours, or one you want your agent to cite.
const newsroom = new Client({ name: "reader", version: "1.0.0" });
await newsroom.connect(new StreamableHTTPClientTransport(
  new URL("https://news.example.com/mcp"),
));
const hits = await newsroom.callTool({
  name: "search_answers",
  arguments: { q: "cyber insurance for small firms" },
});

O mesmo conteúdo também é servido como llms.txt, llms-full.txt, um JSON Feed em /answers.json e Markdown para qualquer resposta, bastando acrescentar .md ao endereço ou enviar Accept: text/markdown. Esse é o lado prático de ser visível para a IA: um assistente que sai procurando encontra uma resposta limpa e com fontes no formato que ele lê melhor.

Prefere REST? As mesmas operações estão lá

As ferramentas MCP e a API REST são geradas a partir de um único registro, então tudo o que está acima pode ser feito com POST https://app.endata.com/api/v1/publications/:id/operations/:operationId. As escritas recebem um cabeçalho Idempotency-Key, e as confirmações são preparadas em /publications/:id/confirmations.

  • GET /api/v1/operations lista todas as operações com o JSON Schema de cada uma, sem chave.
  • GET /api/v1/openapi.json é um documento OpenAPI 3.1 gerado a partir do mesmo registro.
  • Limites: 120 requisições por minuto por chave, corpos JSON de 1 MB (14 MB para envio de imagens).

Não há um SDK da Endata para instalar, e nenhum é necessário: use o SDK do MCP ou um simples fetch. A referência completa está na página para desenvolvedores.

O que o servidor MCP não faz

  • Ele não expõe o relatório de visibilidade em IA. Não há ferramenta para gerar um nem para ler as posições. Traga as lacunas como perguntas com question_create.
  • Ele não usa OAuth pessoal. Hoje só são aceitas chaves de API do projeto.
  • Ele não está no Solo. API, MCP e webhooks fazem parte do Business e do Agency.
  • Ele não contorna os limites do plano. Pesquisa e redação consomem a mesma cota mensal do app.

Perguntas frequentes

Qual é a URL do servidor MCP da Endata?

https://app.endata.com/mcp. É Streamable HTTP sem estado via POST, autenticado com uma chave de API do projeto enviada como Authorization: Bearer fsk_….

Quais clientes MCP funcionam com a Endata?

Qualquer cliente que suporte Streamable HTTP com cabeçalho bearer, incluindo Claude Code, Codex e os SDKs oficiais do Model Context Protocol.

Qual plano inclui MCP e API?

Business ($199 por mês) e Agency. O Solo não inclui API, MCP nem webhooks. Veja os preços.

Um agente pode publicar sem uma pessoa?

Só se o proprietário de um espaço de trabalho tiver concedido à chave escopos sem supervisão. Caso contrário, as ferramentas consequentes exigem um token de confirmação de prepare_action, que o seu cliente só deve obter depois que uma pessoa concordar.

Quantas ferramentas o servidor expõe?

77 operações mais prepare_action, abrangendo conteúdo publicado, artigos, publicação, pesquisa, perguntas, respostas, mídia, configurações, webhooks, equipe e widgets. Uma chave vê apenas as ferramentas que os seus escopos permitem.

Posso ler o meu relatório de visibilidade em IA por MCP ou pela API?

Hoje não. Nenhuma operação expõe o relatório. discovery_read e search_ai_read cobrem a parcela de perguntas respondidas, as visitas de referência de IA e as requisições de recuperação.

Existe um servidor MCP público para o conteúdo publicado?

Sim. Toda publicação da Endata serve um servidor MCP somente leitura e sem chave em /mcp, com search_answers, get_answer, list_questions e list_changes, que pode ser descoberto em /.well-known/mcp.json.

Existe um SDK ou uma especificação OpenAPI?

Não há um SDK específico da Endata. Há um documento OpenAPI 3.1 ativo em https://app.endata.com/api/v1/openapi.json e o catálogo de operações com JSON Schemas em /api/v1/operations.