Obsify

Detecção e redação de PII local e com preservação de privacidade via MCP: o modelo opera sobre a forma (schemas, gêmeos sintéticos, saída mascarada) enquanto o código local manipula os valores reais e retorna apenas resultados mascarados e agregados. Determinístico (Presidio + checksums, AU ABN/ACN/TFN), sem chamadas de LLM, sem rede em tempo de execução.

Documentação

obsify

CI PyPI Python License: MIT

Deixe um assistente de IA trabalhar em arquivos sensíveis sem que seus valores brutos entrem no contexto do modelo.

obsify é um servidor MCP local e determinístico. O modelo de fronteira raciocina sobre a forma — esquemas, gêmeos sintéticos, feedback mascarado — enquanto o código local determinístico toca a substância e retorna apenas resultados mascarados e agregados. Sem chamadas de LLM, sem rede em tempo de execução: a detecção é regex + checksums + dicionários + NER local do Presidio.

Ele vem com suporte a entidades australianas (ABN / ACN / TFN, validados por checksum), detecção de credenciais/segredos (chaves de nuvem, tokens de API, chaves privadas, strings de conexão de banco de dados) e uma camada de roteamento orientada por rótulos que torna "quando o assistente deve evitar dados brutos" uma decisão determinística e imposta, em vez de um julgamento.

Escopo honesto: run_on_real executa código escrito pelo modelo em um sandbox local de melhor esforço e mascara sua saída de melhor esforço. Não é uma prisão. Leia SECURITY.md antes de apontá-lo para qualquer coisa que você não possa se dar ao luxo de vazar. Retorne agregados.

Por quê

Alimentar documentos confidenciais a um LLM hospedado significa que a substância sai do seu perímetro. As respostas usuais são "não use o LLM" ou "confie no provedor". obsify segue um terceiro caminho — compute-to-data: traga o código para os dados, não os dados para o modelo.

  • O modelo vê o esquema de uma planilha, não suas linhas.
  • O modelo desenvolve contra um gêmeo sintético (valores falsos, estrutura real).
  • O código de análise do modelo é executado localmente; apenas a saída mascarada e agregada retorna.

O raciocínio do modelo de fronteira é preservado. Apenas seus olhos sobre valores brutos são removidos.

Ferramentas

FerramentaO que fazRetorna
scan_pii(path)Escaneia um arquivo/pasta para PIITipos, locais, contagens — nunca valores
make_synthetic_twin(path, out)Fiel falso de uma pasta de trabalho do ExcelResumo do esquema; gêmeo escrito em out (valores falsos, verificado contra vazamento)
run_on_real(code, data_path)Compute-to-data: execute seu código localmente contra o arquivo real (limitado a DATA_PATH)Apenas stdout/stderr mascarados para PII e com limite de tamanho — retorne agregados
redact_text(text)Mascara PII em uma string para tokens <TYPE>A string redigida
verify_value_free(text, terms)Verificação de falha fechada de que text não vaza nenhum de terms (ou suas variantes){"value_free": bool}

Documentos suportados: PDF (texto + tabelas; fallback para tabelas complexas via obsify[tables]), Excel .xlsx/.xlsm e Word .docx (parágrafos + tabelas). Arquivos ilegíveis ou não suportados são apresentados como notas/pontos cegos explícitos, nunca descartados silenciosamente. (Ainda sem OCR — páginas escaneadas/imagem são sinalizadas como baixa cobertura, não transcritas.)

Mascaramento de entidades conhecidas (opcional). Forneça uma lista local .obsify.entities de nomes para ocultar; scan_pii / redact_text os capturam deterministicamente — e as variantes de sufixo/abreviação que o NER não detecta (BRIGHTWATER HLDGS P/L para Brightwater Holdings Pty Ltd) — como KNOWN_ENTITY. A lista permanece local e nunca entra no contexto do modelo. Veja docs/known_entities.md.

