c783fff040
Aggiunge la generazione di documenti Word coerenti con l'identità
visiva Tielogic, in parallelo al render PDF già esistente. Il flusso
completo è ora `bullet input → Markdown formattato → PDF e/o DOCX`
in una singola chiamata MCP.
- docx_renderer.py: subprocess Pandoc che legge il Markdown da stdin,
emette il binario .docx su stdout. Strippa il YAML frontmatter e i
blocchi `<style>` (presenti per il PDF, irrilevanti in DOCX) prima
della conversione.
- mcp_tools.py: nuovo tool `document_to_docx(markdown)` che ritorna
`{docx_b64, size_bytes}`; `document_generate` esteso con
`output_format ∈ {md, pdf, docx, all}`. La firma di
`build_mcp_server` accetta ora `docx_reference_path` opzionale.
- config.py: `Settings.docx_reference_path` (default
/app/themes/tielogic-reference.docx).
- main.py: passa la nuova setting a `build_mcp_server`.
- mcp-docugen.Dockerfile: installazione di pandoc accanto alle libs
Chromium.
- themes/tielogic-reference.docx: reference Word (10 KB) con stili
Tielogic — heading colors blu/dark, font Inter, dimensioni allineate
al CSS web. Generato da `scripts/build-reference-docx.py` che parte
dal reference.docx di default di Pandoc e riscrive `word/styles.xml`
con regex sui blocchi `<w:style>`. Pandoc lo applica in automatico
agli output DOCX prodotti dal servizio.
- 9 nuovi test unit per docx_renderer (strip frontmatter/style,
preprocess combinato, error empty input, smoke skippato in
ambienti senza Pandoc): 92 test totali.
Smoke E2E via MCP: una sola chiamata `document_generate` con
`output_format=all` produce MD (14 KB), PDF (137 KB, 4 pagine A4) e
DOCX (12.7 KB) coerenti tra loro.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
104 lines
7.2 KiB
Markdown
104 lines
7.2 KiB
Markdown
# 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`](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, 92 test verde, deploy Docker via gateway Caddy (porta 8090), **8 tool MCP** esposti (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 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-design.md) + [`docs/mcp-docugen-implementation.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`](/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
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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`). La conversione passa per Pandoc invocato come subprocess, con `themes/tielogic-reference.docx` come reference: heading colors (blu Tielogic), font Inter e dimensioni di carattere replicano l'identità del PDF nei limiti di quello che il formato `.docx` permette di stilizzare. La cover grafica con sfondo scuro, le card colorate, le badge e i bordi del CSS rimangono 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`
|