@advlex/mcp-lex
v0.2.0
Published
Conector MCP da AdvLex — dá ao Claude do escritório acesso de leitura à instância Lex (conversas, clientes, processos, prazos, modelos).
Readme
MCP Lex — conector do Claude do cliente (tarefa #34)
Permite que o comprador use o Claude dele ("veja a conversa do número X, monte a pasta de protocolo") conectado à própria instância Lex.
Instruções para o comprador: INSTALACAO.md.
Arquitetura (decidida 13/08/2026, implementada 13/08/2026)
- Servidor MCP stdio em Node (
@modelcontextprotocol/sdk), instalado na máquina do cliente vianpx mcp-lex. - Autentica na instância com
LEX_URL+LEX_API_KEY(aautomation_api_keyda instância). - Sem estado próprio: tudo é HTTP contra a instância do comprador. Uma instância, uma chave.
- Ferramentas v1 (
src/index.js), com o cliente HTTP emsrc/lex-client.js:listar_conversas(filtro?, numero?, limite?)— junta WA1 + WA2, com estágio/árealer_conversa(telefone, numero?, limite?)— histórico completo + URLs de mídiabaixar_midia(telefone, numero?, tipos?, pasta?)— salva os arquivos em disco e devolve os caminhosdados_cliente(nome_ou_telefone)— cadastro + processos + prazos + últimas mensagensgerar_documento(cliente, tipo, objeto)— usa o gerador existente (client-documents.js) e salva .docxlistar_modelos(tipo?, area?)— modelos do escritório
Detalhes que valem lembrar:
- O telefone digitado é resolvido pelo sufixo de 8 dígitos contra a lista de conversas, porque o banco guarda
55 + DDD + númeroe o nono dígito nem sempre está lá. Máscara ("(85) 98650-0579") funciona. baixar_midiagrava em disco em vez de devolver base64: áudio e PDF estourariam o contexto do Claude, e o caso de uso é justamente montar a pasta do cliente. Padrão~/Downloads/lex-midias/<nome>_<telefone>/.gerar_documentosempre gera procuração e contrato no servidor (duas chamadas ao Claude, sequenciais, ~1 min); o parâmetrotiposó escolhe qual sai em .docx. Timeout do cliente em 5 min.
Backend — o que mudou
middleware/auth.js: além das 4 rotas de envio, ax-automation-keyagora abreAUTOMATION_READ_PATHS(conversas, mensagens, clientes, processos, prazos, modelos) só em GET, eAUTOMATION_ACTION_PATHS(geração e exportação de documento) só em POST. A checagem de método é essencial: o allowlist casa apenas o caminho, então liberar/clientssem olhar o método abriria POST/PUT/DELETE na mesma rota.routes/auth.js:GET /api/auth/automation-keyePOST /api/auth/automation-key/rotate, ambos exigindo login (a chave de automação não lê a si mesma).Settings.tsx: bloco "Conector do Claude — chave de automação", com mostrar/copiar/rotacionar.services/document-export.js: corrigidogetOffice is not defined(usado no alt text do logo, nunca importado). Isso quebrava com 500 toda exportação de .docx, inclusive a do painel.
Backups no VPS dos arquivos tocados: *.bak-mcp34.
Resolvido em 24/08/2026
Mídia agora exige link assinado. As rotas /api/whatsapp/media/* e /api/whatsapp2/media/* continuam fora do requireAuth, porque <img>/<audio> realmente não mandam header, mas passaram a validar por conta própria: ou a requisição já está autenticada (JWT ou chave de automação), ou a URL traz uma assinatura HMAC válida. Sem isso, 401.
- Helper em
src/utils/media-token.js. Segredo derivado do JWT, então rotacionar o JWT invalida os links antigos junto. Validade de 7 dias. - As rotas
/messagesdos dois números devolvemmedia_urljá assinada (assinarMensagens). O frontend não mudou, porque sempre consumiu a URL que a API entrega. - O conector MCP também não precisou mudar: ele lê as mensagens por
/messages, que é rota liberada para a chave de automação, e recebe as URLs assinadas prontas. - Testado em produção: sem token 401, token inválido 401, token válido 200, nos dois números.
- Backups:
src/routes/*.bak-media-20260824-1131.
pickTemplates não usa mais modelo de tema alheio. Um modelo cujo nome carrega tema próprio (Consórcio, Divórcio, INSS, Consignação, Negativação, Protesto, Trabalhista, Pensão) só é escolhido quando o objeto do caso é daquele tema; caso contrário a busca cai no modelo geral. Acrescentado hint para consignado, que não existia.
⚠️ A gravidade desse segundo item era menor do que este README dizia. Conferindo os conteúdos por hash, o "Contrato de Honorários Consórcio" é byte a byte idêntico ao "Contrato de Honorários (Geral)" e não menciona consórcio no texto. O mesmo vale para as procurações: Geral, Divórcio, INSS/BPC e Consórcio são o mesmo documento, coerente com a decisão de unificar a procuração num modelo único. Ou seja, o defeito era de rótulo, não de conteúdo: o cliente de consignado nunca recebeu contrato de consórcio. A correção vale para manter o registro coerente e para o dia em que algum desses modelos passar a ser de fato específico.
Conferido de passagem: a variante de contrato para trabalhista/consumidor/maternidade está correta no banco, com "não havendo cobrança de honorários sobre prestações vincendas", e a previdenciária tem as 12 vincendas e o art. 50 do CED. Nada a cadastrar.
Versão 0.2.0 (25/08/2026)
Ferramenta nova: enviar_mensagem. O Claude do comprador passa a poder responder um cliente pelo WhatsApp do escritório ("responde o Emerson pedindo o extrato da cota"). Duas travas, e as duas são consequência do desenho, não código extra:
- Só envia para quem já tem conversa aberta na instância. O
resolverConversaé o caminho: telefone que não casa com nenhuma conversa é recusado. Isso elimina o pior cenário, que é disparo para um número inventado ou digitado errado. - Ambiguidade nunca é resolvida por conta própria. "Emerson" casava com ele e com a esposa: a ferramenta lista as opções e não envia.
O retorno ecoa destinatário, número de origem e o texto integral enviado, que fica no transcrito do Claude e serve de auditoria do que saiu em nome do advogado.
Nota de segurança que vale registrar: as 4 rotas de envio já estavam liberadas para a automation_api_key desde a v0.1.0, em qualquer método. Não ter a ferramenta nunca foi uma restrição, era só ausência de conveniência. Se um dia for preciso restringir de verdade, o controle tem que ser no servidor, não no conector.
Corrigido: o conector enxergava só os 100 contatos mais recentes. As rotas GET /conversations dos dois números tinham LIMIT 100 fixo, sem parâmetro. Na instância do escritório isso significava 483 de 683 conversas invisíveis, 71% do acervo. Afetava ler_conversa, baixar_midia, dados_cliente e teria afetado a ferramenta nova: um cliente de dois meses atrás simplesmente "não existia" para o Claude.
- Backend: as duas rotas passam a aceitar
?search=(casa sufixo de 8 dígitos do telefone ou nome) e?limit=(padrão 100, teto 2000). Sem parâmetro o comportamento é idêntico ao anterior, então o painel não mudou. - Conector:
resolverConversamanda o termo como?search=. O filtro local continua valendo como segunda rede, porque instância que ainda não atualizou ignora o parâmetro e devolve os 100 de sempre. - Backups no VPS:
src/routes/*.bak-search-20260825-1510.
Testado em produção: sem parâmetro 100 conversas, busca por telefone e por nome achando contato fora dos 100, ?limit=2000 trazendo 438 no WA1 e 245 no WA2, e envio real chegando ao destino.
Pontos em aberto
- Publicado em 13/08/2026 como
@advlex/[email protected](público, escopo pessoal do usuárioadvlex, versão solta no manual durante os fundadores). Validado pelo caminho do comprador:npx -y @advlex/mcp-lexcom cache zerado, no Node 20. - Como publicar as próximas versões: o npm não cadastra mais aplicativo autenticador, então a conta usa chave de acesso e não existe código de 6 dígitos. O
npm publishprecisa da versão nova (Node 22 + npm 12, instalados ao lado em~/.nvm/versions/node/v22.23.2), que abre o navegador para confirmar com Touch ID. Isso exige terminal interativo, então quem roda é o Dr. Tiago:export PATH="$HOME/.nvm/versions/node/v22.23.2/bin:$PATH" && cd ~/juridico-app/mcp-lex && npm publish. Alternativa a partir de agora que o pacote existe:npm stage publish(não pede 2FA, pode ser rodado pelo Claude) e o Dr. Tiago aprova no site em Pacotes por etapas, sem abrir terminal.
Status
- [x] Rotas de leitura por automation_api_key (com checagem de método)
- [x] Server MCP (6 ferramentas)
- [x] Teste contra a instância real (lex.tiagoholanda.com) — as 6 ferramentas
- [x] Instruções de instalação pro cliente (INSTALACAO.md)
- [x] Publicado no npm:
@advlex/[email protected], testado pornpxa partir do registro público