Demonstração

Teste as cinco ferramentas ao vivo com dados sintéticos usando o MCP Inspector oficial:

python -m obsify.make_corpus --out ./corpus_demo
npx @modelcontextprotocol/inspector obsify-mcp

Chame scan_pii em ./corpus_demo/ledger.xlsx e confirme que ele retorna apenas tipos / contagens / locais — nunca valores. Veja docs/verifying.md.

Experimente — corpus sintético

Gere um corpus falso, mas realista (tudo sintético; ABN/ACN/TFN são válidos por checksum) abrangendo os três formatos e aponte uma ferramenta para ele:

pip install "obsify[demo]"                 # reportlab, for the sample PDFs
python -m obsify.make_corpus --out ./corpus_demo

Ele escreve um razão Excel com várias planilhas (um campo minado de falsos positivos numéricos), uma carta de compromisso em PDF (prosa + tabela de balancete) e um memorando de auditoria DOCX (parágrafos + tabela de fornecedores). Ótimo para testar scan_pii / make_synthetic_twin sem tocar em dados reais.

Instalação e execução como servidor MCP

Requer Python 3.11+. obsify fala MCP sobre stdio — o cliente o inicia como um subprocesso local; nada é hospedado remotamente. Registre-o em qualquer cliente compatível com MCP (Claude Desktop, Claude Code, Cursor, VS Code, …) adicionando um bloco à configuração desse cliente.

Recomendado — instalação zero via uvx:

{ "mcpServers": { "obsify": { "command": "uvx", "args": ["--from", "obsify", "obsify-mcp"] } } }

uvx busca obsify do PyPI e o executa sob demanda — sem instalação permanente. Na primeira execução, obsify baixa o modelo NER do spaCy (en_core_web_lg, ~560 MB) uma vez e o armazena em cache; isso busca um modelo público e não envia dados do usuário (defina OBSIFY_AUTO_DOWNLOAD=0 para proibir e instale o modelo você mesmo). Execuções posteriores são instantâneas e totalmente offline.

Ou instale-o (pip / pipx):

pipx install obsify        # isolated, on PATH  (or: pip install obsify)

Em seguida, aponte o cliente para o comando instalado:

{ "mcpServers": { "obsify": { "command": "obsify-mcp" } } }

Reinicie o cliente e as ferramentas aparecem. Extras opcionais: obsify[tables] (fallback de PDF com tabelas complexas via camelot + Ghostscript), obsify[compute] (pandas, útil dentro do código run_on_real).

Pegadinha do PATH (a causa nº 1 de "o servidor não conecta"): o command deve ser resolvido no PATH que o cliente vê. Um cliente GUI pode não compartilhar o PATH do seu venv. Correções: use uvx/pipx (globalmente resolvíveis) ou forneça um caminho absoluto — "/path/to/.venv/bin/obsify-mcp" (macOS/Linux) ou "C:\\path\\to\\.venv\\Scripts\\obsify-mcp.exe" (Windows).

Deste repositório (antes de estar no PyPI):

pip install "git+https://github.com/Formative-Sum41/obsify.git"   # gets `obsify-mcp` + `obsify`

A camada de roteamento — determinística, não um julgamento

A parte difícil de "me ajude, mas não leia o arquivo confidencial" é decidir quando proteger. obsify move essa decisão para fora do modelo e para o ambiente:

  1. .obsify.json — um manifesto de rótulos classificando caminhos (public / confidential / restricted).
  2. obsify.guard (executado como python -m obsify.guard) — uma proteção PreToolUse que bloqueia a leitura direta de um arquivo rotulado (saída 2) e redireciona o assistente para scan_pii / make_synthetic_twin / run_on_real.
  3. Uma convenção (em CLAUDE.md) para que o assistente prefira obsify antes mesmo de encontrar a proteção.

Configure com um comando:

obsify init [--dir PATH] [--with-claude-md]

