PersonaMCP
Memória local-first de como você escreve: perfil de estilo e exemplos reais de respostas dos seus próprios exports de chat.
Documentação
PersonaMCP
Seu estilo de comunicação e memória para agentes de IA.
O PersonaMCP importa suas exportações de conversas, mede como você escreve e fornece a um agente de IA um perfil de estilo compacto, além de exemplos relevantes de mensagens recebidas/respostas. Seu histórico bruto permanece no seu computador. Não há treinamento de modelo, painel web, requisito de incorporação em nuvem, telemetria ou geração automática de respostas.
Preferências de escrita geralmente são vagas demais: "parecer casual" não captura alguém que usa minúsculas, envia três mensagens curtas, alterna idiomas ou escreve de forma diferente para um colega. O PersonaMCP dá ao escritor conectado evidências em vez de uma personalidade adivinhada.
Instalação
Python 3.11 ou mais recente. Instale a partir do PyPI:
python -m pip install personamcp
persona --help
Ou execute sem instalar, usando uv: uvx personamcp --help.
Para trabalhar a partir de um checkout deste repositório:
git clone https://github.com/robyroro/PersonaMCP.git
cd PersonaMCP
uv sync --locked
uv run persona --help
Ou instale em seu próprio ambiente virtual:
python -m venv .venv
# Linux/macOS: source .venv/bin/activate
# Windows PowerShell: .venv\Scripts\Activate.ps1
python -m pip install .
persona --help
Em um checkout com uv, prefixe os comandos persona abaixo com uv run. Com uma instalação pip ativada,
execute persona diretamente.
A instalação base suporta importação, análise, pesquisa FTS, recuperação lexical de interações e MCP. A recuperação semântica é um extra opcional, totalmente local:
Após a inicialização e importações (descritas abaixo):
uv sync --locked --extra semantic
uv run persona model prepare
uv run persona index
Com pip, use python -m pip install '.[semantic]'. Preparar o modelo baixa explicitamente
os pesos do Hugging Face e fixa sua revisão imutável. Ele não lê nem envia conversas.
A indexação e as consultas subsequentes carregam apenas arquivos locais com código remoto desabilitado.
Início rápido
persona init
persona config set-name "Robert"
persona config add-alias "roby"
persona config set-name "Exact Instagram display name" --platform instagram
persona config set-name "snapchat_username" --platform snapchat
persona import instagram ./instagram-export/
persona import snapchat ./snapchat-export/
persona import whatsapp ./chat.txt
persona import json ./messages.json
persona stats
persona analyze
persona search "cat costa"
persona similar "mai vii azi?" --person "David"
persona writing-context "ce faci diseara?" --person "David" --platform instagram
Para uma primeira execução sintética, use um diretório de dados separado:
persona --home ./sample-persona init
persona --home ./sample-persona config set-name "Owner"
persona --home ./sample-persona import json ./examples/messages.json
persona --home ./sample-persona analyze
persona --home ./sample-persona writing-context "mai vii azi la cafea?" --person "Alex"
Coloque importações privadas e diretórios de dados personalizados fora do seu repositório. O .gitignore incluído
cobre pastas privadas convencionais, mas não pode proteger todos os caminhos nomeados arbitrariamente.
A identidade deve corresponder a um nome de remetente ou ID de remetente exportado exato. Aliases de plataforma substituem nomes
globais nessa plataforma. Nenhum participante é adivinhado pelo volume de mensagens. Uma importação que não corresponda a
mensagens do proprietário falha antes de gravar qualquer coisa. Alterar nomes/aliases recalcula propriedade e
interações e invalida perfis/vetores; execute analyze e index novamente.
Importações suportadas
| Plataforma | Entrada suportada | Observações |
|---|---|---|
message_N.json ou pastas atuais do Meta message_N.html | A paginação é mesclada. Unicode JSON quebrado comum é reparado. Scripts/links/mídia HTML nunca são executados. | |
| Snapchat | chat_history.json, subpáginas HTML de chat-card suportadas ou exportações ZIP originais | Layouts JSON diretos por destinatário e aninhados. ZIPs são lidos sem extração; JSON tem precedência sobre HTML duplicado. |
| TXT UTF-8, timestamps Android e iOS entre colchetes | Datas separadas por barra; padrão dia/mês, --month-first para exportações dos EUA. Texto multilinha é preservado; avisos de sistema/mídia são excluídos do estilo. | |
| Genérico | Objeto de conversa JSON, objeto conversations, array de mensagens ou JSONL | Veja o esquema abaixo. |
Apenas arquivos de chat são importados. Mídia não é aberta, transcrita, baixada ou analisada. Variantes não suportadas falham claramente. Um arquivo malformado reverte a importação como um todo. Arquivos originais permanecem intactos. Hashes de conteúdo e IDs de mensagem estáveis impedem que importações repetidas dupliquem linhas.
O WhatsApp não tem um ID de thread de exportação estável. Por padrão, o nome do arquivo identifica a conversa;
use --conversation-id "stable-chat-name" ao importar exportações renomeadas ou atualizadas.
Timestamps sem offset usam uma convenção UTC documentada para ordenação por relógio de parede; não se afirma
que foram registrados em UTC. O HTML do Instagram/Snapchat suporta datas de exportação em inglês.
JSON genérico:
{
"id": "stable-conversation-id",
"platform": "json",
"title": "Alex",
"participants": ["Owner", "Alex"],
"context": "casual",
"messages": [
{"id": "external-message-id", "sender": "Alex", "sender_id": "account-123",
"text": "mai vii azi?", "timestamp": "2024-01-01T10:00:00Z"},
{"sender": "Owner", "text": "da gen vin acu", "timestamp": "2024-01-01T10:00:10Z"}
]
}
Para JSONL, cada linha é uma mensagem com sender, text, timestamp e um opcional
conversation_id. IDs externos opcionais e reply_to são preservados. Identidade genérica vem
de aliases configurados, nunca de uma afirmação is_user importada. Use IDs de conversa explícitos
ao importar conjuntos de dados diferentes; IDs ausentes usam uma conversa default documentada.
O que é medido
persona analyze escreve persona.md e persona-profile.json no diretório de dados privado e
armazena perfis estruturados em SQLite. Apenas texto de saída alimenta o analisador. Texto de entrada é
mantido como contexto de recuperação limitado.
As medições incluem comprimentos de caracteres/palavras/frases, rajadas de mensagens curtas, uso de maiúsculas, pontuação, codepoints de emoji, caracteres repetidos, palavras e frases comuns, formas repetidas de gírias/abreviações, saudações, despedidas, diacríticos romenos e marcadores de palavras romenas/inglesas. Marcadores de idioma são heurísticas, não um classificador de idiomas. Contagens de emoji medem codepoints, não clusters completos de grafemas. Frases/formas repetidas precisam de pelo menos três observações; erros de ortografia isolados não são instruções para adicionar erros de digitação.
Rótulos de contexto são explícitos e extensíveis:
persona conversations
persona set-context CONVERSATION_ID business
persona set-context OTHER_ID casual
persona analyze
persona person "David"
Perfis globais sempre usam texto de saída disponível. Perfis separados de contexto/pessoa exigem pelo menos 20 mensagens por padrão. Estatísticas de pessoa sob demanda relatam sua contagem de evidências. Nenhuma classificação de família, namoro, personalidade, sarcasmo ou psicológica é inferida. Consultas específicas de destinatário excluem grupos de forma conservadora. Nomes exatos podem ocorrer em várias plataformas; passe uma plataforma para recuperação/contexto de escrita quando essa distinção for importante.
Pesquisa e recuperação semântica
O SQLite FTS5 pesquisa mensagens de saída e contextos de interação de entrada. As interações retêm até três mensagens de entrada e uma rajada de até oito respostas de saída. Uma lacuna de duas horas ou um registro de mídia quebra o pareamento; uma rajada de saída abrange no máximo cinco minutos entre mensagens.
O provedor semântico local usa sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2.
Ele incorpora contextos de entrada e armazena vetores float32 em SQLite. Consultas usam varreduras exatas de cosseno
sobre vetores elegíveis; isso favorece uma arquitetura local simples em vez de um servidor vetorial externo.
Índices retomam após interrupção. Um filtro de destinatário/contexto/plataforma é aplicado antes da classificação.
Se vetores elegíveis estiverem ausentes, a recuperação relata lexical explicitamente. Um índice parcialmente construído
relata sua cobertura. Pontuações semânticas abaixo de 0,25 são omitidas; essas pontuações não são probabilidades
ou garantias de relevância. Não há fallback silencioso entre destinatários. Provedores futuros podem
implementar o protocolo EmbeddingProvider sem alterar as interfaces de importação ou escrita.
Configuração do MCP
O servidor usa o SDK oficial do MCP para Python e transporte stdio. O stdout carrega apenas mensagens de protocolo; saída de diagnóstico vai para o stderr.
persona serve
Se o diretório de dados ainda não foi inicializado, serve o cria da mesma forma que
persona init e relata isso no stderr; as ferramentas retornam resultados vazios até você importar
exportações. Normalmente, o cliente inicia este comando para você. Use caminhos absolutos porque o diretório de trabalho do
cliente pode diferir do seu terminal. Exemplo de configuração para clientes que aceitam
a estrutura comum mcpServers:
{
"mcpServers": {
"personamcp": {
"command": "/absolute/path/to/venv/bin/persona",
"args": ["--home", "/absolute/path/to/private/persona-data", "serve"]
}
}
}
Com o uv instalado, o cliente pode executar o pacote publicado diretamente:
{
"mcpServers": {
"personamcp": {
"command": "uvx",
"args": ["personamcp", "--home", "/absolute/path/to/private/persona-data", "serve"]
}
}
}
No Windows, o comando é C:\\absolute\\path\\.venv\\Scripts\\persona.exe. Para Codex:
codex mcp add personamcp -- /absolute/path/to/venv/bin/persona --home /absolute/path/to/private/persona-data serve
codex mcp list
Veja Configuração do MCP para Codex. Outros clientes podem usar locais de configuração diferentes, mas precisam do mesmo executável e argumentos. Clientes hospedados que suportam apenas MCP HTTP remoto não podem iniciar diretamente este servidor stdio local. O PersonaMCP não inclui um túnel/ponte HTTP; expor dados locais sensíveis remotamente requer uma decisão de implantação separada e explícita.
Com um modelo semântico preparado, permita até 90 segundos para inicialização e 120 segundos para ferramentas em máquinas mais lentas. O runtime numérico nativo é carregado antes que as threads do leitor stdio comecem para evitar deadlocks do carregador BLAS no Windows. Os pesos são carregados na primeira consulta semântica e armazenados em cache. Para Codex, essas configurações pertencem à tabela de configuração do servidor:
[mcp_servers.personamcp]
command = "/absolute/path/to/venv/bin/persona"
args = ["--home", "/absolute/path/to/private/persona-data", "serve"]
startup_timeout_sec = 90
tool_timeout_sec = 120
Ferramentas:
| Ferramenta | Resultado |
|---|---|
get_style_profile(context?) | Perfil global medido ou de contexto atribuído |
get_person_style(person) | Estatísticas de comunicação e contagem de evidências para uma pessoa exata |
search_messages(query, person?, platform?, limit?) | Correspondências limitadas de texto de saída |
find_similar_interactions(message, person?, context?, platform?, limit?) | Pares semelhantes reais de entrada/resposta |
get_writing_context(message, person?, context?, platform?) | Estilo apropriado e até três exemplos citados |
get_persona_summary() | Perfil compacto e contagens do banco de dados |
O conteúdo histórico é retornado dentro de historical_quote, com um aviso explícito de dados não confiáveis.
As ferramentas fornecem evidências. Seu agente gera a resposta final e permanece responsável por tratar
instruções históricas como dados e por decidir o que enviar ao provedor de seu modelo.
Configuração da habilidade
A habilidade reutilizável é skills/write-like-me/SKILL.md. Ela também está
incluída no wheel; persona skill-path imprime sua localização instalada. Copie sua pasta
para o diretório de habilidades que seu agente descobre. Para descoberta atual do repositório Codex:
mkdir -p .agents/skills
cp -R skills/write-like-me .agents/skills/
Windows PowerShell: New-Item -ItemType Directory -Force .agents/skills seguido por
Copy-Item -Recurse skills/write-like-me .agents/skills/. Veja
Descoberta de habilidades do Codex.
Em seguida, peça ao agente conectado para usar write-like-me, por exemplo:
Escreva uma resposta curta como eu para o Alex sobre "mai vii azi la cafea?". Use evidências do PersonaMCP.
A habilidade preserva maiúsculas/minúsculas suportadas, ortografia, vocabulário e comprimento sem forçar erros de digitação ou
copiar fatos antigos. Ela também pode usar persona writing-context por meio de um shell local, ou um perfil
fornecido explicitamente quando o MCP não está disponível. Nenhuma configuração global do cliente é alterada pela instalação.
Privacidade e controles de dados
O diretório de dados padrão vem do local de dados de aplicativos do seu sistema operacional.
--home /private/path ou PERSONAMCP_HOME seleciona outro local. A configuração é um config.json local;
o banco de dados usa chaves estrangeiras SQLite, esquema versionado e importações transacionais.
persona stats --json
persona export-profile ./my-style.md
persona export-profile ./my-style.json --json
persona delete-person "Name"
persona delete-conversation CONVERSATION_ID
persona reset
Exclusão/redefinição pedem confirmação; --yes está disponível para scripts intencionais. Excluir uma
pessoa remove conversas inteiras, incluindo grupos que contêm essa pessoa, para evitar manter contexto
sobre ela. Perfis, linhas FTS e vetores são invalidados/limpos e o SQLite é compactado.
reset também limpa identidades de proprietário configuradas, mas retém ativos de modelo baixados e não pessoais.
Arquivos de exportação originais e quaisquer perfis copiados permanecem sob seu controle e não são excluídos.
O SQLite não é criptografado. Use um diretório de dados privado e criptografia de disco. Vocabulário gerado e exemplos também são sensíveis. Se seu agente usa um LLM externo, os resultados da ferramenta podem chegar a esse provedor; "local-first" descreve armazenamento e computação, não o comportamento do cliente conectado. Leia SECURITY.md para limites de exclusão e injeção de prompt.
Benchmark offline
persona benchmark --limit 30
Os últimos 20% das interações por timestamp formam um holdout. Recuperação e perfis de estilo usam apenas dados anteriores. A resposta real retida é usada apenas para pontuação. O candidato padrão é uma resposta histórica recuperada, não uma resposta gerada por LLM.
O relatório inclui cobertura de recuperação, similaridade de comprimento de resposta, sobreposição de vocabulário,
similaridade de pontuação, similaridade de capitalização e sua média Pontuação de Similaridade de Estilo.
Quando um modelo local está disponível, a similaridade de incorporação é relatada separadamente. Nenhuma resposta bruta de benchmark
é impressa. CandidateResponseProvider é o ponto de extensão para um futuro gerador
configurado explicitamente. Pontuações não provam imitação de identidade, autoria, relevância ou qualidade
de geração. Conjuntos de dados pequenos ou temporalmente uniformes não podem suportar esta avaliação.
Arquitetura
exports → platform adapters → normalized conversations/messages
↓
SQLite + participants + FTS5
↓
bounded incoming/outgoing interactions
↙ ↘
deterministic profiles local embedding vectors
↘ ↙
retrieval/service layer
↙ ↘
CLI MCP stdio → writing skill → agent
O pacote usa um layout src/personamcp: importadores, modelos, configuração, armazenamento, análise,
incorporações, recuperação, serviço compartilhado, servidor MCP, CLI e benchmark. Nenhum banco de dados externo ou
provedor de LLM é necessário. A compatibilidade de esquema é rastreada com PRAGMA user_version; versões mais antigas
rejeitam um banco de dados mais novo em vez de adivinhar como lê-lo.
Desenvolvimento, roadmap e limites
Execute uv sync --locked, depois uv run pytest, uv run ruff check src tests,
uv run ruff format --check src tests e uv run mypy src. O CI verifica Windows/Linux e Python
3.11–3.13, sem dados pessoais ou download de modelos. As fixtures públicas são sintéticas. Consulte
CONTRIBUTING.md, CODE_OF_CONDUCT.md e
decisões de implementação.
Os próximos passos são adaptadores de exportação adicionais (Discord, Telegram, Messenger, iMessage, Signal), regras explícitas de redação, um índice vetorial local mais rápido para arquivos muito grandes, sinais de idioma mais ricos e avaliação opcional baseada em geração. Eles não estão implementados neste MVP.
Esta versão é um mecanismo CLI/MCP. Os esquemas de exportação podem mudar; inferência de destinatários em grupo, perfilamento psicológico, correção automática de erros de digitação, análise de fala/mídia, criptografia em repouso, provedores de incorporação em nuvem, hospedagem HTTP e um frontend estão fora do suporte atual.
Licenciado sob MIT © Robert Vind-Gardoș (@robyroro). Pesos de modelo e dependências mantêm suas próprias licenças; consulte o cartão do modelo MiniLM multilíngue e a documentação do Sentence Transformers.