Files
Adriano 54bf41efd6 fix(mcp-docugen): preprocessor HTML→Markdown per output Word leggibile
Il DOCX prodotto dalla versione precedente emetteva i div Tielogic
(`<div class="cover">`, `<div class="info-col">`, `<div class="acceptance">`,
`<div class="status-card">`) come testo grezzo: Pandoc non sa
interpretare il CSS-flavoured HTML del PDF e li copia letteralmente
nel documento Word. Anche le tabelle `<table class="financial">`
finivano spezzate cella per cella.

Il fix introduce un preprocessor dedicato che riscrive tutta la
HTML Tielogic-flavoured in Markdown nativo prima di passare il
documento a Pandoc.

- docx_preprocessor.py: nuovo modulo basato su BeautifulSoup. Strippa
  frontmatter e <style>, poi rewrite di:
    * <div class="cover"> → titoli H1/H2, paragrafi, tabella pipe
      2-col FORNITORE/CLIENTE, validità in italic, \newpage finale
    * <table class="financial"> → tabella pipe Markdown con riga
      total-row in **bold**
    * <div class="acceptance"> → heading H2 + intro + tabella pipe
      con riga firma `_____________________` + luogo/data
    * <div class="status-card"> → paragrafo "**name** — descrizione"
    * <span class="badge ..."> → testo **bold**
    * <div class="page-break"> → \newpage Pandoc-friendly
- docx_renderer.py: deferisce tutto il preprocessing al nuovo modulo
  (più compatto, niente regex sparse).
- pyproject.toml + uv.lock: aggiunta dipendenza beautifulsoup4>=4.12.
- 8 nuovi test unit per il preprocessor (cover, tabelle, badge,
  acceptance, idempotenza, niente div residui, badge standalone).
  Adattati i test esistenti agli import dal nuovo modulo. 101 verde.

Smoke E2E via MCP: l'offerta TieMeasureFlow esce in DOCX leggibile
con tabelle Word native, heading colorati Tielogic e firme in tabella.
2026-04-26 11:26:52 +02:00

7.7 KiB

ArcaSuite

Monorepo per il sistema documentale personale+aziendale di Adriano e gli MCP server che lo supportano.

Cos'è

Due pezzi, stesso repo:

  1. Sistema Documentale — vault multi-wiki Markdown versionati su Gitea, pubblicati in sola lettura via Quartz, editabili da Obsidian + Claude Code. Vedi docs/sistema-documentale.md.
  2. MCP server — microservizi MCP riusabili dai wiki (e da altri client Claude). Ogni MCP vive in services/mcp-<nome>/ come membro del workspace uv.

MCP previsti

Servizio Stato Funzione
mcp-docugen Implementato, 101 test verde, deploy Docker via gateway Caddy (porta 8090), 8 tool MCP (CRUD template + document_generate + document_to_pdf + document_to_docx), template seed versionati, CSS Tielogic iniettato inline, render server-side PDF via Chromium/Playwright e DOCX via Pandoc con preprocessor che riscrive HTML/CSS Tielogic in Markdown nativo + reference tielogic-reference.docx Genera Markdown formale da template + LLM (OpenRouter) e converte in PDF o Word. Vedi docs/mcp-docugen-design.md + docs/mcp-docugen-implementation.md.
mcp-convert Da progettare Conversione Markdown → PDF / DOCX / HTML (pandoc/typst backend).
mcp-inbox Da progettare Ingest da Telegram (+ STT opzionale via Whisper) verso draft inbox consumati da Claude Code desktop.

Ogni MCP ha il suo pyproject.toml, src/mcp_<nome>/, tests/ e Dockerfile. Viene registrato in pyproject.toml root come workspace member.

Layout

ArcaSuite/
├── docs/                         # design + implementation plan per componente
│   ├── sistema-documentale.md
│   ├── mcp-docugen-design.md
│   └── mcp-docugen-implementation.md
├── services/                     # workspace members uv (uno per MCP)
│   └── mcp-<nome>/               # src/ tests/ pyproject.toml Dockerfile
├── scripts/                      # script operativi (provisioning, backup, smoke)
├── secrets/                      # chiavi, token (gitignored)
├── docker/                       # base.Dockerfile condiviso multi-stage
├── gateway/                      # Caddy reverse proxy (Caddyfile)
├── themes/                       # CSS condivisi (theme Tielogic unico per md-to-pdf, copre report e offerte)
├── docker-compose.yml            # stack completo (gateway + servizi MCP)
├── pyproject.toml                # workspace uv + ruff + pytest root
├── .env.example                  # config root stack
├── .mcp.json.example             # template registrazione client MCP
└── .gitignore

