PM Copilot

Triangula tickets de suporte ao cliente e solicitações de funcionalidades para gerar planos de produto priorizados com pontuação de convergência e remoção de PII.

Documentação

PM Copilot

Um servidor MCP que triangula tickets de suporte ao cliente, solicitações de recursos e conversas de agentes de suporte com IA para ajudar gerentes de produto a decidir o que construir em seguida.

TypeScript License: MIT MCP SDK Node.js


Resultados reais: Analisou 3.353 sinais em uma janela de 30 dias: 1.678 tickets de suporte, 276 solicitações de recursos e 1.399 conversas de agentes de suporte com IA em 4 produtos.

Os chats são um sinal que uma análise baseada apenas em tickets nunca enxerga.

Leia a história completa: Construí um servidor MCP que mudou como priorizo produtos


O que torna isso diferente

  • Triangulação de sinais. Cruza tickets de suporte com solicitações de recursos para encontrar temas convergentes e dá a temas convergentes um impulso de prioridade de 2x.
  • O ponto cego do desvio. Um agente de suporte com IA responde perguntas que nunca viram tickets, então a priorização baseada em tickets subestima todo tema que o bot resolve. Conversas do Chatbase entram como uma terceira classe de sinal, com um self_serve_failure_rate por tema.
  • Componibilidade. Passe dados de churn ou tráfego de outros servidores MCP para o generate_product_plan via kpi_context, e a metodologia ajusta as prioridades.

Arquitetura

graph TD
    A[Claude Desktop / Code] -->|stdio| B[pm-copilot]
    A -->|stdio| C[Metabase MCP]
    A -->|stdio| D[Google Analytics MCP]
    B -->|Reactive| E[HelpScout: tickets]
    B -->|Proactive| F[ProductLift: feature requests]
    B -->|Deflected| I[Chatbase: AI agent chats]
    C -->|Quantitative| G[Conversion, Churn, Revenue]
    D -->|Acquisition| H[Traffic, Channels, Trends]
    B -.->|kpi_context| A

Início rápido

Requer Node 20+. Não publicado no npm, então instale a partir do código-fonte:

git clone https://github.com/dkships/pm-copilot.git
cd pm-copilot
npm install
cp .env.example .env   # Edit with your credentials
npm run build

O .env fica na raiz do repositório. O servidor o carrega de lá independentemente do diretório de trabalho a partir do qual é iniciado.

Credenciais

Configure pelo menos uma fonte; a análise se adapta a qualquer uma que você configurar. Sem HelpScout não há tickets de suporte, então os temas não recebem pontuação de gravidade nem impulso de convergência; ProductLift e Chatbase ainda classificam os temas por frequência e votos.

VariávelObrigatóriaDescrição
HELPSCOUT_APP_IDNãoID do aplicativo OAuth do https://secure.helpscout.net/apps/custom/ (defina ambos ou nenhum)
HELPSCOUT_APP_SECRETNãoSegredo do aplicativo OAuth
PRODUCTLIFT_PORTALSNãoMulti-portal: name|url|key,name2|url2|key2
PRODUCTLIFT_PORTAL_URLNãoURL de portal único
PRODUCTLIFT_API_KEYNãoToken Bearer de portal único
PRODUCTLIFT_PORTAL_NAMENãoNome de exibição do portal (padrão: default)
CHATBASE_API_KEYNãoChave secreta da conta em Chatbase → Configurações → Chaves de API
CHATBASE_AGENTSNãoMulti-agente: name|agentId,name2|agentId2
CHATBASE_AGENT_IDNãoID de agente único
CHATBASE_AGENT_NAMENãoNome de exibição do agente único (padrão: default)

O acesso à API do Chatbase exige um plano Standard ou superior; em um plano inferior, o sinal de desvio se torna um aviso. Um agente por produto dá atribuição em nível de produto que uma caixa de entrada compartilhada não dá.

Claude Desktop

Adicione ao ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "pm-copilot": {
      "command": "node",
      "args": ["/absolute/path/to/pm-copilot/dist/index.js"]
    }
  }
}

Claude Code

