# Skald Connectors Marketplace _Updated: 2026-07-16_ ## Cos'è Il **marketplace** è il catalogo dei connector testati per Skald. Ogni connector è un adattatore che permette a Skald di interfacciarsi con un servizio esterno (API, email, calendario, ricerca, messaggistica, ecc.). Due tipi di connector: - **`mcp_remote`** — un MCP server già hosted, accessibile via URL (es. Tavily). - **`mcp_local`** — script Python/Node da eseguire lato client (es. Gmail, Google Calendar). ## Struttura directory ``` connectors/ ├── connectors.json ← INDICE (radice di fiducia unica) ├── index.html ← Catalogo UI (legge connectors.json via fetch) ├── gmail/ ← Un connector per cartella │ ├── connector.json ← Configurazione tecnica │ ├── gmail_mcp_server.py ← Script MCP │ ├── gmail_oauth_setup.py ← Script setup OAuth │ ├── requirements.txt ← Dipendenze Python │ ├── icon_sm.svg ← Icona piccola (48×48) │ └── icon_lg.svg ← Icona grande (es. preview) └── tavily/ ├── connector.json ├── icon_sm.png └── icon_lg.png ``` ## Schema — connectors.json (root) Questo è l'**unico punto di fiducia**. Contiene `type`, `scope` e gli sha256 dei file di ogni connector. Non ha hash di sé stesso — in futuro potrà essere firmato digitalmente. ```json { "version": 1, "connectors": [ { "id": "gmail", "name": "Gmail", "type": "mcp_local", "scope": "user", "icon_small": "gmail/icon_sm.svg", "icon_large": "gmail/icon_lg.svg", "user_description": "Read, send, and manage Gmail emails via OAuth...", "requires": ["OAUTH", "PYTHON"], "tags": ["email", "mcp", "local", "google"], "folder": "gmail", "files": [ {"path": "gmail_mcp_server.py", "sha256": "a50d4da9621f7a4b092f...", "size": 46772}, {"path": "gmail_oauth_setup.py", "sha256": "e488acb289c43a3e6d54...", "size": 3627}, {"path": "icon_lg.svg", "sha256": "93c8d9c8dae96f0206e5...", "size": 254}, {"path": "icon_sm.svg", "sha256": "029d7f5d81de6cf2b17b...", "size": 251}, {"path": "requirements.txt", "sha256": "3f659cc5e5f0543f1326...", "size": 82} ] } ] } ``` ### Campi dell'indice | Campo | Obbligatorio | Descrizione | |-------|-------------|-------------| | `id` | ✅ | Identificatore unico (kebab-case) | | `name` | ✅ | Nome visualizzato | | `type` | ✅ | `mcp_remote` o `mcp_local` | | `scope` | ✅ | `global` o `user` | | `icon_small` | ✅ | Path relativo dalla root del marketplace | | `icon_large` | ✅ | Path relativo dalla root del marketplace | | `user_description` | ✅ | Descrizione breve per la UI | | `requires` | ✅ | Array di enum requisiti | | `tags` | ✅ | Array di tag per filtraggio | | `folder` | ✅ | Nome della cartella del connector | | `files` | ✅ | Array di file con sha256 (NO self-hash) | ## Schema — connector.json (per cartella) Configurazione tecnica per l'attivazione del connector. ```json { "id": "gmail", "name": "Gmail", "version": "1.0.0", "type": "mcp_local", "scope": "user", "launch_command": "python3 gmail_mcp_server.py", "transport": "stdio", "requires": ["OAUTH", "PYTHON"], "tags": ["email", "mcp", "local", "google"], "dependencies": [ "google-api-python-client>=2.150.0", "google-auth>=2.35.0", "google-auth-oauthlib>=1.2.0" ], "setup_instructions": [ "Install dependencies: pip install -r requirements.txt", "Create secrets/google_oauth_client.json with {\"client_id\": \"...\", \"client_secret\": \"...\"}", "Run: python3 gmail_oauth_setup.py (opens browser for OAuth)", "Set GMAIL_CREDS_PATH env var or place token at secrets/gmail_creds.json" ], "docs": [ { "lang": "en", "description": "Full description for human users...", "llm_short_description": "One-line description for LLM context..." } ], "auth": { "type": "oauth2", "provider": "google", "scopes": [ "https://www.googleapis.com/auth/gmail.modify", "https://www.googleapis.com/auth/gmail.labels" ] }, "mcp_config": { "command": "python3", "args": ["gmail_mcp_server.py"], "env": { "GMAIL_CREDS_PATH": "{secrets}/gmail_creds.json" } }, "homepage": "https://mail.google.com", "icon_small": "icon_sm.svg", "icon_large": "icon_lg.svg" } ``` ### Campi del connector.json | Campo | Obbligatorio | Descrizione | |-------|-------------|-------------| | `id` | ✅ | Identificatore unico (match con folder name) | | `name` | ✅ | Nome visualizzato | | `version` | ✅ | SemVer | | `type` | ✅ | `mcp_remote` o `mcp_local` | | `scope` | ✅ | `global` o `user` | | `requires` | ✅ | Array di enum requisiti | | `tags` | ✅ | Array di tag | | `auth` | ✅ | Oggetto configurazione autenticazione | | `docs` | ✅ | Array di documentazione multilingua | | `icon_small` | ✅ | Nome file icona nella cartella locale | | `icon_large` | ✅ | Nome file icona nella cartella locale | | `launch_command` | solo `mcp_local` | Comando per avviare il server MCP | | `transport` | solo `mcp_local` | `stdio` (default) | | `dependencies` | consigliato | Dipendenze Python/Node | | `setup_instructions` | consigliato | Passi per configurare il connector | | `mcp_config` | solo `mcp_local` | Configurazione per l'MCP client | | `homepage` | opzionale | URL del servizio | ## Enum riservati ### type (tipo di connector) | Valore | Descrizione | Esempi | |--------|-------------|--------| | `mcp_remote` | Server MCP hosted, accessibile via URL | Tavily, Weather | | `mcp_local` | Script da eseguire localmente | Gmail, Google Calendar, WhatsApp | | `script` | Script standalone (non MCP) | *(futuro)* | ### scope (ambito di configurazione) | Valore | Descrizione | Esempi | |--------|-------------|--------| | `global` | Una singola istanza/config per tutto il sistema | Tavily, Weather, Google Trends | | `user` | Ogni utente ha la propria istanza/autenticazione | Gmail, WhatsApp, Google Calendar | ### requires (prerequisiti) | Valore | Descrizione | |--------|-------------| | `API_KEY` | Richiede una chiave API da configurare | | `OAUTH` | Richiede autenticazione OAuth (Google, ecc.) | | `DOCKER` | Richiede Docker Engine | | `NODE` | Richiede Node.js runtime | | `PYTHON` | Richiede Python 3 | | `SECRETS_DIR` | Richiede file di credenziali in `secrets/` | ## Campo auth Struttura che descrive come il connector gestisce l'autenticazione: ```json // API key in query string {"type": "api_key", "delivery": "query", "param": "tavilyApiKey"} // API key in header {"type": "api_key", "delivery": "header", "param": "X-API-Key"} // OAuth2 {"type": "oauth2", "provider": "google", "scopes": ["...", "..."]} // Nessuna autenticazione {"type": "none"} ``` ## Convenzioni icone - **Formato**: SVG per icone vettoriali (meglio per retina/zoom), PNG per raster - **Nome**: `icon_sm.{svg|png}` (small, ~48×48px), `icon_lg.{svg|png}` (large, ~96×96px) - **Path**: relativo alla cartella del connector - **Nell'indice** la path è `{folder}/{filename}` (es. `gmail/icon_sm.svg`) ## Integrità file (sha256) - Gli hash sha256 sono **solo in `connectors.json`** (l'indice) - `connector.json` **non contiene hash di sé stesso** — è il file manifesto - L'indice è l'unica radice di fiducia; in futuro si può firmare digitalmente solo l'indice - Sui file locali, per calcolare/aggiornare gli hash: ```bash python3 -c "import hashlib; print(hashlib.sha256(open('file.py','rb').read()).hexdigest())" ``` ## Workflow locale 1. Lavora su file nella cartella `connectors/` 2. Modifica `connectors.json`, `connector.json`, script, icone 3. **Prima del deploy** aggiorna gli sha256 in `connectors.json`: ```bash python3 scripts/update_hashes.py ``` 4. Fai l'upload sul server con rsync: ```bash rsync -avz --delete connectors/ dguiducci@skald-server:/var/www/connectors.skaldagent.net/ ``` 5. Verifica su `https://connectors.skaldagent.net/` ## Deploy su server remoto Il server remoto è: - **Host**: skald-home-server (192.168.1.100 / 145.40.169.107) - **User**: dguiducci - **Path**: `/var/www/connectors.skaldagent.net/` - **Proprietario**: `caddy:caddy` - **Sudo**: richiesto per scrivere in `/var/www/` Comando di deploy (da eseguire con sudo o con rsync): ```bash # Sync se il server permette rsync via SSH rsync -avz --delete ./connectors/ dguiducci@skald-server:/var/www/connectors.skaldagent.net/ ``` Dopo il deploy, verificare i permessi: ```bash sudo chown -R caddy:caddy /var/www/connectors.skaldagent.net/ sudo find /var/www/connectors.skaldagent.net/ -type f -exec chmod 644 {} \; ``` ## Connector attuali | ID | Nome | Tipo | Scope | |----|------|------|-------| | `tavily` | Tavily | `mcp_remote` | `global` | | `gmail` | Gmail | `mcp_local` | `user` |