Metadata-Version: 2.4
Name: nomos-ai
Version: 0.1.5
Summary: Document anonymization MCP server for legal use
Requires-Python: >=3.10
Requires-Dist: mcp[cli]>=1.0
Requires-Dist: pdfminer-six>=20221105
Requires-Dist: pdfplumber>=0.11
Requires-Dist: presidio-analyzer>=2.2.351
Requires-Dist: presidio-anonymizer>=2.2.351
Requires-Dist: pypdf>=4.0
Requires-Dist: python-docx>=1.1
Requires-Dist: spacy<3.9,>=3.8
Description-Content-Type: text/markdown

# NomosAI — Anonymiseur de documents juridiques

Détecte et masque les données personnelles dans des documents `.docx`, `.pdf`, `.txt`, `.md` et `.rst`, et produit un Markdown structuré avec métadonnées de conformité.  
Moteur : [Microsoft Presidio](https://github.com/microsoft/presidio) + [spaCy](https://spacy.io/) · **Langue par défaut : français**.

Distribué comme **serveur MCP** — utilisable directement depuis Claude Desktop ou Claude Code, sans interface graphique.

---

## Installation rapide

**Étape 1 — Installer `uv` (une seule fois par machine) :**

- **Windows :** ouvre PowerShell et colle :
  ```
  powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
  ```
- **Mac :** ouvre Terminal et colle :
  ```bash
  curl -LsSf https://astral.sh/uv/install.sh | sh
  ```

**Étape 2 — Ajouter NomosAI à Claude Desktop :**

Directement dans claude code:
```claude code
claude mcp add nomos-ai -- uvx nomos-ai
```

Ou manuellement:

Édite `%APPDATA%\Claude\claude_desktop_config.json` (Windows) ou  
`~/Library/Application Support/Claude/claude_desktop_config.json` (Mac) :

```json
{
  "mcpServers": {
    "nomos-ai": {
      "command": "uvx",
      "args": ["nomos-ai"]
    }
  }
}
```

Redémarre Claude Desktop. Au premier démarrage, `uvx` télécharge automatiquement toutes les dépendances (modèle spaCy `fr_core_news_lg` inclus, ~600 Mo) — environ 1 à 3 minutes. Les démarrages suivants sont instantanés.

Pour plus de détails, voir le **[Guide d'utilisation MCP](NomosAI-Anonymisation-UserGuide.md)

**.

---

## Mettre à jour NomosAI

`uvx` met en cache la version installée. Pour forcer la mise à jour vers la dernière version publiée sur PyPI :

```bash
uvx --reinstall nomos-ai
```

Puis redémarrez Claude Desktop pour que le nouveau serveur soit pris en compte.

---

## Formats supportés

| Entrée | Librairie |
|--------|-----------|
| `.docx` | `python-docx` |
| `.pdf` | `pdfminer.six` (fallback : `pypdf`) |
| `.txt` / `.md` / `.rst` | natif |

---

## Anonymisation

```bash
# Fichier unique (sortie : <nom>_anonymise.md)
python anonymize.py rapport.pdf

# Sortie explicite
python anonymize.py contrat.docx --output contrat_anon.md

# Dossier complet
python anonymize.py dossier/ --output dossier_anonymise/

# Dossier récursif
python anonymize.py dossier/ --recursive --language fr

# Limiter les types d'entités
python anonymize.py notes.txt --entities PERSON EMAIL_ADDRESS PHONE_NUMBER

# Ajuster le seuil de confiance (défaut : 0.55)
python anonymize.py file.pdf --score-threshold 0.6

# Activer les entités opt-in (dates, chemins fichiers)
python anonymize.py file.pdf --entities PERSON DATE_TIME FILE_PATH
```

Chaque exécution produit deux fichiers :

| Fichier | Contenu |
|---------|---------|
| `<nom>_anonymise.md` | Document anonymisé avec frontmatter YAML |
| `<nom>_anonymise-index.md` | **Confidentiel** — table `placeholder → valeur originale` |

En mode dossier, un `RAPPORT_ANONYMISATION.md` de synthèse est également généré.

---

## Désanonymisation

Restaure les valeurs originales à partir de l'index.

```bash
# Index auto-détecté (<fichier>-index.md voisin)
python deanonymize.py contrat_anonymise.md

# Index explicite
python deanonymize.py contrat_anonymise.md --index contrat_anonymise-index.md

# Sortie explicite
python deanonymize.py contrat_anonymise.md --output contrat_restaure.md

# Dossier complet
python deanonymize.py dossier_anonymise/ --output dossier_restaure/
```

> ⚠ Ce script restaure des données personnelles. Réservez-le aux personnes habilitées.

---

## Entités détectées

### Par défaut

| Entité | Label | Description |
|--------|-------|-------------|
| `PERSON` | `[PERSONNE_N]` | Noms de personnes (NLP + titres Pr/Dr/M./Mme) |
| `ORGANIZATION` | `[ORGANISATION_N]` | Noms d'organisations |
| `LOCATION` | `[ADRESSE_N]` | Lieux, adresses |
| `EMAIL_ADDRESS` | `[EMAIL_N]` | Adresses e-mail |
| `PHONE_NUMBER` | `[TELEPHONE_N]` | Numéros français (+33, 0033, local) |
| `URL` | `[URL_N]` | URLs |
| `IP_ADDRESS` | `[IP_N]` | Adresses IP |
| `CREDIT_CARD` | `[CARTE_BANCAIRE_N]` | Numéros de carte bancaire |
| `IBAN_CODE` | `[IBAN_N]` | IBAN |
| `NRP` | `[ID_NATIONAL_N]` | Identifiants nationaux |
| `MEDICAL_LICENSE` | `[LICENCE_MEDICALE_N]` | Licences médicales |
| `CRYPTO` | `[CRYPTO_N]` | Adresses crypto |

### Reconnaisseurs français supplémentaires

| Entité | Label | Exemples |
|--------|-------|---------|
| `FR_NIR` | `[NIR_N]` | Numéro de sécurité sociale (15 chiffres) |
| `FR_SIRET` | `[SIRET_N]` | SIRET (14 chiffres) |
| `FR_SIREN` | `[SIREN_N]` | SIREN (9 chiffres) |
| `FR_TVA` | `[TVA_N]` | TVA intracommunautaire |
| `FR_PASSPORT` | `[PASSEPORT_N]` | Passeport français |
| `FR_CNI` | `[CNI_N]` | Carte nationale d'identité |
| `FR_DRIVING_LICENSE` | `[PERMIS_N]` | Permis de conduire |
| `FR_POSTAL_CODE` | `[CODE_POSTAL_N]` | Code postal (avec contexte) |

### Entités opt-in (à activer via `--entities`)

| Entité | Label | Remarque |
|--------|-------|---------|
| `DATE_TIME` | `[DATE_N]` | Dates — exclus par défaut (bruit dans les rapports) |
| `FILE_PATH` | `[CHEMIN_FICHIER_N]` | Chemins Windows/Unix — français uniquement, exclus par défaut |

---

## Architecture

```
anonymize.py              CLI principal (lecture, anonymisation, écriture)
deanonymize.py            CLI de restauration à partir de l'index
src/
  nomosai/
    readers.py            Lecture DOCX/PDF/TXT/MD/RST → liste de Block
    engine.py             Moteur Presidio + filtres faux positifs + dédup spans
    recognizers_fr.py     Reconnaisseurs regex français (NIR, SIRET, téléphone…)
    formatter.py          Rendu Markdown + frontmatter
    server.py             Serveur MCP (FastMCP, transport stdio)
pyproject.toml            Métadonnées du package et dépendances
```

**Pipeline :** `Reader → Engine → Formatter → fichier .md + fichier -index.md`

---

## Qualité de détection

### Seuils de confiance

Le seuil global par défaut est `0.55`. Certains types ont un plancher plus élevé pour réduire les faux positifs :

| Type | Seuil minimum |
|------|---------------|
| `LOCATION` | 0.80 (sur-détection dans les tableaux PDF) |
| `FR_SIREN` | 0.70 |
| `FR_CNI` | 0.70 |
| `FR_POSTAL_CODE` | 0.70 |

### Filtres anti-faux-positifs

L'engine rejette automatiquement les détections dont le texte :
- est une lettre ou sigle de 1–3 caractères (`F`, `NR`, `ET`…)
- est une valeur statistique (`N=1 035`, `75,6`…)
- est un numéro de section (`II.4`, `I.1`…)
- est un fragment tout-en-majuscules multi-mots (en-tête de tableau)
- contient des artefacts OCR (espaces intrus dans un mot)

---

## Ajouter un reconnaisseur personnalisé

```python
from presidio_analyzer import PatternRecognizer, Pattern

MY_RECOGNIZER = PatternRecognizer(
    supported_entity="MY_ENTITY",
    supported_language="fr",
    patterns=[Pattern("MY_PATTERN", r"\bREGEX\b", score=0.85)],
    context=["mot", "clé", "contextuel"],
)
```

Ajouter l'instance dans `get_french_recognizers()` de `src/nomosai/recognizers_fr.py` et son label dans `FRENCH_ENTITY_LABELS`.

Voir la [doc Presidio](https://microsoft.github.io/presidio/analyzer/adding_recognizers/).

---