obsify init é não destrutivo por design — ele possui exatamente um arquivo e fornece trechos para o resto:

  • .obsify.json — obsify é dono disso; init o escreve (nunca sobrescrito sem --force).
  • .claude/settings.jsonseu arquivo: init imprime o bloco de hook PreToolUse para colar, nunca o edita (ele executa código, então registrá-lo é sua decisão).
  • CLAUDE.mdseu arquivo: a convenção é opt-in. O padrão o imprime; --with-claude-md anexa um bloco idempotente envolto em marcadores que nunca sobrescreve seu conteúdo.

Convenção completa: docs/obsify_routing.md.

Como a detecção permanece precisa

  • Identificadores validados por checksum. Candidatos a ABN/ACN/TFN são propostos por regex e confirmados por seus checksums oficiais, então um número aleatório nunca é relatado como identificador.
  • IDs que exigem contexto. Um número puro só é aceito como ABN/ACN/TFN quando uma palavra de rótulo ("TFN", "ABN", "BSB", …) está próxima — isso elimina a enxurrada de falsos positivos de IDs sequenciais de diário em razões numéricos.
  • Supressão de sem letras / NER com dígitos. Números puros, valores, datas e códigos alfanuméricos não são sinalizados como nomes/orgs; nomes reais, e-mails e endereços (que contêm letras) não são afetados. PII validada sem letras permanece isenta: IDs com checksum (ABN/ACN/TFN/Medicare), cartões Luhn, IPs válidos, contas adjacentes a BSB e telefones (via contexto ou formato de telefone) — enquanto um ponto decimal ainda marca um valor, não um telefone.
  • Credenciais, não apenas PII. Chaves de nuvem (AWS/GitHub/Google/Slack/Stripe), JWTs, blocos de chave privada e strings de conexão de banco de dados são sinalizados como CREDENTIAL por padrões ancorados — prefixos de fornecedor (AKIA…, ghp_…) ou um secret = <value> controlado por palavra-chave, nunca heurísticas de entropia (que inundariam em colunas de razão hex/base64). Todo o bloco de chave privada BEGIN…END é mascarado, não apenas seu cabeçalho, para que nenhum corpo de chave seja deixado para trás.

Precisão medida

obsify inclui um harness de avaliação pontuado (eval/ — corpus sintético rotulado + chave de respostas + avaliador contra o detector de produção, além de uma verificação cruzada independente de terceiros). Destaque no corpus sintético: 100% de recall em itens esperados para detecção, 0 falsos positivos em uma planilha de tortura de FP numérica (com proteção de números agrupados), IDs puros controlados por contexto corretamente suprimidos. Verificação cruzada independente vs Microsoft presidio-research: EMAIL/IBAN 100%, PERSON 94%.

O harness provou seu valor — ele encontrou defeitos reais, que foram então corrigidos: cartões de crédito e números de telefone estavam sendo silenciosamente suprimidos pelo filtro de ruído numérico (agora isentos via validação de checksum / formato de telefone), e Medicare, IP, data de nascimento, passaporte australiano e carteira de motorista não tinham reconhecedor (agora adicionados, controlados por checksum ou contexto). Método completo, números e lacunas documentadas restantes (SWIFT/BIC, datas não-DOB): eval/README.md.

Testes

pip install -e ".[dev]"
pytest tests/            # or run any file directly: python tests/test_obsify.py

