Pular para o conteúdo
Entrar Lista de espera
Docs/Servidor MCP

Servidor MCP do Praeko

Um endereço, https://praeko.app/mcp, e uma de duas credenciais: a mesma chave de API da REST ou o login OAuth do seu agente. O agente lê estas docs, consulta a sua conta e, com a sua aprovação, cria, agenda, edita e cancela posts. Toda escrita que publica ou muda conteúdo tem dois passos: nada acontece na primeira chamada.

18 ferramentasStreamable HTTP, só POSTChave Bearer ou OAuthEscrita em dois passos

O que é

O MCP (Model Context Protocol) é o jeito padrão de um agente de IA chamar ferramentas. O servidor do Praeko roda no mesmo endereço da API e não guarda sessão: cada chamada é um POST com JSON-RPC e a resposta é um objeto JSON. Por dentro, cada ferramenta chama a mesma rota REST que você chamaria, com o contrato em inglês (X-Praeko-Contract: en). Por isso a validação, o escopo, o isolamento por workspace e os erros são os da API, e os nomes de campo são os do contrato.

Uso Ferramentas
Ler as docs search_docs, read_page: busca e leitura das rotas (corpo, exemplo, erros) e de guias curtos, na versão atual.
Consultar a conta list_channels, list_media, get_media, list_posts, get_calendar, get_insights, get_retention, get_usage.
Agir, sempre em dois passos create_post, schedule_post, update_post, cancel_post, upload_media, create_idea.
Enviar um arquivo local create_media_upload, complete_media_upload: o servidor prepara o envio e o agente roda o curl no shell dele (um passo só: criar o espaço não publica nada).
Fora do servidor, de propósitoWebhooks, chaves de API, conexão de canal (o login nas redes), publicar agora, comentários e respostas não existem como ferramenta: ficam no painel e na API. O arquivo nunca passa pela conversa com o agente: se ele tem shell, usa create_media_upload (veja "Arquivo local"); sem shell, upload_media com uma URL pública.

Dois servidores MCP: o remoto publica, o local faz o vídeo

Um agente pode usar os dois ao mesmo tempo. Este, praeko, é o remoto: roda em praeko.app/mcp e é o único que cria, agenda, edita e cancela posts. O praeko-studio é o servidor local do Praeko Studio (@praeko/studio-mcp): roda na sua máquina por stdio, serve a um agente sem terminal e nunca publica. Precisa de Node, de Chrome/Remotion para renderizar e das suas chaves, tudo no seu computador.

O fluxo completo: criar e renderizar o vídeo no servidor local, subir o resultado com studio_upload (devolve só o mediaId, em duas etapas) e publicar com create_post neste servidor, com a sua aprovação. Detalhes e a lista das 14 ferramentas locais em Studio no Claude Desktop: o servidor MCP local.

Conectar

O endpoint aceita duas credenciais, sempre em Authorization: Bearer … e em toda chamada: uma chave de API (praeko_…), que você cria e cola na configuração do agente, ou um token OAuth (mcpat_…), que o agente obtém sozinho depois que você entra e aprova a conexão. Os dois dão as mesmas ferramentas, com o mesmo escopo e a mesma confirmação em dois passos.

Dados de conexão
URL            https://praeko.app/mcp
Transporte     Streamable HTTP (só POST; sem sessão, sem stream)
Autenticação   Authorization: Bearer praeko_…   (chave de API, em TODA chamada; nunca na URL)
               Authorization: Bearer mcpat_…    (token OAuth, obtido pelo agente no login)
OAuth          https://praeko.app/.well-known/oauth-protected-resource/mcp
Credencial Quando usar Como
Chave de API Agentes de terminal e editor que aceitam cabeçalho (Claude Code, Codex, Cursor, Gemini CLI, opencode e outros), automações e o envio de arquivo local pelo shell. Crie a chave e configure o cabeçalho (abaixo).
Login OAuth Conectores que só falam OAuth (Claude.ai, Claude Desktop e mobile) e qualquer agente que prefira entrar sem colar chave, como o Claude Code. Informe só a URL; o agente abre a tela de consentimento (abaixo).

Com chave de API