claude mcp add pm-copilot -- node /absolute/path/to/pm-copilot/dist/index.js

Ou abra o Claude Code no repositório: ele solicita que você aprove o .mcp.json do projeto.

Verificação

Reinicie o cliente e peça para executar list_sources. Ele deve listar as fontes que você configurou: caixas de entrada do HelpScout, portais do ProductLift e agentes do Chatbase.

Ferramentas

Filtros comuns

Compartilhados por synthesize_feedback e generate_product_plan.

ParâmetroTipoPadrãoDescrição
timeframe_daysnúmero30Dias para olhar para trás (1-90)
top_voted_limitnúmero50Solicitações mais votadas por portal (1-200). Solicitações recentes no período são sempre incluídas no topo
mailbox_idstring—ID da caixa de entrada do HelpScout
mailbox_namestring—Nome da caixa de entrada do HelpScout (insensível a maiúsculas), resolvido para um ID
portal_namestring—Portal do ProductLift
agent_namestring—Agente do Chatbase
source_filterstring—Fonte de conversa do Chatbase, separada por vírgulas para múltiplas (ex.: Widget or Iframe ou WhatsApp,API). Insensível a maiúsculas
include_commentsbooleanofalseTambém busca texto de comentários de clientes em solicitações de recursos (limpo; nomes e respostas de administradores removidos) para correspondência de temas e citações. Um ganho modesto por uma chamada extra por solicitação com comentários; pode levar quase um minuto em portais grandes
detail_levelstring"summary""summary", "standard" ou "full". A saída cresce a cada etapa

Execute list_sources para ver nomes válidos de caixas de entrada, portais, agentes e fontes.

synthesize_feedback

Retorna temas ordenados por pontuação de prioridade, cada um com contagens por classe, um indicador de convergência, um resumo de evidências e citações representativas. Aproximadamente 15KB em summary, várias centenas de KB em full. Apenas filtros comuns.

generate_product_plan

Constrói um plano priorizado com evidências e citações de clientes. Aceita os filtros comuns mais:

ParâmetroTipoPadrãoDescrição
kpi_contextstring—Métricas de negócio de outros servidores MCP, passadas literalmente
max_prioritiesnúmero5Número de prioridades a retornar (1-10)
preview_onlybooleanofalseModo de auditoria: mostra quais dados seriam enviados, sem buscá-los
formatstring"json""json" (estruturado) ou "markdown" (resumo pronto para leitura)

get_theme_evidence

Aprofunda em um tema: os tickets, solicitações de recursos e chats individuais por trás dele, do mais recente ao mais antigo, com números de tickets, URLs de solicitações, votos, canais e datas. Passe os mesmos filtros comuns dentro de alguns minutos da chamada de análise e ele reutiliza os dados em cache, então não faz novas chamadas de API. Retorna identificadores, metadados e títulos limpos (para um chat, a mensagem de abertura do cliente, truncada em 200 caracteres), não conversas completas.

ParâmetroTipoPadrãoDescrição
theme_idstring—O theme_id da análise, ex.: booking-scheduling
sourcestring"all""all", "tickets", "feature_requests" ou "chats"
limitnúmero25Registros por fonte (1-200), para que uma fonte movimentada não domine as outras

Mais os filtros comuns.

get_feature_requests

Acesso bruto ao ProductLift. Cada solicitação inclui seu url público.

ParâmetroTipoPadrãoDescrição
portal_namestring—Filtra para um portal
include_commentsbooleanotrueInclui comentários em cada solicitação
statusstring—Filtra por status (insensível a maiúsculas), ex.: open, planned, completed
limitnúmero—Solicitações a retornar por portal (1-500), após o filtro de status e a ordenação. Comentários são buscados apenas para o que for mantido
sortstring—"votes" ou "recent". Omita para manter a ordem do portal

list_sources

Lista caixas de entrada, portais e agentes configurados, além de chatbase_conversation_sources (os valores que source_filter aceita) quando o Chatbase está configurado. Nunca retorna chaves ou dados de clientes. Sem parâmetros.

Classes de sinal