Treze suítes (88 testes), executadas em CI no Linux + Windows / Python 3.11 + 3.12:

  • mcp-protocol — inicia o servidor real via stdio e fala MCP com ele (o mesmo caminho que um cliente como Claude usa): confirma que todas as cinco ferramentas registram com esquemas válidos e que as chamadas fazem round-trip via JSON-RPC — incluindo scan_pii retornando apenas forma, de ponta a ponta.
  • checksums — ancorado em exemplos resolvidos de ABN/ACN/TFN publicados externamente (válidos e corrompidos), o que quebra a circularidade gerador↔validador.
  • obsify / twin / redaction — os invariantes de privacidade: saída apenas de forma, gêmeos sem vazamento e uma autoverificação de falha fechada.
  • precision — os supressores de falsos positivos eliminam o ruído de razão numérica mantendo nomes reais.
  • credentials — os padrões ancorados de segredos capturam chaves de nuvem / tokens / JWTs / blocos de chave privada / strings de conexão, enquanto os genéricos ancorados por palavra-chave permanecem precisos em prosa (sem entropia).
  • routing — a classificação de bloqueio/permissão da proteção e o contrato não destrutivo de obsify init.
  • corpus — o corpus sintético PDF+Excel+DOCX de ponta a ponta: detecção por formato, extração de parágrafos+tabelas do DOCX e saída apenas de forma em todos os formatos.
  • evaluation — o harness pontuado como portão de regressão (recall, supressão, tortura de FP, lacunas).
  • robustness — degradação graciosa: entradas corrompidas/sobredimensionadas/vazias/aninhadas/não suportadas nunca travam e são sempre apresentadas como notas.
  • model / variants — lógica de download automático do modelo na primeira execução; normalização de variantes por trás de verify_value_free.

Para verificação interativa (MCP Inspector) e a verificação de última milha com cliente ao vivo, veja docs/verifying.md.

Trabalhos relacionados

obsify é um dos vários servidores MCP que abordam "deixar uma IA tocar dados sensíveis com segurança" — eles são em sua maioria complementares, resolvendo o mesmo problema de extremidades diferentes. Vale a pena saber onde cada um se encaixa:

FerramentaAbordagemMelhor para
obsifyDetecção + isolamento de forma: o modelo vê apenas forma, gêmeos sintéticos e agregados mascarados — nunca os valores (reais ou falsos)Documentos bagunçados e não estruturados (PDF/Excel/DOCX) onde você não pode enumerar PII antecipadamente; isolamento estrito de valores; aplicação de quando proteger
cloakboxPré-sanitização orientada por políticas: tokenize um banco de dados em uma cópia desidentificada que o modelo consulta livrementeEsquemas conhecidos e estruturados onde você deseja análises ricas (joins/agregações) em uma cópia limpa referencialmente intacta
redact-mcpProxy de ofuscação reversível: o modelo trabalha com dados falsos consistentes; uma ferramenta proxy faz round-trip de chamadas reais de APIFluxos de pentest e segredos, onde o modelo deve operar em dados realistas e você restaura os reais depois
cms-aiserviço de redação empresarial: Presidio + spaCy por trás de REST/MCP, multilíngue, escalávelUma API de redação hospedada, multilíngue, com UI e escala horizontal

Onde o obsify é distinto: é o único desses em que o modelo não recebe nem valores brutos nem um espelho completo para operar — apenas forma + agregados mascarados — combinado com identificadores validados por checksum, detecção de credenciais, um guarda de roteamento determinístico e uma garantia rígida de sem-rede / sem-LLM. Esse é o extremo de isolamento mais estrito do espectro, ajustado para documentos financeiros confidenciais.

Troca honesta: o obsify otimiza isolamento dos valores em detrimento de utilidade nos dados. Se você precisar de análises referencialmente intactas em uma cópia limpa (cloakbox), round-tripping reversível (redact-mcp) ou um serviço hospedado multilíngue (cms-ai), esses são os mais adequados — e combinam bem com o obsify, em vez de competir com ele.

Contribuindo

PRs são bem-vindos — veja CONTRIBUTING.md para configuração, a barra de merge e os invariantes inegociáveis (sem chamadas de LLM na biblioteca, sem rede em tempo de execução, sem dados reais, forma-não-substância). Problemas de segurança: SECURITY.md (reporte em privado).

Licença

MIT — veja LICENSE.