From 7b169fb8dbbc197b54cdbb87bfd44fefd377f1ad Mon Sep 17 00:00:00 2001 From: AdrianoDev Date: Tue, 21 Apr 2026 12:06:38 +0200 Subject: [PATCH] chore: organize repo as uv workspace multi-MCP monorepo Layout stile CerberoSuite/Cerbero: - services/ per MCP workspace members (futuri: mcp-docugen, mcp-convert, mcp-inbox) - docs/ flat con design+implementation per componente - scripts/, secrets/ placeholder - pyproject.toml root (uv workspace vuoto + ruff + pytest) - .gitignore, .env.example, .mcp.json.example, README.md Rinominate le doc: Docs//2026-04-21-*.md -> docs/-*.md. Co-Authored-By: Claude Opus 4.7 (1M context) --- .env.example | 10 +++ .gitignore | 46 +++++++++++++ .mcp.json.example | 9 +++ README.md | 65 +++++++++++++++++++ .../mcp-docugen-design.md | 0 .../mcp-docugen-implementation.md | 0 .../sistema-documentale.md | 0 pyproject.toml | 39 +++++++++++ scripts/.gitkeep | 0 secrets/.gitkeep | 0 services/.gitkeep | 0 11 files changed, 169 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 .mcp.json.example create mode 100644 README.md rename Docs/docugen-mcp/2026-04-21-design.md => docs/mcp-docugen-design.md (100%) rename Docs/docugen-mcp/2026-04-21-implementation.md => docs/mcp-docugen-implementation.md (100%) rename Docs/sistema-documentale/2026-04-21-design.md => docs/sistema-documentale.md (100%) create mode 100644 pyproject.toml create mode 100644 scripts/.gitkeep create mode 100644 secrets/.gitkeep create mode 100644 services/.gitkeep diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..2365e80 --- /dev/null +++ b/.env.example @@ -0,0 +1,10 @@ +# Root stack config (gateway/compose). Ogni servizio aggiunge il proprio .env.example. + +# Porta host del gateway (reverse proxy Caddy/nginx) — da definire +GATEWAY_PORT=8080 + +# Token OpenRouter condiviso fra MCP che usano LLM +# OPENROUTER_API_KEY= + +# Dominio pubblico (usato da servizi che generano URL assoluti) +# PUBLIC_BASE_DOMAIN=arca.tielogic.xyz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..02a7d9b --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# Python +__pycache__/ +*.pyc +*.pyo +*.egg-info/ +build/ +dist/ +.pytest_cache/ +.coverage +htmlcov/ +.venv/ +.venv-*/ +*.db +*.db-journal + +# Secrets +secrets/* +!secrets/.gitkeep + +# Data +data/ + +# Per-service artifacts +services/*/build/ +services/*/dist/ +services/*/.pytest_cache/ +services/*/*.egg-info/ +services/*/.venv/ + +# IDE +.vscode/ +.idea/ +*.swp + +# OS +.DS_Store +Thumbs.db + +# Environment — solo .example tracciati +.env +*.env +!*.env.example +!.env.example + +# MCP config con token — solo .example tracciato +.mcp.json diff --git a/.mcp.json.example b/.mcp.json.example new file mode 100644 index 0000000..2fc41b2 --- /dev/null +++ b/.mcp.json.example @@ -0,0 +1,9 @@ +{ + "mcpServers": { + "docugen": { + "type": "http", + "url": "https://docugen./mcp", + "headers": { "Authorization": "Bearer " } + } + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..1af85e8 --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +# 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-/` come membro del workspace `uv`. + +## MCP previsti + +| Servizio | Stato | Funzione | +|---|---|---| +| `mcp-docugen` | Design pronto, implementazione da iniziare | Genera Markdown formale da template + LLM (OpenRouter). 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_/`, `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-/ # src/ tests/ pyproject.toml Dockerfile +├── scripts/ # script operativi (provisioning, backup, smoke) +├── secrets/ # chiavi, token (gitignored) +├── docker-compose.yml # stack completo (TODO: arriverà con primo MCP) +├── pyproject.toml # workspace uv + ruff + pytest root +├── .env.example # config root stack +├── .mcp.json.example # template registrazione client MCP +└── .gitignore +``` + +## Convenzioni + +- **Nomenclatura**: `mcp-` per tutti gli MCP (pattern Cerbero). Package Python: `mcp_` (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//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 (quando ci sarà il primo MCP implementato) + +```bash +cp .env.example .env +cp .mcp.json.example .mcp.json # compila con URL + API key +uv sync --all-groups +``` + +## Remote + +- Gitea: `ssh://git@git.tielogic.xyz:222/Adriano/ArcaSuite.git` diff --git a/Docs/docugen-mcp/2026-04-21-design.md b/docs/mcp-docugen-design.md similarity index 100% rename from Docs/docugen-mcp/2026-04-21-design.md rename to docs/mcp-docugen-design.md diff --git a/Docs/docugen-mcp/2026-04-21-implementation.md b/docs/mcp-docugen-implementation.md similarity index 100% rename from Docs/docugen-mcp/2026-04-21-implementation.md rename to docs/mcp-docugen-implementation.md diff --git a/Docs/sistema-documentale/2026-04-21-design.md b/docs/sistema-documentale.md similarity index 100% rename from Docs/sistema-documentale/2026-04-21-design.md rename to docs/sistema-documentale.md diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..ec3ae50 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,39 @@ +[tool.uv.workspace] +members = [] + +[tool.ruff] +line-length = 100 +target-version = "py311" + +[tool.ruff.lint] +select = ["E", "F", "I", "W", "UP", "B", "SIM"] +ignore = ["E501"] + +[tool.ruff.lint.flake8-bugbear] +extend-immutable-calls = [ + "fastapi.Depends", + "fastapi.Query", + "fastapi.Body", + "fastapi.Header", + "fastapi.Path", + "fastapi.Cookie", + "fastapi.Form", + "fastapi.File", + "fastapi.Security", +] + +[tool.ruff.lint.per-file-ignores] +"**/test_*.py" = ["B008"] + +[tool.pytest.ini_options] +asyncio_mode = "auto" +testpaths = ["services"] +addopts = "--import-mode=importlib" + +[dependency-groups] +dev = [ + "pytest>=8.0", + "pytest-asyncio>=0.24", + "pytest-httpx>=0.30", + "ruff>=0.7", +] diff --git a/scripts/.gitkeep b/scripts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/secrets/.gitkeep b/secrets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/services/.gitkeep b/services/.gitkeep new file mode 100644 index 0000000..e69de29