Crie a chave no painel (Desenvolvedores, Chaves de API) ou com praeko key create (que exige uma chave admin). Escopo read basta para ler; as ferramentas que escrevem pedem write ou admin. Guarde a chave em variável de ambiente, nunca em arquivo versionado. Cada agente registra o servidor de um jeito: escolha o seu em Agentes de IA e copie o bloco pronto.

Com login (OAuth)

Adicione https://praeko.app/mcp no agente sem cabeçalho nenhum. A primeira chamada recebe 401 com resource_metadata no WWW-Authenticate; o agente descobre o servidor de autorização do Praeko e abre o navegador. Não há chave para copiar nem para vazar.

1. Adicionar a URLNo Claude.ai ou no Claude Desktop, um conector personalizado com https://praeko.app/mcp. No Claude Code, claude mcp add --transport http praeko https://praeko.app/mcp e depois /mcp.
2. Entrar no PraekoO navegador abre o painel. Se você ainda não entrou, entra como sempre (Google, senha ou passkey, mais a verificação em duas etapas, se estiver ligada).
3. ConsentimentoA tela "Conectar {agente} ao Praeko" mostra o nome do aplicativo, o endereço de retorno, o workspace e o acesso (Leitura ou Escrita). Você escolhe e clica em Permitir ou Negar.
4. ConectadoO agente volta com o token e passa a chamar as ferramentas. A conexão aparece em Conexões de agentes, no painel.
Claude Code com login, sem chave
# registra o servidor sem cabeçalho; o login acontece no navegador
claude mcp add --transport http praeko https://praeko.app/mcp
# dentro do Claude Code: /mcp, escolha praeko e entre
Ponto Como funciona
Acesso Leitura = escopo read (as dez ferramentas de leitura e docs). Escrita = escopo write (as dezoito). admin nunca é concedido por OAuth: chaves de API, canais, membros e configurações ficam fora do alcance do agente. O cliente pede um teto e a tela deixa você escolher esse acesso ou menos; sem pedido, vale Leitura.
Escopo efetivo O menor entre o que você concedeu e o que o seu papel no workspace permite hoje. Quem perde poder no workspace perde também no agente.
Tokens Token de acesso mcpat_… vale 1 hora; o de renovação mcprt_…, 30 dias, e é trocado a cada uso. Reapresentar um token de renovação já usado revoga a conexão inteira (o agente precisa entrar de novo). O servidor guarda só o hash.
Onde o token vale Só no /mcp. A REST e o painel recusam o token OAuth; para eles, use uma chave de API.
Gerenciar e revogar No painel, em Desenvolvedores, Chaves de API, seção Conexões de agentes: aplicativo, acesso, pessoa e último uso, com o botão Revogar, que corta o acesso na hora. Cada pessoa vê e revoga as próprias conexões; o admin do workspace vê e revoga todas. Autorizar de novo o mesmo aplicativo substitui a conexão anterior.
Padrões OAuth 2.1 só com cliente público: código de autorização com PKCE S256 obrigatório e resource (RFC 8707). Descoberta por Protected Resource Metadata (/.well-known/oauth-protected-resource/mcp) e pelos metadados do servidor de autorização (/.well-known/oauth-authorization-server). Registro de cliente por Client ID Metadata Document (o client_id é uma URL https) ou por registro dinâmico (RFC 7591, POST /oauth/register). A resposta de autorização traz iss (RFC 9207).
Endereço de retorno https, ou http só em localhost, 127.0.0.1 e [::1] (porta livre, como pede a RFC 8252). Esquemas próprios como cursor:// e vscode:// são recusados: nesses clientes, use a chave de API.
Cabeçalho fixo ganha do loginNo Claude Code, um Authorization configurado tem precedência sobre o OAuth: se a chave for recusada, ele não cai para o login. Para usar o login, registre o servidor sem --header. Com o ChatGPT, o login por OAuth ainda não foi conferido na documentação da OpenAI.

Respostas de autenticação

