feedme-html-publisher-mcp
v1.1.0
Published
MCP server pra publicar HTML de projetos no CRM da Rede FeedMe direto do Claude Code, sem precisar de acesso ao código.
Maintainers
Readme
feedme-html-publisher-mcp
MCP server pra publicar HTML em projetos do CRM da Rede FeedMe direto do Claude Code, sem precisar de acesso ao código dos repos
feedme-api/ufm-webflow.
O que isso resolve
Hoje, pessoas que editam HTMLs de projeto (briefings, propostas, decks) precisam:
- Editar o arquivo localmente
- Abrir o CRM no navegador
- Achar o projeto, modo edição
- Colar o HTML
- Salvar
Esse MCP corta tudo pro fluxo:
- Editar o arquivo localmente no Claude Code
- Falar "publica isso no projeto cannes" → pronto, tá no ar.
Permissionamento idêntico ao da web (mesmo crmJwt + projectMembershipGuard). Histórico de versões automático (snapshot do anterior em project_html_versions). Reversão com 1 comando.
Tools disponíveis
| Tool | O que faz |
|------|-----------|
| login(email, password) | Autentica no CRM e salva o JWT no Keychain (TTL ~5 anos) |
| logout() | Remove o JWT salvo |
| whoami() | Confirma quem está logado |
| list_projects(query?) | Lista projetos do CRM (filtro por nome/slug) |
| list_project_documents(slug) | Lista os documentos de um projeto |
| view_current_html(slug, doc_slug?) | Retorna o HTML publicado atual |
| view_versions(slug, doc_slug?, limit?) | Histórico de versões |
| publish_html(slug, file_path, doc_slug?, change_summary?, confirm_overwrite?) | Publica HTML local. Aviso de overwrite se houve mudança recente. |
| restore_version(slug, version_id, doc_slug?, change_summary?) | Reverte pra versão anterior |
Auto-merge ao detectar conflito (v1.1.0+)
Se o HTML do projeto foi publicado nas últimas 24h (configurável via FEEDME_OVERWRITE_WINDOW_HOURS), publish_html não publica direto — em vez disso:
- Pega o HTML do servidor (versão atual publicada)
- Lê o HTML local (o arquivo que o usuário ia publicar)
- Inclui ambos no payload de retorno + instruções pro Claude da sessão
- Claude (na sessão do usuário) age automaticamente:
- Compara os dois HTMLs bloco por bloco
- Identifica mudanças de cada lado e conflitos
- Apresenta resumo pro usuário em linguagem natural
- Propõe um HTML merged
- Aguarda aprovação do usuário antes de publicar
O usuário não precisa pedir merge — ele apenas decide se aprova ou não a proposta do Claude.
Fluxo típico:
Usuário: "publica esse arquivo no projeto cannes"
↓
MCP detecta que servidor foi modificado há 2h por Pietra
↓
Claude (automático): puxa servidor, lê local, compara
↓
Claude → Usuário:
"Pietra adicionou seção 'Marcas Confirmadas' há 2h.
Você editou pesquisa de comportamento.
Sem conflito — mexeram em seções diferentes.
Proposta: junta as duas. Topa publicar?"
↓
Usuário: "topa"
↓
Claude: escreve HTML merged + chama publish_html(confirm_overwrite=true)
↓
✓ Publicado com mergePara HTMLs muito grandes (>80kb cada), o MCP retorna apenas instruções e o Claude usa view_current_html + Read separados. Comportamento é o mesmo, só não inlina os HTMLs no payload pra economizar contexto.
Para forçar publicação sem merge (situação rara), chama com confirm_overwrite: true.
Para desabilitar a proteção totalmente, exporta FEEDME_OVERWRITE_WINDOW_HOURS=0.
Instalação (pra usuário final)
Pré-requisitos
- macOS, Linux ou Windows com Node 18+
- Conta no CRM da FeedMe (mesmo login que você usa em feedme-api-prod.herokuapp.com/p/...)
- Claude Code instalado
Passo 1 — Adicionar o MCP no Claude Code
Abra ~/.claude.json (ou crie se não existir) e adicione na seção mcpServers:
{
"mcpServers": {
"feedme-html": {
"command": "npx",
"args": ["-y", "feedme-html-publisher-mcp"]
}
}
}Não tem o arquivo? Use o CLI:
claude mcp add feedme-html npx -- -y feedme-html-publisher-mcp
Passo 2 — Reiniciar o Claude Code
Sai e abre de novo. Na primeira vez, o npx -y baixa o pacote (~5s).
Passo 3 — Login
Na conversa com o Claude, fala:
fazer login no feedme com [email protected]O Claude vai chamar a tool login, te pedir a senha, e salvar o JWT no Keychain do macOS (ou em ~/.config/feedme/token.json no Linux/Windows).
Esse passo é uma vez só — o token dura 5 anos.
Passo 4 — Usar
Edita um HTML no Claude Code, depois fala (em linguagem natural mesmo):
publica esse arquivo no projeto expedicao-cannes-2026, com o resumo "atualiza pesquisa de marcas"O Claude lê o HTML, identifica o projeto pelo slug e chama publish_html. Em ~2 segundos:
✓ Publicado: Expedição Cannes 2026
arquivo: cannes-pesquisa-completa.html (156.3kb)
publicado_em: 2026-05-01T15:42:11Z
link: https://feedme-api-prod.herokuapp.com/p/expedicao-cannes-2026
snapshot anterior: v3 (use restore_version pra reverter)Casos de uso
Atualizar HTML principal de um projeto
publica ./pesquisa.html no projeto expedicao-cannes-2026Atualizar um documento específico dentro de um projeto
publica ./briefing.html no projeto gramado-summit-2026 como documento briefing-lecaVer versões anteriores
me mostra as últimas 5 versões do projeto cannesResposta:
Expedição Cannes 2026 — 5 versão(ões):
v5 • 2026-05-01T15:42:11Z • Leticia — atualiza pesquisa de marcas
id: 7a2f3b...
v4 • 2026-04-28T11:20:03Z • Jay — adiciona timeline 5 atos
id: 9c4e1d...
...Reverter pra versão antiga
reverte o projeto cannes pra versão 7a2f3b... porque a v5 quebrou layoutVer o HTML atual sem publicar (pra editar)
me mostra o HTML atual do projeto rap-in-cenaConfiguração avançada
Override do API URL
Pra apontar pra staging ou local, exporta a env var antes de abrir o Claude Code:
export FEEDME_API_URL=http://localhost:3000Ou adiciona no mcpServers:
{
"mcpServers": {
"feedme-html": {
"command": "npx",
"args": ["-y", "feedme-html-publisher-mcp"],
"env": {
"FEEDME_API_URL": "https://feedme-api-staging.herokuapp.com"
}
}
}
}Token via env var (sem login)
Útil pra CI ou Docker:
{
"env": {
"FEEDME_CRM_TOKEN": "eyJhbGc..."
}
}Pega o token rodando login em outra máquina ou copiando do localStorage do navegador (feedme-api-prod).
Troubleshooting
| Sintoma | Causa | Fix |
|---------|-------|-----|
| [401] Token inválido ou expirado | Token revogado ou senha mudou | Roda login de novo |
| [404] Projeto "X" não encontrado | Slug errado, OU usuário sem acesso | Use list_projects pra ver slugs corretos |
| [403] Sem permissão pra essa ação | Não está em project_people desse projeto | Pedir pra owner adicionar |
| Não há token salvo. Rode login | Primeira execução | Roda login |
| Arquivo não parece HTML válido | Arquivo sem tag <html> | Verifica que é arquivo HTML completo |
Onde fica o token salvo?
- macOS: Keychain → "feedme-html-publisher-mcp"
- Fallback (todos os SOs):
~/.config/feedme/token.json(modo 600)
Pra remover manualmente: feedme-html-publisher-mcp logout (via Claude) ou rm ~/.config/feedme/token.json.
Desenvolvimento
# clone do monorepo ufm-webflow
cd solucoes/feedme-html-publisher-mcp
npm install
npm run build # tsc + chmod +x dist/index.js
npm run dev # tsc --watch
# testar local
node dist/index.js # roda em stdio (ferramenta esperando JSON-RPC)Publicação no npm
npm version patch # ou minor/major
npm publish # exige `npm login` antesEstrutura
src/
├── index.ts # MCP server + tools
├── client.ts # HTTP client (fetch) com resolução slug→id
├── auth.ts # Keychain (keytar) + arquivo fallback
└── types.ts # tipos compartilhadosEndpoints consumidos
Todos do feedme-api (/crm/*):
POST /crm/auth/login(sem auth)GET /crm/projects?q=...GET /crm/projects/by-slug/:slug/rawGET /crm/projects/by-slug/:slug/documents/:docSlug/rawGET /crm/projects/:id/documentsGET /crm/projects/:id/versionsGET /crm/projects/:id/documents/:docId/versionsPOST /crm/projects/:id/publishPOST /crm/projects/:id/documents/:docId/publishPOST /crm/projects/:id/versions/:vid/restorePOST /crm/projects/:id/documents/:docId/versions/:vid/restore
Licença
MIT — Rede FeedMe.