Convenzioni

  • Nomenclatura: mcp-<nome> per tutti gli MCP (pattern Cerbero). Package Python: mcp_<nome> (snake_case).
  • Package manager: uv workspace. Nessun requirements.txt. uv.lock committato.
  • Python: 3.11+, async-first, Pydantic v2 per ogni I/O.
  • Testing: pytest + pytest-asyncio, asyncio_mode = "auto", test sotto services/<svc>/tests/.
  • Lint: ruff (config root), line 100.
  • Config: ogni servizio ha un proprio .env.example. Root .env solo per cose cross-cutting (gateway port, dominio pubblico).
  • Secrets: mai committati. .mcp.json locale gitignored, solo .mcp.json.example tracciato.

Riferimento spec Python

Servizi non-MCP (es. eventuali inbox-service REST) seguono /home/adriano/Documenti/Struttura_Progetti/2026-04-01-python-project-spec-design.md. Gli MCP server seguono la struttura specifica descritta nei rispettivi design doc (FastMCP come root ASGI).

Setup

cp .env.example .env             # imposta OPENROUTER_API_KEY, DOCUGEN_API_KEY, GATEWAY_PORT
cp .mcp.json.example .mcp.json   # compila con URL + API key per registrazione client
uv sync --all-groups
docker compose up -d --build     # avvia gateway + mcp-docugen

Smoke test:

curl -H "Authorization: Bearer $DOCUGEN_API_KEY" http://localhost:8090/mcp-docugen/health

Endpoint utili (richiede Bearer per quelli MCP, pubblici per la documentazione):

  • GET /mcp-docugen/health — healthcheck (pubblico)
  • GET /mcp-docugen/docs — Swagger UI REST (pubblico)
  • GET /mcp-docugen/redoc — ReDoc REST (pubblico)
  • POST /mcp-docugen/mcp — endpoint MCP JSON-RPC (Bearer + sessione MCP)

Template mcp-docugen

I template ufficiali sono versionati in services/mcp-docugen/templates_seed/<nome>/template.md e copiati nel volume docugen-data al primo boot. La copia è idempotente: se un template esiste già nel volume (es. modificato a runtime via tool MCP template_update) non viene sovrascritto.

Template attualmente disponibili:

  • report-analisi — report tecnico stile DEVNOTES Tielogic (analisi sperimentali, criticità, fattibilità, roadmap, accettazione)
  • offerta — offerta economica stile docx Tielogic (cover FORNITORE/CLIENTE, modello commerciale setup+canone+sconto+proiezione, condizioni, accettazione)

Per propagare modifiche al template versionato su un'installazione esistente: usare il tool MCP template_update, oppure rimuovere il template dal volume e fare restart del container.

Conversione Markdown→PDF: tre strade, in ordine di comodità.

  1. Server-side via tool MCP (il mcp-docugen espone document_to_pdf e accetta output_format="pdf" su document_generate). Il render avviene dentro al container Docker tramite Chromium headless gestito da Playwright; il PDF viene restituito come stringa base64 nella risposta JSON-RPC. Opzione consigliata: il chiamante (Claude Code, script, altri MCP) riceve direttamente il PDF e non deve avere alcun tool installato.
  2. Client-side con md-to-pdf (Node) sull'host che ha generato il Markdown. Comando: md-to-pdf <file>.md.
  3. Script di bundling per documenti .md legacy che ancora referenziano stylesheet: come path host: scripts/bundle-css.py <file.md> [--in-place] rimuove la riga e inietta il CSS inline.

Il CSS Tielogic non viene mai referenziato come path esterno nel Markdown prodotto dal servizio: il Renderer lo legge da themes/tielogic.css (copiato nell'immagine Docker in /app/themes/) e lo inietta come blocco <style> inline subito dopo il frontmatter. Il file .md risultante è quindi autocontenuto e portabile — chi lo riceve può convertirlo in PDF stilizzato anche senza avere il CSS sull'host.

Per il formato Word (.docx) il servizio espone il tool MCP document_to_docx (oppure output_format ∈ {docx, all} su document_generate). Il pipeline è:

  1. Preprocessor (docx_preprocessor.py, basato su BeautifulSoup) riscrive l'HTML Tielogic-flavoured presente nel Markdown generato — <div class="cover">, <table class="financial">, <div class="acceptance">, <div class="status-card">, <span class="badge ..."> e <div class="page-break"> — in costrutti Markdown nativi (heading, tabelle pipe, paragrafi bold, \newpage). Senza questo passaggio Pandoc emetterebbe i <div> come testo grezzo nel DOCX.
  2. Pandoc converte il Markdown ripulito in DOCX usando themes/tielogic-reference.docx come template di stili: heading colors (blu Tielogic), font Inter e dimensioni di carattere replicano l'identità del PDF nei limiti di quello che il formato .docx permette.

La cover grafica con sfondo scuro, le card colorate, i bordi e gli sfondi delle status-card restano solo nel PDF (sono effetti CSS che non hanno equivalente nativo Word). Il reference .docx viene generato dallo script scripts/build-reference-docx.py partendo dal default Pandoc e riscrivendo word/styles.xml.

Remote

  • Gitea: ssh://git@git.tielogic.xyz:222/Adriano/ArcaSuite.git