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.
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_ratepor tema. - Componibilidade. Passe dados de churn ou tráfego de outros servidores MCP para o
generate_product_planviakpi_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ável | Obrigatória | Descrição |
|---|---|---|
HELPSCOUT_APP_ID | Não | ID do aplicativo OAuth do https://secure.helpscout.net/apps/custom/ (defina ambos ou nenhum) |
HELPSCOUT_APP_SECRET | Não | Segredo do aplicativo OAuth |
PRODUCTLIFT_PORTALS | Não | Multi-portal: name|url|key,name2|url2|key2 |
PRODUCTLIFT_PORTAL_URL | Não | URL de portal único |
PRODUCTLIFT_API_KEY | Não | Token Bearer de portal único |
PRODUCTLIFT_PORTAL_NAME | Não | Nome de exibição do portal (padrão: default) |
CHATBASE_API_KEY | Não | Chave secreta da conta em Chatbase → Configurações → Chaves de API |
CHATBASE_AGENTS | Não | Multi-agente: name|agentId,name2|agentId2 |
CHATBASE_AGENT_ID | Não | ID de agente único |
CHATBASE_AGENT_NAME | Não | Nome 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âmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
timeframe_days | número | 30 | Dias para olhar para trás (1-90) |
top_voted_limit | número | 50 | Solicitações mais votadas por portal (1-200). Solicitações recentes no período são sempre incluídas no topo |
mailbox_id | string | — | ID da caixa de entrada do HelpScout |
mailbox_name | string | — | Nome da caixa de entrada do HelpScout (insensível a maiúsculas), resolvido para um ID |
portal_name | string | — | Portal do ProductLift |
agent_name | string | — | Agente do Chatbase |
source_filter | string | — | 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_comments | booleano | false | També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_level | string | "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âmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
kpi_context | string | — | Métricas de negócio de outros servidores MCP, passadas literalmente |
max_priorities | número | 5 | Número de prioridades a retornar (1-10) |
preview_only | booleano | false | Modo de auditoria: mostra quais dados seriam enviados, sem buscá-los |
format | string | "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âmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
theme_id | string | — | O theme_id da análise, ex.: booking-scheduling |
source | string | "all" | "all", "tickets", "feature_requests" ou "chats" |
limit | número | 25 | Registros 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âmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
portal_name | string | — | Filtra para um portal |
include_comments | booleano | true | Inclui comentários em cada solicitação |
status | string | — | Filtra por status (insensível a maiúsculas), ex.: open, planned, completed |
limit | nú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 |
sort | string | — | "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
| Classe | Fonte | O que significa | Alimenta |
|---|---|---|---|
| Reativa | Tickets do HelpScout | Algo está quebrado | Frequência, gravidade, convergência |
| Proativa | Solicitações do ProductLift | Algo é desejado | Frequência, impulso de votos, convergência |
| Desviada | Conversas do Chatbase | Algo foi perguntado, e o autoatendimento resolveu ou não | Apenas 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 temaself_serve_failure_rate: parcela delas em que a menor confiança de resposta do agente caiu abaixo de 0,5mean_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: trueemgenerate_product_planmostra o que seria enviado sem buscar dados.- Toda resposta inclui
pii_scrubbing_appliedepii_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.envexiste 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 deHELPSCOUT_*.- As alterações não estão surtindo efeito. O cliente executa o
dist/compilado. Executenpm run builde reinicie o cliente. No HelpScout mailbox named "…". Executelist_sourcespara nomes exatos, ou passemailbox_id.No portal found with name "…"/No ProductLift portal named "…". O portal deve estar emPRODUCTLIFT_PORTALS(ou nas variáveis de portal único). Executelist_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_agentsestá vazio emlist_sources. Defina ambosCHATBASE_API_KEYe um deCHATBASE_AGENTS/CHATBASE_AGENT_ID. Uma chave sozinha não configura nada.
Contribuindo
Veja CONTRIBUTING.md.