feedme-mcp
v2.0.0
Published
MCP server da Rede FeedMe: opera o CRM (projetos, equipe, tarefas, financeiro), lê reuniões do FeedMeet e publica HTML, direto do Claude Code sem acesso ao código.
Downloads
168
Maintainers
Readme
feedme-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 |
Gestão de projetos (v1.2.0+)
Além de publicar HTML, dá pra criar e operar projetos direto do Claude Code. Todo projeto é identificado pelo slug (igual às tools de HTML). As mesmas permissões da web valem: o financeiro exige papel financeiro (finance_admin/finance_full/…).
Projetos
| Tool | O que faz |
|------|-----------|
| create_project(name, slug?, type?, status?, priority?, owner_person_id?, primary_company_id?, tags?, …) | Cria projeto. Só name é obrigatório; status default planejando |
| get_project(slug) | Detalhe: status, equipe, empresas, tarefas, documentos |
| update_project(slug, status?, name?, new_slug?, …) | Atualiza campos. status="concluido" congela unit_jobs + cria campanha de avaliação |
| clone_project(slug, name, new_slug?) | Duplica um projeto (o clone volta a planejando) |
| delete_project(slug, confirm) | Soft-delete (exige confirm=true). Pra arquivar reversível, use update_project status="arquivado" |
Equipe
| Tool | O que faz |
|------|-----------|
| find_person(query, limit?) | Busca pessoa por nome/email → retorna person_id (cus_…/tem_…) |
| find_company(query) | Busca empresa por nome → retorna company_id (comp_…) |
| find_studio_associate(query?, functions?, segments?, state?, review_status?) | Busca associados FeedMe Studios (filtra por função/segmento/UF) → person_id + funções, experiência, nº de projetos |
| get_studio_associate(person_id) | Perfil completo do associado: características (funções, especialidades, oferta, bio, equipamento, disponibilidade, preço), portfólio e os projetos que já fez. Pra montar times criativos |
| link_person(slug, person_id, role?) | Vincula pessoa (default colaborador) |
| update_person_role(slug, person_id, role) | Muda o papel da pessoa |
| unlink_person(slug, person_id, role?) | Remove o vínculo da pessoa |
| link_company(slug, company_id, role?) | Vincula empresa (default parceiro) |
| unlink_company(slug, company_id, role?) | Remove o vínculo da empresa |
Tarefas (status em inglês: todo / in_progress / review / done)
| Tool | O que faz |
|------|-----------|
| list_tasks(slug, status?, priority?) | Lista tarefas do projeto |
| create_task(slug, title, status?, priority?, assignee_email?, due_date?, …) | Cria tarefa |
| update_task(task_id, status?, …) | Atualiza tarefa |
| delete_task(task_id, confirm) | Apaga tarefa (exige confirm=true) |
Financeiro (requer papel financeiro)
| Tool | O que faz |
|------|-----------|
| finance_summary(slug) | Margem por moeda (confirmado + pago) |
| list_finance_categories(kind) | Categorias (expenses/revenues) pra usar em category_id |
| list_expenses(slug, status?, competence_month?) / list_revenues(...) | Lista despesas / receitas |
| create_expense(slug, description, amount, vendor_kind, …) | Registra despesa. vendor_kind: company→vendor_company_id, person→vendor_person_id, freeform→vendor_name |
| create_revenue(slug, description, amount, client_company_id?/client_name?, …) | Registra receita |
| update_expense / update_revenue / delete_expense / delete_revenue | Editar / remover (soft-delete exige confirm=true) |
Exemplo em linguagem natural: "Cria um projeto chamado Cobertura Torra #027, tipo evento. Vincula a Kandi como lead e a empresa Torra como cliente. Adiciona uma tarefa 'Fechar equipe' pra sexta. Lança uma despesa de R$ 800 de freela de vídeo pro Yuri."
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": {
"command": "npx",
"args": ["-y", "feedme-mcp"]
}
}
}Não tem o arquivo? Use o CLI:
claude mcp add feedme npx -- -y feedme-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": {
"command": "npx",
"args": ["-y", "feedme-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-mcp"
- Fallback (todos os SOs):
~/.config/feedme/token.json(modo 600)
Pra remover manualmente: feedme-mcp logout (via Claude) ou rm ~/.config/feedme/token.json.
Desenvolvimento
# clone do monorepo ufm-webflow
cd solucoes/feedme-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.
