Planfix

Um servidor MCP para integração com a plataforma de gerenciamento de projetos e CRM Planfix.

Documentação

Servidor MCP Planfix

Coverage Status

Este servidor MCP fornece integração com a API do Planfix, permitindo que clientes do Model Context Protocol (MCP) interajam com o CRM Planfix e o sistema de gerenciamento de tarefas.

Recursos

  • Gerenciamento de leads (criar, pesquisar, converter em tarefas)
  • Pesquisas de leads podem reutilizar um clientId conhecido para pular consultas de contatos
  • Gerenciamento de contatos e empresas
  • Gerenciamento de tarefas (criar, pesquisar, comentar)
  • Geração e gerenciamento de relatórios
  • Usa a API REST do Planfix v2.0 (documentação da API)
  • Autenticação via token Bearer

Configuração

O servidor requer as seguintes variáveis de ambiente para acesso à API do Planfix:

  • PLANFIX_ACCOUNT – Nome da sua conta Planfix (ex.: yourcompany)
  • PLANFIX_TOKEN – Token da API do Planfix com as permissões necessárias
  • PLANFIX_BASE_URL – (opcional) Substitui a URL base da API REST. O padrão é https://<PLANFIX_ACCOUNT>.planfix.com/rest/. Defina isso para .ru e outras instalações regionais, ex.: https://yourcompany.planfix.ru/rest/
  • PLANFIX_ACCOUNT_URL – (opcional) Substitui a origem web usada para links voltados a humanos (páginas de tarefas/contatos/usuários). O padrão é PLANFIX_BASE_URL sem o /rest/ final
  • PLANFIX_FIELD_ID_EMAIL – ID do campo personalizado para e-mail
  • PLANFIX_FIELD_ID_EMAIL_ADDITIONAL – (opcional, sem padrão) ID numérico do campo personalizado usado para armazenar endereços de e-mail adicionais (multivalor). Deve apontar para um campo personalizado multivalor real que você criou na sua conta; o ID do campo de e-mail secundário do sistema 124 não é um destino de gravação válido. Quando não definido, o armazenamento de endereços adicionais fica desabilitado (a correspondência pelo campo do sistema ainda funciona). O campo de e-mail secundário do sistema do Planfix (additionalEmailAddresses) é somente leitura via API REST, então endereços adicionais são gravados neste campo personalizado; a correspondência usa tanto o campo do sistema (tipo de filtro 4221) quanto este campo personalizado (tipo de filtro 4101), para qualquer pesquisa de e-mail uma vez que isso esteja definido
  • PLANFIX_FIELD_ID_PHONE – ID do campo personalizado para telefone
  • PLANFIX_FIELD_ID_TELEGRAM – Defina qualquer valor para usar o campo Telegram do sistema
  • PLANFIX_FIELD_ID_TELEGRAM_CUSTOM – ID do campo personalizado para Telegram ao usar o campo personalizado
  • PLANFIX_FIELD_ID_CLIENT – ID do campo personalizado para cliente
  • PLANFIX_FIELD_ID_MANAGER – ID do campo personalizado para gerente
  • PLANFIX_FIELD_ID_AGENCY – ID do campo personalizado para agência
  • PLANFIX_FIELD_ID_LEAD_SOURCE – ID do campo personalizado para fonte do lead
  • PLANFIX_FIELD_ID_LEAD_SOURCE_VALUE – ID do valor para a fonte padrão do lead
  • PLANFIX_FIELD_ID_PIPELINE – ID do campo personalizado para funil
  • PLANFIX_FIELD_ID_TAGS – ID do campo personalizado para tags de tarefas
    • Nomes de tags ausentes serão adicionados automaticamente ao diretório
  • PLANFIX_FIELD_ID_LEAD_ID – ID do campo personalizado para ID externo do lead
  • PLANFIX_LEAD_TEMPLATE_ID – ID do modelo de tarefa de lead
  • PLANFIX_TASK_TITLE_TEMPLATE – Modelo para o título padrão da tarefa de lead (ex.: {name} - client's task)

config.yml

Os campos personalizados também podem ser configurados via config.yml. O caminho padrão é ./data/config.yml. Substitua-o com o sinalizador de CLI --config=/abs/path/config.yml ou a variável de ambiente PLANFIX_CONFIG. Você também pode especificar uma conta Planfix diferente ao usar um config personalizado:

PLANFIX_CONFIG=/etc/planfix-mcp.yml PLANFIX_ACCOUNT=demo \
npx @popstas/planfix-mcp-server
proxyUrl: "http://localhost:8080"

webhook:
  enabled: false
  url: "https://example.com/hook"
  token: "<token>"
  skipPlanfixApi: false

leadTaskFields:
  - id: "456"
    name: "id сделки"
    argName: lead_id
    type: number
contactFields:
  - id: "123"
    name: "Резидентство"
    argName: resident
    type: enum
    values: ["резидент", "нерезидент", "иное"]
userFields:
  - id: "789"
    name: "Департамент"
    argName: department
    type: string

proxyUrl roteia todas as chamadas da API REST do Planfix (incluindo solicitações de ferramentas) através do proxy HTTP especificado.

Os valores de config.yml substituem as entradas correspondentes das variáveis de ambiente legadas quando mesclados por id. Os campos personalizados de usuário desta lista são solicitados individualmente pela ferramenta planfix_search_manager para que seus valores estejam disponíveis nas respostas. Os gerentes podem ser pesquisados por email ou por id numérico através desta ferramenta, permitindo consultas quando apenas um identificador está disponível.

API de Chat

Para criar tarefas a partir de mensagens de chat, adicione um bloco chatApi ao config.yml:

chatApi:
  useChatApi: true
  chatApiToken: "<token>"
  providerId: "<id>"
  baseUrl: "https://<account>.planfix.com/webchat/api"
  • chatApiToken – token para solicitações da API de Chat do Planfix.
  • providerId – identificador do provedor de chat configurado no Planfix.
  • useChatApi – habilita a integração com a API de Chat. Quando true, a criação de tarefas prossegue da seguinte forma:
    1. Um chat é criado via API de Chat com a mensagem inicial.
    2. getTask recupera o taskId da nova tarefa.
    3. Atualizações subsequentes são feitas através da API REST.
  • baseUrl – URL base para chamadas da API de Chat. O padrão é https://<account>.planfix.com/webchat/api.

Webhook

Para enviar payloads de tarefas de lead para um webhook antes de criar ou atualizar uma tarefa, adicione um bloco webhook ao config.yml:

webhook:
  enabled: true
  url: "https://example.com/hook"
  token: "<token>"
  skipPlanfixApi: false
  • enabled – se deve enviar o payload da tarefa de lead para a URL do webhook.
  • url – URL do endpoint do webhook.
  • token – segredo compartilhado anexado ao payload JSON como token.
  • skipPlanfixApi – quando true, a resposta do webhook deve incluir taskId, e a chamada à API REST do Planfix é ignorada.

Depuração

npx @modelcontextprotocol/inspector node d:/projects/expertizeme/planfix-mcp-server/dist/index.js

Registro de logs

Defina LOG_LEVEL=debug para habilitar logs detalhados de cache. Os logs são gravados em data/mcp.log.

Limpando o cache

Execute npm run cache-clear para remover todas as respostas em cache da API do Planfix armazenadas em data/planfix-cache.sqlite3 e excluir o arquivo de cache de objetos data/planfix-cache.yml.

Exemplo de Configuração MCP (NPX)

{
  "mcpServers": {
    "planfix": {
      "command": "npx",
      "args": [
        "-y",
        "@popstas/planfix-mcp-server"
      ],
      "env": {
        "PLANFIX_ACCOUNT": "yourcompany",
        "PLANFIX_TOKEN": "your-api-token",
        "PLANFIX_FIELD_ID_EMAIL": "123",
        "PLANFIX_FIELD_ID_PHONE": "124",
        "PLANFIX_FIELD_ID_TELEGRAM": "1",
        "PLANFIX_FIELD_ID_TELEGRAM_CUSTOM": "125",
        "PLANFIX_FIELD_ID_CLIENT": "126",
        "PLANFIX_FIELD_ID_MANAGER": "127",
        "PLANFIX_FIELD_ID_AGENCY": "128",
        "PLANFIX_FIELD_ID_TAGS": "129",
        "PLANFIX_FIELD_ID_LEAD_ID": "130",
        "PLANFIX_LEAD_TEMPLATE_ID": "42",
        "PLANFIX_TASK_TITLE_TEMPLATE": "{name} - работа с клиентом"
      }
    }
  }
}

Uso

Executando o servidor

Execute o servidor com as variáveis de ambiente necessárias definidas. Exemplo (com npx):

PLANFIX_ACCOUNT=yourcompany \
PLANFIX_TOKEN=your-api-token \
PLANFIX_FIELD_ID_EMAIL=123 \
PLANFIX_FIELD_ID_PHONE=124 \
PLANFIX_FIELD_ID_TELEGRAM=1 \
PLANFIX_FIELD_ID_TELEGRAM_CUSTOM=125 \
PLANFIX_FIELD_ID_CLIENT=126 \
PLANFIX_FIELD_ID_MANAGER=127 \
PLANFIX_FIELD_ID_AGENCY=128 \
PLANFIX_FIELD_ID_LEAD_SOURCE=129 \
PLANFIX_FIELD_ID_LEAD_SOURCE_VALUE=130 \
PLANFIX_FIELD_ID_PIPELINE=131 \
PLANFIX_FIELD_ID_LEAD_ID=132 \
PLANFIX_FIELD_ID_TAGS=133 \
PLANFIX_LEAD_TEMPLATE_ID=42 \
PLANFIX_TASK_TITLE_TEMPLATE="{name} - работа с клиентом" \
npx @popstas/planfix-mcp-server

Para executar o servidor via Server-Sent Events (SSE), use o comando planfix-mcp-server-sse:

PLANFIX_ACCOUNT=yourcompany \
PLANFIX_TOKEN=your-api-token \
planfix-mcp-server-sse

Usando o cliente Planfix

O cliente Planfix fornece uma maneira conveniente de interagir com a API do Planfix diretamente da linha de comando.

Pré-requisitos

Certifique-se de ter as seguintes variáveis de ambiente definidas no seu arquivo .env:

PLANFIX_ACCOUNT=your-account
PLANFIX_TOKEN=your-api-token

Comandos básicos

  1. Testar a conexão

    npm run planfix test
    
  2. Fazer uma solicitação GET

    npm run planfix get user/current
    
  3. Fazer uma solicitação POST com dados

    npm run planfix post task/ --data '{"name":"Test Task","description":"Test Description"}'
    
  4. Pesquisar objetos

    npm run planfix post object/list --data '{"filters":[{"type":1,"operator":"equal","value":"Продажа"}]}'
    

Referência de Ferramentas

planfix_create_sell_task

  • Cria uma tarefa de venda usando informações textuais sobre a agência e o funcionário.
  • Resolve o cliente, a tarefa de lead pai, os responsáveis e os IDs da agência automaticamente com base nas strings fornecidas.
  • Campos de entrada (todas strings):
    • name: Título da tarefa, ex.: "Продажа {{ название товара }} на pressfinity.com".
    • agency: Nome da agência/empresa (opcional).
    • email: E-mail do funcionário usado para localizar o contato no Planfix.
    • contactName/employeeName: Nome completo do funcionário (opcional).
    • telegram: Nome de usuário do Telegram do funcionário (opcional).
    • description: Descrição com a lista de produtos pedidos.
    • project: Nome do projeto para associar à tarefa de venda (opcional).
  • Retorna { taskId, url }.

planfix_create_sell_task_ids

  • Cria uma tarefa de venda quando os identificadores do Planfix já são conhecidos.
  • Requer clientId numérico e leadTaskId, agencyId e assignees opcionais (IDs de usuário).
  • Aceita valores de string name, description e project opcional.
  1. Atualizar um objeto (solicitação PUT)

    npm run planfix put task/123 --data '{"name":"Updated Task Name"}'
    
  2. Excluir um objeto

    npm run planfix delete task/123
    

Usando em código

import { planfixClient } from './lib/planfix-client';

// Get current user
const user = await planfixClient.get('user/current');

// Create a new task
const newTask = await planfixClient.post('task/', {
  name: 'New Task',
  description: 'Task description',
  // ... other task properties
});

// Search for objects
const objects = await planfixClient.post('object/list', {
  filters: [
    {
      type: 1,
      operator: 'equal',
      value: 'Продажа'
    }
  ]
});

Ferramentas Disponíveis

Gerenciamento de Leads

  • leadToTask: Converte um lead em tarefa criando/atualizando contato e tarefa
  • searchLeadTask: Pesquisa tarefas de lead por informações de contato

Gerenciamento de Contatos

  • searchPlanfixContact: Pesquisa contatos por nome, telefone, e-mail ou Telegram. Quando o email principal não corresponde ao campo de e-mail principal, ele também é comparado com o campo de e-mail secundário do sistema (tipo de filtro 4221) e, quando PLANFIX_FIELD_ID_EMAIL_ADDITIONAL está definido, com esse campo personalizado (tipo de filtro 4101). Ambos os fallbacks se aplicam a uma pesquisa simples de email — o campo personalizado é onde este servidor grava extras, então um email isolado precisa ser comparado a ele para que um contato criado aqui seja encontrado novamente. O argumento opcional additionalEmails: string[] (máx. 10) adiciona cada endereço a esses mesmos fallbacks, além do campo de e-mail principal.
  • createPlanfixContact: Cria um novo contato no Planfix. Aceita um argumento additionalEmails: string[] opcional (máx. 10) que é gravado no campo personalizado de e-mails adicionais (PLANFIX_FIELD_ID_EMAIL_ADDITIONAL), deduplicado e excluindo o email principal. (O campo de e-mail secundário do sistema é somente leitura via API.)
  • updatePlanfixContact: Atualiza informações de contato existentes. Aceita um argumento additionalEmails: string[] opcional (máx. 10) que é mesclado no campo personalizado de e-mails adicionais. As gravações de campos personalizados do Planfix substituem todo o valor, então o campo é reescrito com a união do que já está armazenado lá e os endereços genuinamente novos; nada é perdido. Endereços já no contato — no campo personalizado, no campo de e-mail secundário do sistema somente leitura, ou como o email principal — não são adicionados novamente. Com forceUpdate, o campo é reescrito com exatamente os endereços que você passar, então um array vazio o limpa; omitir additionalEmails deixa o campo intocado de qualquer forma.
  • searchPlanfixCompany: Pesquisa empresas por nome

Gerenciamento de Tarefas

  • searchPlanfixTask: Pesquisa tarefas por título, ID do cliente e templateId opcional
  • createSellTask: Resolve IDs de contato/agência e cria uma tarefa de venda
  • createSellTaskIds: Cria uma tarefa de venda quando os IDs já são conhecidos
  • createLeadTask: Cria uma nova tarefa de lead. Quando chatApi.useChatApi está habilitado, envia a mensagem inicial através da API de Chat, obtém o taskId resultante via getTask e então atualiza a tarefa usando a API REST. Aceita campos message e contactName.
  • addToLeadTask: Cria ou atualiza uma tarefa de lead e atualiza os detalhes do contato. Aceita um argumento additionalEmails: string[] opcional (máx. 10) que percorre pesquisa, criação e atualização de contato (comparado com o campo de e-mail secundário do sistema e o campo personalizado PLANFIX_FIELD_ID_EMAIL_ADDITIONAL; gravado no campo personalizado). Quando webhook.enabled é verdadeiro, envia o payload de entrada para o endpoint do webhook, opcionalmente ignorando a API do Planfix se skipPlanfixApi estiver definido.
  • createTask: Cria uma tarefa usando campos de texto
  • createComment: Adiciona um comentário a uma tarefa
  • getChildTasks: Recupera tarefas filhas de uma tarefa pai. Use recursive para buscar todas as tarefas descendentes como uma lista plana; as tarefas retornadas incluem parent_task_id.
  • updateLeadTask: Atualiza uma tarefa de lead existente (apenas campos vazios são atualizados, a menos que forceUpdate seja verdadeiro)

Gerenciamento de Diretórios

  • planfix_search_directory: Pesquisa diretórios por nome
  • planfix_search_directory_entry: Pesquisa entrada de diretório por nome do diretório e nome da entrada

Gerenciamento de Usuários

  • searchManager: Encontra um gerente por e-mail

Relatórios

  • listReports: Lista todos os relatórios disponíveis
  • runReport: Gera e recupera um relatório específico

Referências

TODO:

  • Adicionar ferramenta getTask para recuperar detalhes de tarefas
  • Adicionar ferramenta getContact para recuperar detalhes de contatos
  • Adicionar ferramenta getManager para recuperar detalhes de gerentes
  • Adicionar tratamento de erros e registro de logs mais abrangentes
  • Adicionar validação de entrada para todos os endpoints da API
  • Adicionar lógica de limite de taxa e nova tentativa para chamadas de API

Licença MIT