ClasseFonteO que significaAlimenta
ReativaTickets do HelpScoutAlgo está quebradoFrequência, gravidade, convergência
ProativaSolicitações do ProductLiftAlgo é desejadoFrequência, impulso de votos, convergência
DesviadaConversas do ChatbaseAlgo foi perguntado, e o autoatendimento resolveu ou nãoApenas frequência

Sinais desviados nunca afetam gravidade, impulso de votos ou o impulso de convergência. Cada tema carrega:

  • deflected_count: conversas que correspondem ao tema
  • self_serve_failure_rate: parcela delas em que a menor confiança de resposta do agente caiu abaixo de 0,5
  • mean_answer_confidence: média dessa mesma pontuação

O Chatbase não documenta o que seu min_score mede, então esses são evidências para o LLM ponderar, não parte da pontuação. A análise também conta conversas por canal (chatbase_sources). Um valor de source_filter não reconhecido é passado adiante com um aviso, não rejeitado. Sem Chatbase, os campos de desvio ficam ausentes.

Exemplo de saída

Uma resposta synthesize_feedback reduzida no nível de detalhe summary. Os valores são ilustrativos. Observe o e-mail limpo na primeira citação.

{
  "timeframe_days": 30,
  "detail_level": "summary",
  "pii_scrubbing_applied": true,
  "pii_categories_redacted": ["email", "phone", "credit_card"],
  "analysis": {
    "total_data_points": 924,
    "reactive_count": 548,
    "proactive_count": 64,
    "deflected_count": 312,
    "themes": [
      {
        "theme_id": "booking-scheduling",
        "label": "Booking & Scheduling",
        "priority_score": 78.4,
        "convergent": true,
        "reactive_count": 211,
        "proactive_count": 19,
        "deflected_count": 96,
        "self_serve_failure_rate": 0.41,
        "representative_quotes": [
          "[Support ticket] \"Double-booked slots again after the timezone change — reach me at [EMAIL REDACTED]\"",
          "[Feature request, 47 votes] \"Let me block buffer time between meetings\"",
          "[AI chat, answer confidence 0.31] \"how do i stop people booking on weekends\""
        ]
      }
    ],
    "emerging_themes": [{ "pattern": "csv export", "frequency": 12 }],
    "unmatched_count": 38
  }
}

Componibilidade

Peça ao Claude para puxar dados de churn e conversão de seus outros servidores MCP e passá-los como kpi_context:

Product A: booking completion rate dropped from 74% to 66% over last
30 days. Monthly churn increased from 3.1% to 4.2%. Organic traffic
up 22% MoM. Product B: document completion rate steady at 81%.
Churn flat at 2.8%.

A metodologia diz que o churn substitui a fórmula, então um tema ligado à queda na taxa de conclusão do Produto A pode saltar para o #1 mesmo quando outro tema pontua mais alto. O servidor classifica o sinal; o contexto de KPI fornece o julgamento.

Metodologia

O recurso pm-copilot://methodology é meu framework de planejamento de produtos de 7 anos lançando 9 produtos para mais de 1M de usuários. As regras centrais:

  • A regra dos 5%. Você conclui cerca de 5% do que os clientes pedem a cada mês. O framework escolhe quais 5%.
  • Sinais convergentes vencem. Um tema presente tanto em tickets quanto em solicitações de recursos é o sinal de maior confiança.
  • Reativo > proativo. Coisas quebradas geram churn. Você sobrevive a um recurso ausente; não sobrevive a erros.
  • Métricas de negócio substituem a fórmula. Churn crescente ou conversão em queda muda tudo.

É versionado (v2.2). Toda resposta generate_product_plan linka para ele e diz ao Claude para aplicá-lo quando kpi_context estiver definido. Se ele será lido depende de o cliente expor recursos.

Avaliação

Os temas são correspondidos com listas de palavras-chave, não embeddings ou um classificador LLM. O texto do cliente nunca sai do servidor, e a mesma entrada sempre produz os mesmos temas, então uma classificação pode ser auditada. O custo é a revocação.