Situação Resposta
Sem Authorization 401 com WWW-Authenticate: Bearer realm="Praeko MCP", scope="read write", resource_metadata="https://praeko.app/.well-known/oauth-protected-resource/mcp".
Chave ou token desconhecido, revogado ou vencido 401 com error="invalid_token" e o mesmo resource_metadata no WWW-Authenticate.
Escopo insuficiente para a ferramenta 403 com WWW-Authenticate: Bearer error="insufficient_scope", scope="write" (e o resource_metadata).
Cookie do painel Não vale aqui: só chave de API ou token OAuth.
GET, DELETE ou outro método 405 com Allow: POST.
Origin que não é do Praeko nem localhost 403 (proteção contra DNS rebinding). Cliente de linha de comando não manda Origin.
Passou de 300 requisições por minuto 429. O limite é o mesmo da REST, contado por chave de API ou por conexão OAuth.

Ferramentas

Dezoito ferramentas. A lista que o agente recebe em tools/list varia com o escopo: read vê as dez de leitura e docs; write e admin veem as dezoito (o servidor não expõe nada a mais para admin: evite admin em agente). A coluna "O agente recebe" é a descrição literal, em inglês, que o servidor entrega; o texto de dois passos que fecha as seis ferramentas que publicam ou mudam conteúdo está logo depois da tabela. create_media_upload e complete_media_upload são as únicas escritas sem dois passos (veja "Arquivo local").

