Aggiunge la possibilità di convertire un documento Markdown in PDF
direttamente lato server, senza richiedere al chiamante di avere
md-to-pdf, pandoc o altri tool sull'host. Il PDF è restituito come
stringa base64 nella risposta JSON-RPC, pronto a essere salvato,
allegato o spedito al cliente.
- pdf_renderer.py: nuovo modulo che parsea il frontmatter YAML del
Markdown (incluso il blocco pdf_options stile Puppeteer/md-to-pdf),
rende il body in HTML via markdown-it-py (supporta tabelle e
HTML inline) e produce il PDF tramite Chromium headless gestito
da Playwright. Le pdf_options camelCase (printBackground,
displayHeaderFooter, headerTemplate, ...) vengono tradotte negli
argomenti snake_case di page.pdf().
- mcp_tools.py: nuovo tool `document_to_pdf(markdown)` che ritorna
`{pdf_b64, size_bytes}`; `document_generate` esteso con il
parametro `output_format ∈ {md, pdf, both}` per emettere il PDF
contestualmente alla generazione del Markdown.
- pyproject.toml + uv.lock: aggiunte le dipendenze playwright>=1.48
e markdown-it-py[plugins]>=3.0.
- mcp-docugen.Dockerfile: nuova fase di runtime che installa le
librerie native richieste da Chromium (libnss3, libgbm1, ecc.) e
scarica il binario Chromium di Playwright in /opt/ms-playwright.
- 7 nuovi test unit (83 totali) che coprono lo split del frontmatter,
il rendering Markdown→HTML con tabelle, la traduzione delle
pdf_options camelCase→snake_case e l'errore su YAML invalido. Il
test E2E che richiede Chromium è marcato skip in unit; lo smoke
via MCP conferma generazione PDF da 134 KB / 4 pagine.
README aggiornato con le tre strade di conversione (server-side,
client-side, bundling) e la stima del nuovo costo immagine.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.4 KiB
ArcaSuite
Monorepo per il sistema documentale personale+aziendale di Adriano e gli MCP server che lo supportano.
Cos'è
Due pezzi, stesso repo:
- 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. - MCP server — microservizi MCP riusabili dai wiki (e da altri client Claude). Ogni MCP vive in
services/mcp-<nome>/come membro del workspaceuv.
MCP previsti
| Servizio | Stato | Funzione |
|---|---|---|
mcp-docugen |
Implementato, 83 test verde, deploy Docker via gateway Caddy (porta 8090), 7 tool MCP esposti (CRUD template + document_generate + document_to_pdf), template seed versionati, CSS Tielogic iniettato inline, render PDF server-side via Chromium/Playwright |
Genera Markdown formale da template + LLM (OpenRouter) e converte in PDF. 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:
uvworkspace. Nessunrequirements.txt.uv.lockcommittato. - Python: 3.11+, async-first, Pydantic v2 per ogni I/O.
- Testing:
pytest+pytest-asyncio,asyncio_mode = "auto", test sottoservices/<svc>/tests/. - Lint:
ruff(config root), line 100. - Config: ogni servizio ha un proprio
.env.example. Root.envsolo per cose cross-cutting (gateway port, dominio pubblico). - Secrets: mai committati.
.mcp.jsonlocale gitignored, solo.mcp.json.exampletracciato.
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à.
- Server-side via tool MCP (il
mcp-docugenesponedocument_to_pdfe accettaoutput_format="pdf"sudocument_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. - Client-side con
md-to-pdf(Node) sull'host che ha generato il Markdown. Comando:md-to-pdf <file>.md. - Script di bundling per documenti
.mdlegacy che ancora referenzianostylesheet: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.
Remote
- Gitea:
ssh://git@git.tielogic.xyz:222/Adriano/ArcaSuite.git