npm run eval mede isso. No fixture de 86 exemplos versionado, a configuração v3 pontua precisão micro de 96,1%, revocação de 99,0%, F1 de 97,5%, com taxa de falha de 1,3%. Esse número é dentro da amostra (a configuração foi ajustada contra ela), então é um portão de regressão. Em dados reais de chat fora da amostra, um terço das conversas ainda não corresponde a nenhum tema.

Resultados completos, o que a primeira execução encontrou e limites conhecidos: docs/evaluation.md.

Segurança

Todo texto de cliente é limpo antes de entrar na análise ou sair do servidor:

  • SSNs, cartões de crédito (validados por Luhn), endereços de e-mail e números de telefone (formatos dos EUA e internacionais com prefixo +) são mascarados, e também limpos das URLs de solicitações de recursos. O campo de e-mail do cliente é sempre [REDACTED].
  • Respostas de agentes/administradores, notas internas, anexos, identidades de votantes, nomes de comentaristas e turnos de assistente do Chatbase, formulários de lead, IDs de usuário e país são excluídos por completo.
  • preview_only: true em generate_product_plan mostra o que seria enviado sem buscar dados.
  • Toda resposta inclui pii_scrubbing_applied e pii_categories_redacted.

Detalhes, limitações conhecidas e o processo de relato: SECURITY.md.

Configuração de temas

O themes.config.json na raiz do repositório define os temas. Ele é lido em tempo de execução, então edições não precisam de recompilação. Ele vem com 18 temas em 12 categorias; adicione os seus ao array themes. Pontos de dados sem correspondência são minerados para padrões emergentes com frequência de bigramas/trigramas.

Palavras-chave de uma palavra correspondem em um limite de palavra com plural regular opcional. Palavras-chave de várias palavras também correspondem em limites de palavra. Após editar, execute npm run eval para detectar palavras-chave que disparam no tema errado.

Fórmula de pontuação

priority = (frequency × 0.35 + severity × 0.35 + vote_momentum × 0.30) × convergence_boost
  • Frequência (0,35): contagem de pontos de dados, normalizada entre temas. Inclui sinais desviados.
  • Gravidade (0,35): apenas sinais reativos. Contagem de threads, recência (decaimento de meia-vida de 7 dias) e um impulso da tag de maior gravidade correspondente.
  • Impulso de votos (0,30): apenas sinais proativos. 80% votos, 20% comentários.
  • Convergência (2x): aplicada quando um tema tem sinais reativos e proativos. Sinais desviados não a acionam.

Frequência e impulso de votos são normalizados contra o tema principal na mesma chamada, então as pontuações são relativas a uma janela de análise. Compare classificações entre chamadas, não pontuações brutas.

Solução de problemas

  • No data sources configured. Verifique se .env existe na raiz do repositório e define pelo menos uma fonte.
  • HELPSCOUT_APP_SECRET is missing (ou _ID). Defina ambos os valores do HelpScout, ou remova ambos para executar sem o HelpScout.
  • HelpScout auth expired or invalid (403) em cada chamada. Se a solicitação de token for bem-sucedida, mas as chamadas de API retornarem 403, o usuário do HelpScout que possui o aplicativo OAuth foi desativado ou perdeu o acesso. Rotacionar o segredo não ajudará; crie um novo aplicativo a partir do perfil de um usuário ativo e atualize ambos os valores de HELPSCOUT_*.
  • As alterações não estão surtindo efeito. O cliente executa o dist/ compilado. Execute npm run build e reinicie o cliente.
  • No HelpScout mailbox named "…". Execute list_sources para nomes exatos, ou passe mailbox_id.
  • No portal found with name "…" / No ProductLift portal named "…". O portal deve estar em PRODUCTLIFT_PORTALS (ou nas variáveis de portal único). Execute list_sources.
  • Aviso do Chatbase: API access needs a Chatbase Standard plan or higher. O restante da análise ainda é executado; apenas os campos de deflexão estão ausentes.
  • chatbase_agents está vazio em list_sources. Defina ambos CHATBASE_API_KEY e um de CHATBASE_AGENTS / CHATBASE_AGENT_ID. Uma chave sozinha não configura nada.

Contribuindo

Veja CONTRIBUTING.md.

Licença

MIT