Ferramenta Escopo e anotações O agente recebe Argumentos
search_docs read somente leitura Search the Praeko API documentation (routes, fields, enums, errors, guides). Returns the best pages with a snippet; open one with read_page. Use it before building a create_post or update_post body. query (obrigatório, até 200 caracteres), limit (1 a 20, padrão 8)
read_page read somente leitura Read one documentation page in full (a route with its body schema, example and errors, or a guide). Ids come from search_docs: route:posts.create, guide:overview, guide:mcp-two-step... id (obrigatório)
list_channels read somente leitura List the connected channels (one item per account; default marks the one used when a post item has no channel), with state and slots count. Use the channel ids in create_post. nenhum
list_media read somente leitura List the media library (last 100 items): id, type, name, state, size and duration. Use a ready media id in create_post. type (video, cover ou image)
get_media read somente leitura One media item of the library: state (uploading or ready), type, size and, when ready, publicUrl, durationMs, width and height. Use it to check a media id (for example after complete_media_upload) before create_post or schedule_post. mediaId (obrigatório)
list_posts read somente leitura List posts, newest first (queue and drafts nearest first). Filters: state, channel, tag. state (queued, draft, sent, error, canceled), channel, tag, limit (1 a 200), offset
get_calendar read somente leitura Scheduled items in a period plus the free weekly slots of each channel (default: next 14 days; at most 100 days). from, to (ISO-8601 com fuso), channel, tag
get_insights read somente leitura Cards, top posts, per-channel results and a summary for a period (views, likes, comments, followers), optionally compared with the previous period. from, to, channel, tag, type, compare, sort, direction, page, limit
get_retention read somente leitura Audience retention, impressions and CTR per post of the period (YouTube) and reach/watch time (Instagram). A missing number is null, never 0; channels[].state says whether each account can deliver them. from, to, channel, limit
get_usage read somente leitura API usage of this workspace over the last N days (total, errors, p95, peak per minute vs the limit, by day and by key). MCP calls appear with the route prefix mcp:. days (1 a 30, padrão 7)
create_post write escreve, rede externa Create a post with one item per network. Items are drafts by default or take the next free slot of the channel (queue: true). For a fixed publication time use schedule_post. For a single-photo Instagram post send kind image with media.images (one JPEG image media, optional alt text). Never publishes immediately. TWO-STEP (parágrafo final comum às seis ferramentas de dois passos, logo abaixo da tabela) media, texts, items (obrigatórios); kind (video ou image), title, baseText, queue, draft, options, tags, confirm. Com kind: image, media.images leva a foto (uma). Recusa scheduledFor
schedule_post write escreve, rede externa Create a post and publish it at a fixed time per item (scheduledFor, ISO-8601 with timezone: ALWAYS state the BRT time to the user as well; the panel runs on America/Sao_Paulo). The post goes out by itself at that time on the real account. For a single-photo Instagram post send kind image with media.images. TWO-STEP (parágrafo final comum às seis ferramentas de dois passos, logo abaixo da tabela) os de create_post, mas todo item exige scheduledFor; sem queue nem draft
update_post write escreve, destrutiva, idempotente, rede externa Edit a post: title, texts, media, tags, items (mode, scheduledFor, queue, draft) or moveTo draft/queue. Send only what changes. WHAT CAN CHANGE, per network and when: (1) Any item still pending (draft or scheduled, not yet sent): time, mode, texts, queue/draft. (2) YouTube item ALREADY UPLOADED (the video sits in the channel as private with a future publish time, state "scheduled", or private without a time): it can still be RESCHEDULED (scheduledFor) and its title, description (texts.youtube), videoTags, categoryId and a not-yet-posted pinnedComment can change, until the video goes live. The server checks live on YouTube first; if the video is already public, the scheduled time already passed, the video was deleted, or Praeko did not upload it, nothing is written and the error names the reason and the manual alternative (YouTube Studio: https://studio.youtube.com/video/<videoId>/edit). The new time must be at least 5 minutes ahead; asking for the same time again changes nothing. A YouTube video never becomes public by this tool. (3) Instagram Reels in Buffer: text, time and draft only. (4) TikTok/Instagram items already sent or in the TikTok inbox cannot change. A request touching several items applies each one independently and the result lists itemResults (applied or not, and why): read it, nothing is skipped silently. TWO-STEP (parágrafo final comum às seis ferramentas de dois passos, logo abaixo da tabela) The preview lists, per item, "will_change" or "cannot_change" with the reason. postId (obrigatório); title, texts, media, tags, items (id ou network, mode, scheduledFor, queue, draft, videoTags, categoryId), moveTo (draft ou queue), confirm
cancel_post write escreve, destrutiva, idempotente, rede externa Cancel the pending items of a post (they will not be published; Instagram items scheduled in Buffer are removed there). Items already sent are kept. IMPORTANT for YouTube: a video Praeko already uploaded and scheduled (private with a future publish time) is NOT cancelled by this tool: it stays and YouTube will still publish it on time (the result says so). To stop it, either reschedule it with update_post, or manage it in YouTube Studio (https://studio.youtube.com/video/<videoId>/edit: remove the schedule to keep it private, or delete it). TWO-STEP (parágrafo final comum às seis ferramentas de dois passos, logo abaixo da tabela) postId (obrigatório), confirm
upload_media write escreve, rede externa Add a video, a cover or the photo of an image post (type image: JPEG only) to the media library by giving a PUBLIC https URL that the Praeko server downloads (video/mp4, video/quicktime, image/png, image/jpeg; up to 50 MB; private networks are refused). Files are never sent through MCP: for larger files use the REST/CLI upload and then use the media id. TWO-STEP (parágrafo final comum às seis ferramentas de dois passos, logo abaixo da tabela) url e type (video, cover ou image) obrigatórios; name, confirm
create_media_upload write escreve, rede externa Use this to publish a video, cover or photo (type image, JPEG) that is a file on the user's machine (you need a shell; with no shell, use upload_media with a public URL). The file never goes through MCP: this tool only creates the media slot and returns the exact upload command (curl; a loop of parts above 50 MiB). Steps: 1) call this with the real size in bytes (wc -c < file), type (video, cover or image), mime (video/mp4, video/quicktime, image/png, image/jpeg; an image type takes only image/jpeg); 2) run upload.command in the shell after replacing /path/to/file; the API key is read from the shell environment (PRAEKO_KEY): NEVER ask for the key, paste it in the chat, print it or write it to a file; 3) call complete_media_upload with the mediaId; 4) use that media id in create_post or schedule_post (their two-step preview and confirmation still protect the publication). Creating the slot publishes nothing, so there is no confirmation code. Limits: video up to 2 GiB, cover and image up to 20 MiB (Instagram itself takes photos up to 8 MB: that is checked when the post is created), 20 pending uploads per workspace, 60 per hour; an upload not finished in 24 hours is discarded. type (video, cover ou image), name, mime (video/mp4, video/quicktime, image/png, image/jpeg) e size em bytes, todos obrigatórios. Sem confirm: criar o espaço de envio não publica nada
complete_media_upload write escreve, idempotente Call this after running the upload command from create_media_upload. It finishes the upload (joins the parts of a large file; a single-PUT file is already complete), verifies it and returns status ready or uploading, with the media record: publicUrl, durationMs, width and height (read from the video header). Safe to call again. Then use the media id in create_post or schedule_post. mediaId (obrigatório). Sem confirm
create_idea write escreve Add a card to the idea board (the "Create" screen). Nothing is published. TWO-STEP (parágrafo final comum às seis ferramentas de dois passos, logo abaixo da tabela) title (obrigatório, até 200 caracteres); note, group (idea, scripting, ready, posted), tags, confirm
Parágrafo final das seis ferramentas com dois passos
TWO-STEP: the first call (without `confirm`) executes NOTHING: it returns a preview and a single-use `confirmation_code` (10 minutes). Show the preview (action, channels, time in BRT and UTC, media, text, warnings) to the user and WAIT for explicit approval. Only then call this tool again with the SAME arguments plus `confirm: "<code>"`. Changing any argument invalidates the code.

As anotações vão em tools/list (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) e a coluna as escreve em palavras: "somente leitura" é readOnlyHint, "destrutiva" é destructiveHint, "idempotente" é idempotentHint e "rede externa" é openWorldHint (o que fala com uma rede social ou baixa da internet). O cliente decide se confia nelas: a especificação manda tratá-las como dicas.

O que cada escrita faz

Escrita em dois passos

A confirmação é do servidor, não do agente: mesmo que o agente esteja configurado para aprovar tudo, uma ferramenta de escrita nunca executa na primeira chamada. Vale igual para chave de API e para login OAuth.

1. Chamada sem confirmO servidor valida e devolve a prévia. Nada é gravado, nada é enviado.
2. A préviaAção exata, canais com id e nome, horário em BRT e UTC, mídia encontrada ou não, textos e avisos, mais um confirmation_code.
3. Você aprovaO agente mostra a prévia e espera o seu "sim".
4. Chamada com confirmOs mesmos argumentos mais confirm: "<código>". Só agora executa.
Passo 1: o agente chama (sem confirm)
{
  "name": "schedule_post",
  "arguments": {
    "title": "O teste que só falhava na segunda",
    "media": {
      "video": "01KA3VQ7M2T9XE4HB8N5RZ6C0D"
    },
    "texts": {
      "youtube": {
        "title": "O teste que só falhava na segunda",
        "text": "…"
      }
    },
    "items": [
      {
        "network": "youtube",
        "mode": "scheduled",
        "scheduledFor": "2026-11-13T20:30:00Z"
      }
    ]
  }
}
Passo 1: a prévia (nada foi gravado)
{
  "preview": true,
  "executed": false,
  "tool": "schedule_post",
  "action": "Create a post and schedule it at fixed times",
  "title": "O teste que só falhava na segunda",
  "items": [
    {
      "network": "youtube",
      "channel": {
        "id": "…",
        "name": "Meu canal",
        "connected": true
      },
      "mode": "network default",
      "timing": "fixed_time",
      "scheduledFor": {
        "utc": "2026-11-13T20:30:00.000Z",
        "brt": "2026-11-13 17:30 (BRT, UTC-03:00)"
      }
    }
  ],
  "media": [
    {
      "id": "01KA3VQ7M2T9XE4HB8N5RZ6C0D",
      "found": true,
      "type": "video",
      "state": "ready"
    }
  ],
  "warnings": [
    "Confirming schedules a REAL publication on the connected account(s) at the time above. It can be edited or cancelled until then (update_post, cancel_post)."
  ],
  "confirmation_code": "K7MQ-2VXZ-9RT4",
  "expires_at": "2026-11-13T12:10:00.000Z",
  "expires_in_seconds": 600,
  "next_step": "NOTHING was done yet. Show this preview to the user and wait for approval. …"
}
Passo 2: o agente repete com o código
{
  "name": "schedule_post",
  "arguments": {
    "title": "O teste que só falhava na segunda",
    "media": {
      "video": "01KA3VQ7M2T9XE4HB8N5RZ6C0D"
    },
    "texts": {
      "youtube": {
        "title": "O teste que só falhava na segunda",
        "text": "…"
      }
    },
    "items": [
      {
        "network": "youtube",
        "mode": "scheduled",
        "scheduledFor": "2026-11-13T20:30:00Z"
      }
    ],
    "confirm": "K7MQ-2VXZ-9RT4"
  }
}
Passo 2: resultado
{
  "preview": false,
  "executed": true,
  "tool": "schedule_post",
  "result": {
    "id": "…",
    "items": [
      {
        "network": "youtube",
        "state": "scheduled"
      }
    ]
  }
}

O código de confirmação

Propriedade Valor
Formato XXXX-XXXX-XXXX: 12 caracteres aleatórios (cerca de 58 bits), por exemplo K7MQ-2VXZ-9RT4.
Validade 10 minutos (expires_in_seconds: 600).
Uso Único. Duas confirmações ao mesmo tempo: só uma executa.
Preso a O workspace, a credencial que pediu a prévia (a chave de API ou a conexão OAuth: renovar o token não invalida o código), a ferramenta e os argumentos (SHA-256 do JSON canônico: a ordem das chaves não importa).
Guardado como Só o hash, no banco.
Recusado pela validação Se a rota recusar o pedido (4xx, nada foi gravado), o código volta a valer até vencer: o usuário corrige o que faltava (a mídia ainda subindo, por exemplo) e confirma de novo.

Mudar qualquer argumento, repetir o código, usar um vencido ou de outra credencial, ferramenta ou workspace falha. A resposta é um erro de execução (isError: true) com error.code confirmation_invalid e o motivo em error.reason (a message vem em inglês):

`reason` Significa O que o agente faz
unknown_code O código não existe neste workspace. Chamar sem confirm para uma prévia nova.
already_used O código já foi usado. Pedir uma prévia nova se for repetir a ação.
expired Passaram os 10 minutos. Pedir uma prévia nova e mostrar de novo ao usuário.
wrong_key O código foi emitido para outra chave de API ou outra conexão OAuth. Pedir uma prévia com a credencial atual.
wrong_tool O código é de outra ferramenta. Usar a ferramenta que gerou o código.
arguments_changed Os argumentos diferem dos que foram vistos na prévia. Pedir uma prévia nova com os argumentos finais.
Exemplo de erro
{
  "error": {
    "code": "confirmation_invalid",
    "message": "this confirmation code expired (10 minutes). Request a new preview and show it to the user again.",
    "reason": "expired"
  }
}

upload_media: mídia por URL

A ferramenta recebe uma URL pública https e o servidor baixa o arquivo. O arquivo nunca passa pela conversa com o agente.

Regra Valor
Tipos video: video/mp4, video/quicktime. cover: image/png, image/jpeg. image (a foto de um post de imagem): só image/jpeg. O tipo é conferido no download (unsupported_mime).
Tamanho Até 50 MB, conferido no cabeçalho e durante o download. Acima disso, file_too_large: use o envio de arquivo local abaixo, ou o envio em partes da REST, do CLI ou do SDK.
Redirecionamentos Até 3 saltos, e cada salto passa de novo pela mesma verificação.
Endereços recusados Só https, sem usuário e senha, sem localhost, nome interno, IP privado, reservado ou de metadados de nuvem (a mesma barreira dos webhooks).

O Worker não resolve o DNS antes de baixar: contra um nome público que resolva para IP privado, a proteção é a própria rede da Cloudflare, que não alcança a rede privada de ninguém.

Arquivo local: create_media_upload e complete_media_upload

O caso mais comum de um agente com shell (Claude Code, Codex, Gemini CLI, opencode, Cursor, Kimi, Cline): o vídeo está no disco. O MCP não carrega arquivo grande, então o servidor só prepara o envio e quem envia é o curl do próprio agente, direto para a API, com a chave que já está no ambiente do usuário.

1. create_media_uploadO agente informa type, name, mime e o size exato em bytes (wc -c < arquivo). O servidor cria a mídia e devolve mediaId, o comando curl pronto e a especificação HTTP.
2. Rodar o comandoO agente roda upload.command no shell. A chave vem de $PRAEKO_KEY (exporte a partir de PRAEKO_API_KEY se for o nome que você usa) e nunca aparece na conversa.
3. complete_media_uploadJunta as partes (arquivo grande), confere e devolve status: ready com publicUrl, durationMs, width e height. Pode ser repetida; get_media consulta o estado.
4. create_post ou schedule_postCom o mediaId. Estes continuam em dois passos: prévia, o seu "sim", código.
Tamanho Como o arquivo sobe
Até 50 MiB Um PUT em /v1/media/{id}/content, com o corpo igual ao arquivo.
Acima de 50 MiB (vídeo até 2 GiB) Partes de 64 MiB em PUT /v1/media/{id}/parts/{n} (todas iguais, a última menor; cada parte pode ser reenviada). O comando devolvido já é o laço com dd e curl; a resposta traz também a lista de partes com a URL de cada uma.
Resposta de create_media_upload (arquivo até 50 MiB)
{
  "executed": true,
  "tool": "create_media_upload",
  "upload": {
    "mediaId": "01KB7J3V9Q2W8E5R1T6Y4N0M3P",
    "state": "uploading",
    "expectedSize": 48213377,
    "mime": "video/mp4",
    "expiresAt": "2026-11-08T12:00:00.000Z",
    "keyHandling": "The API key is already in the user's shell environment as PRAEKO_KEY (…)",
    "method": "single_put",
    "http": {
      "method": "PUT",
      "url": "https://praeko.app/v1/media/01KB7J3V9Q2W8E5R1T6Y4N0M3P/content",
      "headers": {
        "Authorization": "Bearer $PRAEKO_KEY",
        "Content-Type": "video/mp4"
      },
      "body": "the raw bytes of the file (exactly 48213377 bytes)"
    },
    "command": "curl -sS --fail-with-body -X PUT -H \"Authorization: Bearer $PRAEKO_KEY\" -H \"Content-Type: video/mp4\" -H \"Expect:\" -T \"/path/to/file\" \"https://praeko.app/v1/media/01KB7J3V9Q2W8E5R1T6Y4N0M3P/content\""
  },
  "next_step": "Run `upload.command` in the shell (replace /path/to/file; the key comes from the environment, do not print it), then call complete_media_upload with this mediaId, then create_post or schedule_post with media.video = mediaId (those keep their two-step preview/confirmation)."
}

Por que sem código de confirmação

Criar o espaço de envio não publica nada, não envia nada para uma rede e não altera post. O que protege a conta é o passo seguinte, create_post ou schedule_post, que segue em dois passos. Por isso estas duas ferramentas são de um passo só, com limites no lugar do código:

Limite Valor
Escopo write (a lista de quem tem só read não mostra as duas).
Tipos video/mp4, video/quicktime (vídeo), image/png, image/jpeg (capa) e image/jpeg (imagem); o tipo tem de combinar com type.
Tamanho Vídeo até 2 GiB, capa e imagem até 20 MiB. O servidor recusa o envio cujo tamanho difira do declarado (size_mismatch).
Envios pendentes No máximo 20 por workspace (too_many_pending_uploads, com os ids pendentes) e 60 criações por hora (rate_limited).
Validade Um envio que não terminou em 24 horas é descartado (o arquivo parcial é apagado e a mídia some).
Isolamento A mídia é do workspace da credencial; outro workspace recebe media_not_found.
A chave O curl usa uma chave de API com escopo write, lida do ambiente do shell ($PRAEKO_KEY). As ferramentas nunca devolvem a chave, só o marcador $PRAEKO_KEY, e mandam o agente não pedir, não imprimir e não colar a chave na conversa.
Com login OAuth O token OAuth só vale no /mcp, e o curl fala com a REST: mesmo conectado por login, o shell precisa de uma chave write em $PRAEKO_KEY. Sem ela, use upload_media com uma URL pública.
O cliente pode pedir para aprovar o comandoO Claude Code pede aprovação para um comando de shell que usa uma variável como $PRAEKO_KEY e, sem interação (claude -p), recusa o que não estiver liberado nas permissões. Aprove o curl na sessão ou libere-o nas permissões. O comando devolvido usa só $PRAEKO_KEY, sem a forma ${VAR:-…}, que o Claude Code bloqueia. Isso é regra do cliente, não do Praeko.
Agente sem shellConectores do Claude.ai, do Claude Desktop e do ChatGPT não têm shell nem acesso ao disco: use upload_media com uma URL pública https (até 50 MB). Sem URL, suba pelo CLI (praeko post), pelo SDK (uploadFile) ou pela REST e entregue o id da mídia.

Protocolo

O endpoint fala duas eras do MCP no mesmo endereço, como a especificação prevê. Os clientes de hoje, na maioria, ainda usam a 2025-11-25; a 2026-07-28 (a mais nova na data da conferência, 07/11/2026) não tem initialize nem sessão.

Era moderna `2026-07-28` Era antiga `2025-11-25`, `2025-06-18`, `2025-03-26`
Como é reconhecida _meta["io.modelcontextprotocol/protocolVersion"] no corpo ou MCP-Protocol-Version: 2026-07-28 Qualquer outro pedido. Sem cabeçalho de versão vale 2025-03-26.
Abertura Nenhuma. server/discover é opcional. initialize, resposta com a versão pedida (ou 2025-11-25), notifications/initialized (202).
Cabeçalhos exigidos MCP-Protocol-Version igual ao corpo, Mcp-Method igual ao method, Mcp-Name igual a params.name em tools/call. Divergência: 400 e JSON-RPC -32020. MCP-Protocol-Version, se vier, tem de ser uma versão conhecida (senão 400).
Versão desconhecida 400 e -32022, com data.supported e data.requested. Idem.
Método desconhecido 404 e -32601. 200 e -32601.
Resultado Traz "resultType": "complete". Sem resultType.
Lote JSON-RPC Recusado (400). Aceito.
Testar com curl (era antiga, sem sessão)
curl -s https://praeko.app/mcp \
  -H "Authorization: Bearer $PRAEKO_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Segurança

Cuidado Como funciona
Confirmação no servidor Nenhuma escrita que publica ou muda conteúdo executa sem o segundo passo. O código é de uso único, vale 10 minutos e está preso à credencial, à ferramenta e aos argumentos.
Menor escopo Uma chave read (ou o acesso Leitura, no login) para o agente que só consulta; write só para quem agenda. O escopo é conferido no /mcp e de novo na rota REST.
Consentimento explícito A tela de consentimento aparece em toda autorização, mesmo para um aplicativo já conhecido, e destaca quando ele pede mais acesso do que tinha. Ela mostra o endereço de retorno e avisa quando o aplicativo é desconhecido ou só tem endereço local.
Texto das ferramentas é dado As instruções do servidor mandam o modelo tratar títulos, comentários e notas devolvidos como dado do usuário, nunca como ordem.
Envio de arquivo local Só um espaço de envio com limites (20 pendentes, 60 por hora, 24 h de validade, 2 GiB); o arquivo vai do shell do agente direto para a API. Publicar continua em dois passos.
Credencial fora do código Chave em variável de ambiente. Chave e token nunca aparecem em resposta, log ou banco (só o hash). Se uma chave vazou, revogue em Chaves de API; uma conexão, em Conexões de agentes.
Rastro Cada chamada MCP vira uma linha em Uso e log, com a rota mcp:tools/call create_post, mcp:tools/list etc. e o status; as chamadas por login aparecem com a chave mcp-oauth. Filtre pela rota mcp: no painel ou com GET /v1/usage/log?route=mcp%3A.

Clientes conferidos

Testado com o Claude Code real: com chave de API (inicialização, tools/list, list_channels e a prévia de create_idea) e com login OAuth (descoberta, registro pelo documento de metadados do cliente, consentimento, conexão e revogação). Os blocos dos demais agentes em Agentes de IA vêm da documentação de cada fabricante. O login pelo ChatGPT não foi conferido em fonte primária.

Dúvida ou erro nesta página? contato@praeko.appVer .md

Digite para buscar páginas, rotas e códigos de erro.