Nuovo sistema: index.json + fragment.json + compile.py (SHA-256 automatici)

This commit is contained in:
2026-07-22 22:52:01 +01:00
parent 5f254d9a96
commit ccab72c586
20 changed files with 1121 additions and 240 deletions
+110 -29
View File
@@ -15,7 +15,13 @@ _Updated: 2026-07-22_
Il branch **`main`** è il branch di **release**. Solo codice pronto per produzione finisce qui. Il branch **`main`** è il branch di **release**. Solo codice pronto per produzione finisce qui.
Sviluppo e versioni alfa-staranno su branch separati in futuro. Sviluppo e versioni alfa-staranno su branch separati in futuro.
Per deployare l'ultima versione del marketplace sul server: Deploy rapido con MCP SSH:
```bash
mcp__ssh__exec alias=skald-home-server command="/home/dguiducci/marketplace_deploy.sh"
```
Oppure via SSH classico:
```bash ```bash
ssh dguiducci@skald-home-server /home/dguiducci/marketplace_deploy.sh ssh dguiducci@skald-home-server /home/dguiducci/marketplace_deploy.sh
@@ -28,6 +34,11 @@ Lo script sul server fa:
La directory `/var/www/connectors.skaldagent.net/` è di proprietà di `dguiducci`, La directory `/var/www/connectors.skaldagent.net/` è di proprietà di `dguiducci`,
quindi non serve sudo per la copia. quindi non serve sudo per la copia.
**Prima del deploy**, ricordarsi di rigenerare l'indice:
```bash
python3 scripts/compile.py
```
## Cos'è ## 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.). 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.).
@@ -56,18 +67,22 @@ Stato attuale (2026-07-21): tutti i 13 connector del marketplace hanno `title` n
``` ```
connectors/ connectors/
├── connectors.json ← INDICE (radice di fiducia unica) ├── index.json ← lista ordinata degli id dei connector (input per compile.py)
├── connectors.json ← INDICE COMPILATO (generato da compile.py, non editare)
├── compile.py ← genera connectors.json
├── index.html ← Catalogo UI (legge connectors.json via fetch) ├── index.html ← Catalogo UI (legge connectors.json via fetch)
├── oauth/ ├── oauth/
│ └── show.html ← OAuth callback receiver (client-side, no backend) │ └── show.html ← OAuth callback receiver (client-side, no backend)
├── gmail/ ← Un connector per cartella ├── gmail/ ← Un connector per cartella
│ ├── fragment.json ← Frammento dell'indice (id, name, type, ..., SENZA files[])
│ ├── connector.json ← Configurazione tecnica │ ├── connector.json ← Configurazione tecnica
│ ├── gmail_mcp_server.py ← Script MCP │ ├── gmail_mcp_server.py ← Script MCP
│ ├── gmail_oauth_setup.py ← Script setup OAuth │ ├── gmail_oauth_setup.py ← Script setup OAuth
│ ├── requirements.txt ← Dipendenze Python │ ├── requirements.txt ← Dipendenze Python
│ ├── icon_sm.svg ← Icona piccola (48×48) │ ├── icon_sm.svg ← Icona piccola (48×48)
│ └── icon_lg.svg ← Icona grande (es. preview) │ └── icon_lg.svg ← Icona grande (es. 96×96)
├── email/ ├── email/
│ ├── fragment.json
│ ├── connector.json │ ├── connector.json
│ ├── email_mcp_server.py │ ├── email_mcp_server.py
│ ├── verify.py │ ├── verify.py
@@ -75,17 +90,21 @@ connectors/
│ ├── icon_sm.svg │ ├── icon_sm.svg
│ └── icon_lg.svg │ └── icon_lg.svg
├── ssh/ ├── ssh/
│ ├── fragment.json
│ ├── connector.json │ ├── connector.json
│ ├── ssh_mcp_server.py │ ├── ssh_mcp_server.py
│ ├── requirements.txt │ ├── requirements.txt
│ ├── icon_sm.svg │ ├── icon_sm.svg
│ └── icon_lg.svg │ └── icon_lg.svg
└── tavily/ └── tavily/
├── fragment.json
├── connector.json ├── connector.json
├── verify.py ├── verify.py
├── icon_sm.png ├── icon_sm.png
└── icon_lg.png └── icon_lg.png
``` ```
└── icon_lg.png
```
## Schema — connectors.json (root) ## Schema — connectors.json (root)
@@ -436,28 +455,103 @@ il test scrivendo `verify`.
## Integrità file (sha256) ## Integrità file (sha256)
- Gli hash sha256 sono **solo in `connectors.json`** (l'indice) - Gli SHA-256 sono generati **automaticamente** da `scripts/compile.py` a partire
- `connector.json` **non contiene hash di sé stesso** — è il file manifesto dai file fisici presenti in ogni cartella — mai manuali, mai stale.
- L'indice è l'unica radice di fiducia; in futuro si può firmare digitalmente solo l'indice - L'unico file firmato (in futuro) sarà `connectors.json` (l'indice).
- Sui file locali, per calcolare/aggiornare gli hash: - `fragment.json` e `index.json` non hanno hash — sono solo input di compilazione.
```bash
python3 -c "import hashlib; print(hashlib.sha256(open('file.py','rb').read()).hexdigest())" ## Struttura directory
```
```
connectors/
├── index.json ← lista ordinata degli id dei connector (input per compile.py)
├── connectors.json ← INDICE COMPILATO (generato da compile.py, non editare)
├── compile.py ← genera connectors.json (lanciato da scripts/compile.py)
├── index.html ← Catalogo UI (legge connectors.json via fetch)
├── oauth/
│ └── show.html ← OAuth callback receiver
├── gmail/ ← Un connector per cartella
│ ├── fragment.json ← Frammento dell'indice (id, name, type, ..., SENZA files[])
│ ├── connector.json ← Configurazione tecnica (mcp_config, auth.deliver, ...)
│ ├── 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. 96×96)
├── email/
│ ├── fragment.json
│ ├── connector.json
│ ├── email_mcp_server.py
│ ├── verify.py
│ ├── requirements.txt
│ ├── icon_sm.svg
│ └── icon_lg.svg
└── ...
```
## Workflow locale ## Workflow locale
1. Lavora su file nella cartella `connectors/` 1. **Aggiungere un nuovo connector**:
2. Modifica `connectors.json`, `connector.json`, script, icone - Crea cartella `connectors/<id>/`
3. **Prima del deploy** aggiorna gli sha256 in `connectors.json`: - Crea `fragment.json` (id, name, type, scope, icone, auth, tools, ...)
- Crea `connector.json` (config tecnica: mcp_config, launch_command, ...)
- Aggiungi script MCP, icone, verify.py, requirements.txt
- Aggiungi l'id a `connectors/index.json`
- Lancia `python3 scripts/compile.py`
2. **Modificare un connector esistente**:
- Modifica i file nella cartella del connector
- **Non toccare** `connectors.json` — viene rigenerato
- Lancia `python3 scripts/compile.py`
3. **Prima del deploy**:
```bash ```bash
python3 scripts/update_hashes.py python3 scripts/compile.py # rigenera connectors.json con SHA-256 fresh
python3 scripts/compile.py --verify # (opzionale) verifica che sia aggiornato
``` ```
4. Fai l'upload sul server con rsync:
4. **Deploy sul server**:
```bash ```bash
rsync -avz --delete connectors/ dguiducci@skald-server:/var/www/connectors.skaldagent.net/ ssh dguiducci@skald-home-server /home/dguiducci/marketplace_deploy.sh
``` ```
oppure con MCP SSH:
```bash
# via mcp__ssh__exec alias "skald-home-server"
/home/dguiducci/marketplace_deploy.sh
```
(Il deploy script fa `git pull` + `cp -r connectors/* /var/www/connectors.skaldagent.net/`)
5. Verifica su `https://connectors.skaldagent.net/` 5. Verifica su `https://connectors.skaldagent.net/`
## Fragment.json
Vedi [connector.manifest_guide.md](docs/connector.manifest_guide.md) per i dettagli.
`fragment.json` contiene tutti i campi dell'entry di `connectors.json` **tranne** `files[]`.
Questi sono i campi obbligatori:
| Campo | Obbligatorio | Descrizione |
|-------|-------------|-------------|
| `id` | ✅ | Identificatore unico (match con folder name) |
| `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 (match con `id`) |
| `version` | ✅ | Intero per-connector, +1 a ogni modifica dei file |
| `version_string` | ✅ | Semver (solo display) |
| `version_release_date` | ✅ | Data ISO 8601 (solo display) |
| `tools` | ✅ | Array di `{name, display_name}` per friendly names UI |
| `auth` | opzionale | Configurazione autenticazione (se diversa da `"none"`) |
Nota: l'array `files[]` (con SHA-256 e size) viene aggiunto **automaticamente**
da `compile.py` scansionando i file presenti nella cartella — non va mai scritto
a mano.
## Deploy su server remoto ## Deploy su server remoto
Il server remoto è: Il server remoto è:
@@ -468,19 +562,6 @@ Il server remoto è:
- **Proprietario**: `caddy:caddy` - **Proprietario**: `caddy:caddy`
- **Sudo**: richiesto per scrivere in `/var/www/` - **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 ## Connector attuali
| ID | Nome | Tipo | Scope | Auth | Verify | | ID | Nome | Tipo | Scope | Auth | Verify |
+234 -211
View File
@@ -100,24 +100,24 @@
"size": 38437 "size": 38437
}, },
{ {
"path": "verify.py", "path": "icon_lg.svg",
"sha256": "d994ae435d8a5a3d9cdc85c8f73805a877c1a8818637b2912f6c31c693fdded4", "sha256": "b5daeeaaebba5b6d5ea31fd51bc63887225dee8aa1a42b571e49263f930895a9",
"size": 3429 "size": 479
}, },
{ {
"path": "icon_sm.svg", "path": "icon_sm.svg",
"sha256": "477ab05d24b40aaf4209c37e30558878fd0833dfbcfa8648b0ab9b903bd171d3", "sha256": "477ab05d24b40aaf4209c37e30558878fd0833dfbcfa8648b0ab9b903bd171d3",
"size": 473 "size": 473
}, },
{
"path": "icon_lg.svg",
"sha256": "b5daeeaaebba5b6d5ea31fd51bc63887225dee8aa1a42b571e49263f930895a9",
"size": 479
},
{ {
"path": "requirements.txt", "path": "requirements.txt",
"sha256": "41a908f999095b052865efdcf793cfe7b032a3609c0cdd9f7711b2af5b3b7827", "sha256": "41a908f999095b052865efdcf793cfe7b032a3609c0cdd9f7711b2af5b3b7827",
"size": 54 "size": 54
},
{
"path": "verify.py",
"sha256": "d994ae435d8a5a3d9cdc85c8f73805a877c1a8818637b2912f6c31c693fdded4",
"size": 3429
} }
] ]
}, },
@@ -164,14 +164,9 @@
"size": 20124 "size": 20124
}, },
{ {
"path": "verify.py", "path": "icon_lg.png",
"sha256": "3f1da92f15e7f6898545bb170f7123610025088c7403edd2021ce8b3499713e2", "sha256": "723b1ec7c72309f75d2ea0ea38ff526502f6fd1cf4c849090bfb6b3a4e69efd3",
"size": 3304 "size": 3997
},
{
"path": "requirements.txt",
"sha256": "3f659cc5e5f0543f132699b06ccf9016ffe9afb40f9df4d110e0445b8d20f63e",
"size": 82
}, },
{ {
"path": "icon_sm.png", "path": "icon_sm.png",
@@ -179,9 +174,14 @@
"size": 1860 "size": 1860
}, },
{ {
"path": "icon_lg.png", "path": "requirements.txt",
"sha256": "723b1ec7c72309f75d2ea0ea38ff526502f6fd1cf4c849090bfb6b3a4e69efd3", "sha256": "3f659cc5e5f0543f132699b06ccf9016ffe9afb40f9df4d110e0445b8d20f63e",
"size": 3997 "size": 82
},
{
"path": "verify.py",
"sha256": "3f1da92f15e7f6898545bb170f7123610025088c7403edd2021ce8b3499713e2",
"size": 3304
} }
] ]
}, },
@@ -259,28 +259,6 @@
"version": 4, "version": 4,
"version_string": "1.0.3", "version_string": "1.0.3",
"version_release_date": "2026-07-21", "version_release_date": "2026-07-21",
"files": [
{
"path": "connector.json",
"sha256": "bce7389bfc62c9a1f633df09cdcd4630c592efc11ef064cbbf5a2a48a1b2606e",
"size": 1619
},
{
"path": "verify.py",
"sha256": "8e77da3ca3eca8f733296da134aaa964e5db8d01d4bfb89aa5832296e9dc45a6",
"size": 2125
},
{
"path": "icon_sm.png",
"sha256": "dd0a17d75ce36187f34c1fbfa459aee1665d94b2b8e1e300c2559631ffdcd1bd",
"size": 1728
},
{
"path": "icon_lg.png",
"sha256": "a1b698035af2cb146dccd57f992155359d55a48bc85802e2a02e8148dcec1558",
"size": 3730
}
],
"tools": [ "tools": [
{ {
"name": "web_search_exa", "name": "web_search_exa",
@@ -290,6 +268,28 @@
"name": "web_fetch_exa", "name": "web_fetch_exa",
"display_name": "Web Fetch" "display_name": "Web Fetch"
} }
],
"files": [
{
"path": "connector.json",
"sha256": "bce7389bfc62c9a1f633df09cdcd4630c592efc11ef064cbbf5a2a48a1b2606e",
"size": 1619
},
{
"path": "icon_lg.png",
"sha256": "a1b698035af2cb146dccd57f992155359d55a48bc85802e2a02e8148dcec1558",
"size": 3730
},
{
"path": "icon_sm.png",
"sha256": "dd0a17d75ce36187f34c1fbfa459aee1665d94b2b8e1e300c2559631ffdcd1bd",
"size": 1728
},
{
"path": "verify.py",
"sha256": "8e77da3ca3eca8f733296da134aaa964e5db8d01d4bfb89aa5832296e9dc45a6",
"size": 2125
}
] ]
}, },
{ {
@@ -319,23 +319,6 @@
"version": 4, "version": 4,
"version_string": "1.0.3", "version_string": "1.0.3",
"version_release_date": "2026-07-21", "version_release_date": "2026-07-21",
"files": [
{
"path": "connector.json",
"sha256": "6cab1a43e32741eb4f31638841e65b68fb937d2c6313fd18ace38e722bc2eb23",
"size": 5008
},
{
"path": "icon_sm.png",
"sha256": "3a4be30d4c16ce93a1d132e063dfdffb8bd27b6c97715c9f3b12414439aaeb01",
"size": 6858
},
{
"path": "icon_lg.png",
"sha256": "3a4be30d4c16ce93a1d132e063dfdffb8bd27b6c97715c9f3b12414439aaeb01",
"size": 6858
}
],
"tools": [ "tools": [
{ {
"name": "firecrawl_scrape", "name": "firecrawl_scrape",
@@ -441,6 +424,23 @@
"name": "firecrawl_research_search_github", "name": "firecrawl_research_search_github",
"display_name": "Search GitHub" "display_name": "Search GitHub"
} }
],
"files": [
{
"path": "connector.json",
"sha256": "6cab1a43e32741eb4f31638841e65b68fb937d2c6313fd18ace38e722bc2eb23",
"size": 5008
},
{
"path": "icon_lg.png",
"sha256": "3a4be30d4c16ce93a1d132e063dfdffb8bd27b6c97715c9f3b12414439aaeb01",
"size": 6858
},
{
"path": "icon_sm.png",
"sha256": "3a4be30d4c16ce93a1d132e063dfdffb8bd27b6c97715c9f3b12414439aaeb01",
"size": 6858
}
] ]
}, },
{ {
@@ -470,23 +470,6 @@
"version": 4, "version": 4,
"version_string": "1.0.3", "version_string": "1.0.3",
"version_release_date": "2026-07-21", "version_release_date": "2026-07-21",
"files": [
{
"path": "connector.json",
"sha256": "8087d8ed8af7c6b628c95ff74f5126023a1ed1c99c2b3fc5c0599f665ffaa6f2",
"size": 1862
},
{
"path": "icon_sm.svg",
"sha256": "fa32e634744d8cba369f6d8ba45746166124f7d3507cefd9a1f96180c787e1a8",
"size": 380
},
{
"path": "icon_lg.svg",
"sha256": "3e5496d949062678ae44cd74430b29232bbfe28a7600038deb3159c4b26adee1",
"size": 382
}
],
"tools": [ "tools": [
{ {
"name": "fetch_html", "name": "fetch_html",
@@ -512,6 +495,23 @@
"name": "fetch_youtube_transcript", "name": "fetch_youtube_transcript",
"display_name": "Get YouTube Transcript" "display_name": "Get YouTube Transcript"
} }
],
"files": [
{
"path": "connector.json",
"sha256": "8087d8ed8af7c6b628c95ff74f5126023a1ed1c99c2b3fc5c0599f665ffaa6f2",
"size": 1862
},
{
"path": "icon_lg.svg",
"sha256": "3e5496d949062678ae44cd74430b29232bbfe28a7600038deb3159c4b26adee1",
"size": 382
},
{
"path": "icon_sm.svg",
"sha256": "fa32e634744d8cba369f6d8ba45746166124f7d3507cefd9a1f96180c787e1a8",
"size": 380
}
] ]
}, },
{ {
@@ -536,6 +536,12 @@
"version": 4, "version": 4,
"version_string": "1.0.3", "version_string": "1.0.3",
"version_release_date": "2026-07-21", "version_release_date": "2026-07-21",
"tools": [
{
"name": "serpapi_search_flights",
"display_name": "Search Flights"
}
],
"files": [ "files": [
{ {
"path": "connector.json", "path": "connector.json",
@@ -543,9 +549,9 @@
"size": 1498 "size": 1498
}, },
{ {
"path": "verify.py", "path": "icon_lg.svg",
"sha256": "eca6298a01cc1c8ce2aece9170a0b228efda7cb8a5c469d1ca3b62932fb7ea51", "sha256": "5a2ffa7f2502fd27dc0027395db2c863bb544c8de1eef8131a5228d87402c8e6",
"size": 2003 "size": 574
}, },
{ {
"path": "icon_sm.svg", "path": "icon_sm.svg",
@@ -553,15 +559,9 @@
"size": 570 "size": 570
}, },
{ {
"path": "icon_lg.svg", "path": "verify.py",
"sha256": "5a2ffa7f2502fd27dc0027395db2c863bb544c8de1eef8131a5228d87402c8e6", "sha256": "eca6298a01cc1c8ce2aece9170a0b228efda7cb8a5c469d1ca3b62932fb7ea51",
"size": 574 "size": 2003
}
],
"tools": [
{
"name": "serpapi_search_flights",
"display_name": "Search Flights"
} }
] ]
}, },
@@ -598,14 +598,9 @@
"size": 3986 "size": 3986
}, },
{ {
"path": "ssh_mcp_server.py", "path": "icon_lg.svg",
"sha256": "68509094a35578ffaaf357e13b55e1bfcf397f16a3b993719c4c3b97ab2dc798", "sha256": "84dc85685be0fff4cae1c2554b5fe958dd94455e182117c7470838b3cfca6ba1",
"size": 50193 "size": 432
},
{
"path": "requirements.txt",
"sha256": "fa65d44e3d3219c79e5272ef7123352b5d71a35871ede721e66422c897b94e0e",
"size": 14
}, },
{ {
"path": "icon_sm.svg", "path": "icon_sm.svg",
@@ -613,9 +608,14 @@
"size": 254 "size": 254
}, },
{ {
"path": "icon_lg.svg", "path": "requirements.txt",
"sha256": "84dc85685be0fff4cae1c2554b5fe958dd94455e182117c7470838b3cfca6ba1", "sha256": "fa65d44e3d3219c79e5272ef7123352b5d71a35871ede721e66422c897b94e0e",
"size": 432 "size": 14
},
{
"path": "ssh_mcp_server.py",
"sha256": "68509094a35578ffaaf357e13b55e1bfcf397f16a3b993719c4c3b97ab2dc798",
"size": 50193
} }
] ]
}, },
@@ -639,28 +639,6 @@
"version": 5, "version": 5,
"version_string": "1.0.4", "version_string": "1.0.4",
"version_release_date": "2026-07-22", "version_release_date": "2026-07-22",
"files": [
{
"path": "connector.json",
"sha256": "c020a333b78778bc29f4097d56e27d6bde8c33b691f9aedb176a1887e65db730",
"size": 1577
},
{
"path": "icon_lg.png",
"sha256": "55a00f6108c1ba0a7d75780c446494c3272733879748e18b0377b7f816f39c5d",
"size": 3803
},
{
"path": "icon_sm.png",
"sha256": "7cc2d70581dc4288b43b27c9e1f3e3946c5598a8f71c2916aa5c2b64b9273dfe",
"size": 1882
},
{
"path": "verify.py",
"sha256": "35a4f3b518c79363893c0438b1932b68e2dc5b4b61303037984488f6967b73a4",
"size": 2057
}
],
"tools": [ "tools": [
{ {
"name": "tavily_search", "name": "tavily_search",
@@ -682,6 +660,28 @@
"name": "tavily_research", "name": "tavily_research",
"display_name": "Deep Research" "display_name": "Deep Research"
} }
],
"files": [
{
"path": "connector.json",
"sha256": "c020a333b78778bc29f4097d56e27d6bde8c33b691f9aedb176a1887e65db730",
"size": 1577
},
{
"path": "icon_lg.png",
"sha256": "55a00f6108c1ba0a7d75780c446494c3272733879748e18b0377b7f816f39c5d",
"size": 3803
},
{
"path": "icon_sm.png",
"sha256": "7cc2d70581dc4288b43b27c9e1f3e3946c5598a8f71c2916aa5c2b64b9273dfe",
"size": 1882
},
{
"path": "verify.py",
"sha256": "35a4f3b518c79363893c0438b1932b68e2dc5b4b61303037984488f6967b73a4",
"size": 2057
}
] ]
}, },
{ {
@@ -708,20 +708,15 @@
"version_string": "3.0.4", "version_string": "3.0.4",
"version_release_date": "2026-07-21", "version_release_date": "2026-07-21",
"files": [ "files": [
{
"path": "weather_mcp_server.py",
"sha256": "2b1c40f927d3095806504ae3c82ace156e6079294cf15c6c2c47df1422068185",
"size": 30001
},
{ {
"path": "connector.json", "path": "connector.json",
"sha256": "29881ad0ff5752dc546484cca6d98c22153e053d3e50c8480d02009314c9d1a8", "sha256": "29881ad0ff5752dc546484cca6d98c22153e053d3e50c8480d02009314c9d1a8",
"size": 1448 "size": 1448
}, },
{ {
"path": "requirements.txt", "path": "icon_lg.svg",
"sha256": "bff057979879bf8d16acdc64317c6f2ac3dba4f1c4cd8df5ccd2a592fa804c95", "sha256": "b1a16c5da95783d79e06388e5a18bc6c8291875335e8ac48665edeff5aeafca7",
"size": 14 "size": 372
}, },
{ {
"path": "icon_sm.svg", "path": "icon_sm.svg",
@@ -729,9 +724,14 @@
"size": 308 "size": 308
}, },
{ {
"path": "icon_lg.svg", "path": "requirements.txt",
"sha256": "b1a16c5da95783d79e06388e5a18bc6c8291875335e8ac48665edeff5aeafca7", "sha256": "bff057979879bf8d16acdc64317c6f2ac3dba4f1c4cd8df5ccd2a592fa804c95",
"size": 372 "size": 14
},
{
"path": "weather_mcp_server.py",
"sha256": "2b1c40f927d3095806504ae3c82ace156e6079294cf15c6c2c47df1422068185",
"size": 30001
} }
] ]
}, },
@@ -766,6 +766,16 @@
"sha256": "6ccae6fdf863bb6bd531d9ee0c4dcc65d46c18dd5a5f01ec914be7788f05aa31", "sha256": "6ccae6fdf863bb6bd531d9ee0c4dcc65d46c18dd5a5f01ec914be7788f05aa31",
"size": 1354 "size": 1354
}, },
{
"path": "icon_lg.png",
"sha256": "1128f198b2a07041f2e0c8c330fc998d29c310ec3225f866073b9e921aa59b5f",
"size": 74223
},
{
"path": "icon_sm.png",
"sha256": "1128f198b2a07041f2e0c8c330fc998d29c310ec3225f866073b9e921aa59b5f",
"size": 74223
},
{ {
"path": "index.js", "path": "index.js",
"sha256": "0bfaa3c5449f22a4e2c4c99c6e9402bb24651647eca9a36dbd7a639c95a6bfd6", "sha256": "0bfaa3c5449f22a4e2c4c99c6e9402bb24651647eca9a36dbd7a639c95a6bfd6",
@@ -775,16 +785,6 @@
"path": "package.json", "path": "package.json",
"sha256": "b99a9dccfd286b59e8482076129f2e40f7b339eba6c3db2a744887d65bd4964e", "sha256": "b99a9dccfd286b59e8482076129f2e40f7b339eba6c3db2a744887d65bd4964e",
"size": 302 "size": 302
},
{
"path": "icon_sm.png",
"sha256": "1128f198b2a07041f2e0c8c330fc998d29c310ec3225f866073b9e921aa59b5f",
"size": 74223
},
{
"path": "icon_lg.png",
"sha256": "1128f198b2a07041f2e0c8c330fc998d29c310ec3225f866073b9e921aa59b5f",
"size": 74223
} }
] ]
}, },
@@ -812,20 +812,15 @@
"version_string": "3.0.4", "version_string": "3.0.4",
"version_release_date": "2026-07-21", "version_release_date": "2026-07-21",
"files": [ "files": [
{
"path": "wikipedia_mcp_server.py",
"sha256": "ce9feed6a8b0a29ed405dbfe90743816d7f0714f1b580671bac722112bb54146",
"size": 12174
},
{ {
"path": "connector.json", "path": "connector.json",
"sha256": "f921a43e16d459c6ab6ddc375664e8ebe30c94e8dc35e07a72ca25d2303c6179", "sha256": "f921a43e16d459c6ab6ddc375664e8ebe30c94e8dc35e07a72ca25d2303c6179",
"size": 1339 "size": 1339
}, },
{ {
"path": "requirements.txt", "path": "icon_lg.svg",
"sha256": "bff057979879bf8d16acdc64317c6f2ac3dba4f1c4cd8df5ccd2a592fa804c95", "sha256": "f9a8dde47baf3842331534ddc4333024b195c53b5f3bda40b0b99cea3daa9a96",
"size": 14 "size": 285
}, },
{ {
"path": "icon_sm.svg", "path": "icon_sm.svg",
@@ -833,9 +828,14 @@
"size": 286 "size": 286
}, },
{ {
"path": "icon_lg.svg", "path": "requirements.txt",
"sha256": "f9a8dde47baf3842331534ddc4333024b195c53b5f3bda40b0b99cea3daa9a96", "sha256": "bff057979879bf8d16acdc64317c6f2ac3dba4f1c4cd8df5ccd2a592fa804c95",
"size": 285 "size": 14
},
{
"path": "wikipedia_mcp_server.py",
"sha256": "ce9feed6a8b0a29ed405dbfe90743816d7f0714f1b580671bac722112bb54146",
"size": 12174
} }
] ]
}, },
@@ -861,28 +861,6 @@
"version": 3, "version": 3,
"version_string": "1.0.2", "version_string": "1.0.2",
"version_release_date": "2026-07-22", "version_release_date": "2026-07-22",
"files": [
{
"path": "connector.json",
"sha256": "2c0a92ece0fa0bb6d5e00d4db6f858d21a94bdf08b6043b93cffe372054e0100",
"size": 1279
},
{
"path": "verify.py",
"sha256": "8e46d562c028c4f5370c22c7df455886836267cf4bbb8ac605c79a2b509fb5f1",
"size": 2094
},
{
"path": "icon_sm.svg",
"sha256": "5407c6bf958a7d1c83a76440c8bb8e6508941cae9f9f319dfbb9c9250807f5e0",
"size": 724
},
{
"path": "icon_lg.svg",
"sha256": "1f9b3ec611c448eff1c4fb1844a948770f4c4aadf6b7e7a73d07fec738afe209",
"size": 739
}
],
"tools": [ "tools": [
{ {
"name": "resolve-library-id", "name": "resolve-library-id",
@@ -892,6 +870,28 @@
"name": "query-docs", "name": "query-docs",
"display_name": "Query Docs" "display_name": "Query Docs"
} }
],
"files": [
{
"path": "connector.json",
"sha256": "2c0a92ece0fa0bb6d5e00d4db6f858d21a94bdf08b6043b93cffe372054e0100",
"size": 1279
},
{
"path": "icon_lg.svg",
"sha256": "1f9b3ec611c448eff1c4fb1844a948770f4c4aadf6b7e7a73d07fec738afe209",
"size": 739
},
{
"path": "icon_sm.svg",
"sha256": "5407c6bf958a7d1c83a76440c8bb8e6508941cae9f9f319dfbb9c9250807f5e0",
"size": 724
},
{
"path": "verify.py",
"sha256": "8e46d562c028c4f5370c22c7df455886836267cf4bbb8ac605c79a2b509fb5f1",
"size": 2094
}
] ]
}, },
{ {
@@ -923,33 +923,6 @@
"version": 4, "version": 4,
"version_string": "1.0.3", "version_string": "1.0.3",
"version_release_date": "2026-07-22", "version_release_date": "2026-07-22",
"files": [
{
"path": "connector.json",
"sha256": "ec483834a2c6d090716be0ac0c55b328f46edca26c17c24c4b289279d6a3186d",
"size": 2444
},
{
"path": "gmaps_mcp_server.py",
"sha256": "98db82cc3f94d237c1675dbda97ec331d9b757f018c612b934a14c88143d9dd0",
"size": 30987
},
{
"path": "verify.py",
"sha256": "f566e0a0d297bf636d43e89c4b0085cdbd5322f6d353ea3552f37373e8612f55",
"size": 1903
},
{
"path": "icon_sm.svg",
"sha256": "796656d456681ef331ea9f3fa11419f37b8bb454ad7089de32f5583b2523abc4",
"size": 766
},
{
"path": "icon_lg.svg",
"sha256": "796656d456681ef331ea9f3fa11419f37b8bb454ad7089de32f5583b2523abc4",
"size": 766
}
],
"tools": [ "tools": [
{ {
"name": "status", "name": "status",
@@ -975,9 +948,35 @@
"name": "distance_matrix", "name": "distance_matrix",
"display_name": "Distance Matrix" "display_name": "Distance Matrix"
} }
],
"files": [
{
"path": "connector.json",
"sha256": "ec483834a2c6d090716be0ac0c55b328f46edca26c17c24c4b289279d6a3186d",
"size": 2444
},
{
"path": "gmaps_mcp_server.py",
"sha256": "98db82cc3f94d237c1675dbda97ec331d9b757f018c612b934a14c88143d9dd0",
"size": 30987
},
{
"path": "icon_lg.svg",
"sha256": "796656d456681ef331ea9f3fa11419f37b8bb454ad7089de32f5583b2523abc4",
"size": 766
},
{
"path": "icon_sm.svg",
"sha256": "796656d456681ef331ea9f3fa11419f37b8bb454ad7089de32f5583b2523abc4",
"size": 766
},
{
"path": "verify.py",
"sha256": "f566e0a0d297bf636d43e89c4b0085cdbd5322f6d353ea3552f37373e8612f55",
"size": 1903
}
] ]
}, },
{ {
"id": "google-trends", "id": "google-trends",
"name": "Google Trends", "name": "Google Trends",
@@ -985,7 +984,7 @@
"scope": "global", "scope": "global",
"icon_small": "google-trends/icon_sm.png", "icon_small": "google-trends/icon_sm.png",
"icon_large": "google-trends/icon_lg.png", "icon_large": "google-trends/icon_lg.png",
"user_description": "Current trending topics by country, keyword search interest history, related queries, and regional interest maps. Powered by trendspyg no API key required.", "user_description": "Current trending topics by country, keyword search interest history, related queries, and regional interest maps. Powered by trendspyg \u2014 no API key required.",
"requires": [ "requires": [
"PYTHON" "PYTHON"
], ],
@@ -1004,14 +1003,6 @@
"version": 1, "version": 1,
"version_string": "1.0.0", "version_string": "1.0.0",
"version_release_date": "2026-07-22", "version_release_date": "2026-07-22",
"files": [
{"path": "google_trends_mcp.py", "sha256": "5404eb7c81e82180a3b9e3052a4793e80a361ae60156d598d8e62e36b21dea8a", "size": 13552},
{"path": "connector.json", "sha256": "0f50383fa3d664e6f487983645c56a57a076353a8fea337d121826210ebd3a8a", "size": 1191},
{"path": "verify.py", "sha256": "adbae57fc109c06c5d61ff50b67faaf62e1fa493a18cbfdacbc73f24d51ba9b8", "size": 831},
{"path": "requirements.txt", "sha256": "8b13038b5c79cff2680a9b482491b969ac83ce4efa396f408bfca97385d00621", "size": 17},
{"path": "icon_sm.png", "sha256": "e7b9a8ba97f824948dae572db069296bbf81bef84007d1e18c0fd598b0a05232", "size": 2304},
{"path": "icon_lg.png", "sha256": "636d2982098c862a04099aea01d7f7ca7a9ad258dafed286baa08864480eacad", "size": 4664}
],
"tools": [ "tools": [
{ {
"name": "status", "name": "status",
@@ -1029,6 +1020,38 @@
"name": "explore", "name": "explore",
"display_name": "Explore Keyword" "display_name": "Explore Keyword"
} }
],
"files": [
{
"path": "connector.json",
"sha256": "0f50383fa3d664e6f487983645c56a57a076353a8fea337d121826210ebd3a8a",
"size": 1191
},
{
"path": "google_trends_mcp.py",
"sha256": "5404eb7c81e82180a3b9e3052a4793e80a361ae60156d598d8e62e36b21dea8a",
"size": 13552
},
{
"path": "icon_lg.png",
"sha256": "636d2982098c862a04099aea01d7f7ca7a9ad258dafed286baa08864480eacad",
"size": 4664
},
{
"path": "icon_sm.png",
"sha256": "e7b9a8ba97f824948dae572db069296bbf81bef84007d1e18c0fd598b0a05232",
"size": 2304
},
{
"path": "requirements.txt",
"sha256": "8b13038b5c79cff2680a9b482491b969ac83ce4efa396f408bfca97385d00621",
"size": 17
},
{
"path": "verify.py",
"sha256": "adbae57fc109c06c5d61ff50b67faaf62e1fa493a18cbfdacbc73f24d51ba9b8",
"size": 831
}
] ]
} }
] ]
+33
View File
@@ -0,0 +1,33 @@
{
"id": "context7",
"name": "Context7",
"type": "mcp_remote",
"scope": "global",
"icon_small": "context7/icon_sm.svg",
"icon_large": "context7/icon_lg.svg",
"user_description": "Up-to-date documentation and code examples for any library, framework, SDK, API, CLI tool, or cloud service \u2014 fetched directly from the source. Free, no API key required.",
"tags": [
"documentation",
"search",
"mcp",
"remote",
"developer-tools"
],
"auth": {
"type": "none"
},
"folder": "context7",
"version": 3,
"version_string": "1.0.2",
"version_release_date": "2026-07-22",
"tools": [
{
"name": "resolve-library-id",
"display_name": "Resolve Library"
},
{
"name": "query-docs",
"display_name": "Query Docs"
}
]
}
+32
View File
@@ -0,0 +1,32 @@
{
"id": "drive",
"name": "Google Drive",
"type": "mcp_local",
"scope": "user",
"icon_small": "drive/icon_sm.png",
"icon_large": "drive/icon_lg.png",
"user_description": "List, search, upload, download, delete, and manage Google Drive files and folders. Full OAuth \u2014 same pattern as Gmail and Google Calendar.",
"requires": [
"OAUTH",
"PYTHON"
],
"tags": [
"cloud-storage",
"files",
"mcp",
"local",
"google",
"drive"
],
"auth": {
"type": "oauth2",
"provider": "google",
"scopes": [
"https://www.googleapis.com/auth/drive"
]
},
"folder": "drive",
"version": 7,
"version_string": "1.0.6",
"version_release_date": "2026-07-22"
}
+26
View File
@@ -0,0 +1,26 @@
{
"id": "email",
"name": "Email (IMAP/SMTP)",
"type": "mcp_local",
"scope": "user",
"icon_small": "email/icon_sm.svg",
"icon_large": "email/icon_lg.svg",
"user_description": "Read, search, organize, and send email over IMAP/SMTP \u2014 any provider, no OAuth. Real-time push notifications on new mail.",
"requires": [
"PYTHON"
],
"tags": [
"email",
"mcp",
"local",
"imap",
"smtp"
],
"auth": {
"type": "password"
},
"folder": "email",
"version": 5,
"version_string": "1.0.4",
"version_release_date": "2026-07-21"
}
+32
View File
@@ -0,0 +1,32 @@
{
"id": "exa",
"name": "Exa",
"type": "mcp_remote",
"scope": "global",
"icon_small": "exa/icon_sm.png",
"icon_large": "exa/icon_lg.png",
"user_description": "AI-powered web search, content extraction, and research via Exa's neural search engine. Works without an API key (free rate-limited tier).",
"tags": [
"search",
"mcp",
"remote",
"ai"
],
"auth": {
"type": "api_key"
},
"folder": "exa",
"version": 4,
"version_string": "1.0.3",
"version_release_date": "2026-07-21",
"tools": [
{
"name": "web_search_exa",
"display_name": "Web Search"
},
{
"name": "web_fetch_exa",
"display_name": "Web Fetch"
}
]
}
+134
View File
@@ -0,0 +1,134 @@
{
"id": "firecrawl",
"name": "Firecrawl",
"type": "mcp_local",
"scope": "global",
"icon_small": "firecrawl/icon_sm.png",
"icon_large": "firecrawl/icon_lg.png",
"user_description": "Web scraping, crawling, search, deep research, and autonomous browsing \u2014 extract content from any website.",
"requires": [
"NODE"
],
"tags": [
"scraping",
"crawling",
"search",
"mcp",
"local",
"browser",
"research"
],
"auth": {
"type": "api_key"
},
"folder": "firecrawl",
"version": 4,
"version_string": "1.0.3",
"version_release_date": "2026-07-21",
"tools": [
{
"name": "firecrawl_scrape",
"display_name": "Scrape URL"
},
{
"name": "firecrawl_map",
"display_name": "Map Site"
},
{
"name": "firecrawl_search",
"display_name": "Web Search"
},
{
"name": "firecrawl_search_feedback",
"display_name": "Search Feedback"
},
{
"name": "firecrawl_feedback",
"display_name": "Feedback"
},
{
"name": "firecrawl_crawl",
"display_name": "Crawl Site"
},
{
"name": "firecrawl_check_crawl_status",
"display_name": "Check Crawl Status"
},
{
"name": "firecrawl_extract",
"display_name": "Extract Data"
},
{
"name": "firecrawl_agent",
"display_name": "Research Agent"
},
{
"name": "firecrawl_agent_status",
"display_name": "Agent Status"
},
{
"name": "firecrawl_interact",
"display_name": "Interact with Page"
},
{
"name": "firecrawl_interact_stop",
"display_name": "Stop Interact"
},
{
"name": "firecrawl_parse",
"display_name": "Parse"
},
{
"name": "firecrawl_monitor_create",
"display_name": "Create Monitor"
},
{
"name": "firecrawl_monitor_list",
"display_name": "List Monitors"
},
{
"name": "firecrawl_monitor_get",
"display_name": "Get Monitor"
},
{
"name": "firecrawl_monitor_update",
"display_name": "Update Monitor"
},
{
"name": "firecrawl_monitor_delete",
"display_name": "Delete Monitor"
},
{
"name": "firecrawl_monitor_run",
"display_name": "Run Monitor"
},
{
"name": "firecrawl_monitor_checks",
"display_name": "List Checks"
},
{
"name": "firecrawl_monitor_check",
"display_name": "Get Check"
},
{
"name": "firecrawl_research_search_papers",
"display_name": "Search Papers"
},
{
"name": "firecrawl_research_inspect_paper",
"display_name": "Inspect Paper"
},
{
"name": "firecrawl_research_related_papers",
"display_name": "Related Papers"
},
{
"name": "firecrawl_research_read_paper",
"display_name": "Read Paper"
},
{
"name": "firecrawl_research_search_github",
"display_name": "Search GitHub"
}
]
}
+30
View File
@@ -0,0 +1,30 @@
{
"id": "gcal",
"name": "Google Calendar",
"type": "mcp_local",
"scope": "user",
"icon_small": "gcal/icon_sm.svg",
"icon_large": "gcal/icon_lg.svg",
"user_description": "Read, create, update, delete, and respond to Google Calendar events \u2014 full CRUD with push notifications.",
"requires": [
"OAUTH",
"PYTHON"
],
"tags": [
"calendar",
"mcp",
"local",
"google"
],
"auth": {
"type": "oauth2",
"provider": "google",
"scopes": [
"https://www.googleapis.com/auth/calendar"
]
},
"folder": "gcal",
"version": 5,
"version_string": "0.3.4",
"version_release_date": "2026-07-21"
}
+31
View File
@@ -0,0 +1,31 @@
{
"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 \u2014 full MCP integration with push notifications.",
"requires": [
"OAUTH",
"PYTHON"
],
"tags": [
"email",
"mcp",
"local",
"google"
],
"auth": {
"type": "oauth2",
"provider": "google",
"scopes": [
"https://www.googleapis.com/auth/gmail.modify",
"https://www.googleapis.com/auth/gmail.labels"
]
},
"folder": "gmail",
"version": 6,
"version_string": "1.0.5",
"version_release_date": "2026-07-22"
}
+56
View File
@@ -0,0 +1,56 @@
{
"id": "gmaps",
"name": "Google Maps",
"type": "mcp_local",
"scope": "global",
"icon_small": "gmaps/icon_sm.svg",
"icon_large": "gmaps/icon_lg.svg",
"user_description": "Get transit, driving, walking and cycling directions, geocode addresses, search nearby places, and compute distance matrices \u2014 powered by Google Maps Platform.",
"requires": [
"PYTHON",
"ENV"
],
"tags": [
"maps",
"mcp",
"local",
"google",
"navigation",
"transit"
],
"auth": {
"type": "api_key",
"delivery": "env",
"param": "GOOGLE_MAPS_API_KEY"
},
"folder": "gmaps",
"version": 4,
"version_string": "1.0.3",
"version_release_date": "2026-07-22",
"tools": [
{
"name": "status",
"display_name": "Status Check"
},
{
"name": "directions",
"display_name": "Directions"
},
{
"name": "geocode",
"display_name": "Geocode"
},
{
"name": "reverse_geocode",
"display_name": "Reverse Geocode"
},
{
"name": "search_places",
"display_name": "Search Places"
},
{
"name": "distance_matrix",
"display_name": "Distance Matrix"
}
]
}
+45
View File
@@ -0,0 +1,45 @@
{
"id": "google-trends",
"name": "Google Trends",
"type": "mcp_local",
"scope": "global",
"icon_small": "google-trends/icon_sm.png",
"icon_large": "google-trends/icon_lg.png",
"user_description": "Current trending topics by country, keyword search interest history, related queries, and regional interest maps. Powered by trendspyg \u2014 no API key required.",
"requires": [
"PYTHON"
],
"tags": [
"trends",
"mcp",
"local",
"google",
"search",
"analytics"
],
"auth": {
"type": "none"
},
"folder": "google-trends",
"version": 1,
"version_string": "1.0.0",
"version_release_date": "2026-07-22",
"tools": [
{
"name": "status",
"display_name": "Status Check"
},
{
"name": "get_trending",
"display_name": "Get Trending Topics"
},
{
"name": "get_interest_over_time",
"display_name": "Interest Over Time"
},
{
"name": "explore",
"display_name": "Explore Keyword"
}
]
}
+54
View File
@@ -0,0 +1,54 @@
{
"id": "http-fetch",
"name": "HTTP Fetch",
"type": "mcp_local",
"scope": "global",
"icon_small": "http-fetch/icon_sm.svg",
"icon_large": "http-fetch/icon_lg.svg",
"user_description": "Fetch any URL as HTML, Markdown, text, JSON, or YouTube transcripts \u2014 free, no API key, no rate limits.",
"requires": [
"NODE"
],
"tags": [
"http",
"fetch",
"mcp",
"local",
"free",
"scraping",
"youtube"
],
"auth": {
"type": "none"
},
"folder": "http-fetch",
"version": 4,
"version_string": "1.0.3",
"version_release_date": "2026-07-21",
"tools": [
{
"name": "fetch_html",
"display_name": "Fetch as HTML"
},
{
"name": "fetch_markdown",
"display_name": "Fetch as Markdown"
},
{
"name": "fetch_txt",
"display_name": "Fetch as Text"
},
{
"name": "fetch_json",
"display_name": "Fetch as JSON"
},
{
"name": "fetch_readable",
"display_name": "Fetch Readable Content"
},
{
"name": "fetch_youtube_transcript",
"display_name": "Get YouTube Transcript"
}
]
}
+1
View File
@@ -0,0 +1 @@
["gmail", "gcal", "drive", "email", "exa", "firecrawl", "http-fetch", "serpapi-flights", "ssh", "tavily", "weather", "whatsapp", "wikipedia", "context7", "gmaps", "google-trends"]
+29
View File
@@ -0,0 +1,29 @@
{
"id": "serpapi-flights",
"name": "SerpAPI Flights",
"type": "mcp_remote",
"scope": "global",
"icon_small": "serpapi-flights/icon_sm.svg",
"icon_large": "serpapi-flights/icon_lg.svg",
"user_description": "Search and compare flights, lookup airport codes, and explore routes via SerpAPI\u2019s Google Flights integration.",
"tags": [
"flights",
"travel",
"mcp",
"remote",
"search"
],
"auth": {
"type": "api_key"
},
"folder": "serpapi-flights",
"version": 4,
"version_string": "1.0.3",
"version_release_date": "2026-07-21",
"tools": [
{
"name": "serpapi_search_flights",
"display_name": "Search Flights"
}
]
}
+27
View File
@@ -0,0 +1,27 @@
{
"id": "ssh",
"name": "SSH Remote Access",
"type": "mcp_local",
"scope": "user",
"icon_small": "ssh/icon_sm.svg",
"icon_large": "ssh/icon_lg.svg",
"user_description": "Full SSH remote server access \u2014 files, commands, systemd, upload/download. Aliases manage host config; auth via key/agent or elicited password.",
"requires": [
"PYTHON"
],
"tags": [
"ssh",
"mcp",
"local",
"remote",
"server",
"sysadmin"
],
"auth": {
"type": "none"
},
"folder": "ssh",
"version": 5,
"version_string": "1.0.4",
"version_release_date": "2026-07-21"
}
+43
View File
@@ -0,0 +1,43 @@
{
"id": "tavily",
"name": "Tavily",
"type": "mcp_remote",
"scope": "global",
"icon_small": "tavily/icon_sm.png",
"icon_large": "tavily/icon_lg.png",
"user_description": "Web search API for LLMs \u2014 real-time results, news, and content extraction.",
"tags": [
"search",
"mcp",
"remote"
],
"auth": {
"type": "api_key"
},
"folder": "tavily",
"version": 5,
"version_string": "1.0.4",
"version_release_date": "2026-07-22",
"tools": [
{
"name": "tavily_search",
"display_name": "Web Search"
},
{
"name": "tavily_extract",
"display_name": "Extract Content"
},
{
"name": "tavily_crawl",
"display_name": "Crawl Site"
},
{
"name": "tavily_map",
"display_name": "Map Site"
},
{
"name": "tavily_research",
"display_name": "Deep Research"
}
]
}
+24
View File
@@ -0,0 +1,24 @@
{
"id": "weather",
"name": "Weather (Open-Meteo)",
"type": "mcp_local",
"scope": "global",
"icon_small": "weather/icon_sm.svg",
"icon_large": "weather/icon_lg.svg",
"user_description": "Global weather, forecast, and air quality via Open-Meteo \u2014 free, no API key required.",
"tags": [
"weather",
"mcp",
"local",
"free",
"forecast",
"air-quality"
],
"auth": {
"type": "none"
},
"folder": "weather",
"version": 7,
"version_string": "3.0.4",
"version_release_date": "2026-07-21"
}
+26
View File
@@ -0,0 +1,26 @@
{
"id": "whatsapp",
"name": "WhatsApp",
"type": "mcp_local",
"scope": "user",
"icon_small": "whatsapp/icon_sm.png",
"icon_large": "whatsapp/icon_lg.png",
"user_description": "Send and read WhatsApp messages from your own linked account. Link via QR code \u2014 no browser needed.",
"requires": [
"NODE"
],
"tags": [
"messaging",
"mcp",
"local",
"whatsapp",
"qr"
],
"auth": {
"type": "qr"
},
"folder": "whatsapp",
"version": 6,
"version_string": "2.0.6",
"version_release_date": "2026-07-21"
}
+24
View File
@@ -0,0 +1,24 @@
{
"id": "wikipedia",
"name": "Wikipedia",
"type": "mcp_local",
"scope": "global",
"icon_small": "wikipedia/icon_sm.svg",
"icon_large": "wikipedia/icon_lg.svg",
"user_description": "Search and read Wikipedia articles \u2014 free, no API key required.",
"tags": [
"wikipedia",
"mcp",
"local",
"free",
"reference",
"research"
],
"auth": {
"type": "none"
},
"folder": "wikipedia",
"version": 7,
"version_string": "3.0.4",
"version_release_date": "2026-07-21"
}
+130
View File
@@ -0,0 +1,130 @@
#!/usr/bin/env python3
"""Compile connectors/index.json + fragment.json + file hash scan → connectors.json
Usage:
python3 scripts/compile.py # scrive connectors/connectors.json
python3 scripts/compile.py --verify # verifica che l'indice esistente sia aggiornato
Legge:
- connectors/index.json — lista ordinata di id folder
- connectors/<id>/fragment.json — entry dell'indice senza files[]
- scansione fisica dei file — SHA-256 e size di ogni file nella cartella
Produce:
- connectors/connectors.json — indice completo con files[] e SHA-256
Esclusioni automatiche: fragment.json, connector.json, compile.sh, compile.py,
update_hashes.py, e l'intera directory scripts/.
"""
from __future__ import annotations
import hashlib
import json
import os
import sys
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
INDEX_DIR = os.path.join(ROOT, "connectors")
EXCLUDE_FILES = {
"fragment.json",
"connectors.json",
"index.json",
"compile.sh",
"compile.py",
"update_hashes.py",
".DS_Store",
}
EXCLUDE_DIRS = {"scripts", "__pycache__", ".git"}
def scan_files(folder_path: str) -> list[dict]:
"""Scan all files in folder_path, return [{path, sha256, size}, ...] sorted."""
files = []
for fname in sorted(os.listdir(folder_path)):
fpath = os.path.join(folder_path, fname)
if os.path.isdir(fpath):
continue
if fname in EXCLUDE_FILES:
continue
with open(fpath, "rb") as f:
data = f.read()
files.append({
"path": fname,
"sha256": hashlib.sha256(data).hexdigest(),
"size": len(data),
})
return files
def compile_index() -> list[dict]:
"""Build the connectors list from index.json + fragments + file scan."""
index_path = os.path.join(INDEX_DIR, "index.json")
if not os.path.exists(index_path):
print("❌ connectors/index.json not found. Create it first.", file=sys.stderr)
sys.exit(1)
with open(index_path) as f:
order: list[str] = json.load(f)
connectors = []
for i, connector_id in enumerate(order):
frag_path = os.path.join(INDEX_DIR, connector_id, "fragment.json")
if not os.path.exists(frag_path):
print(
f"⚠️ [{i+1}/{len(order)}] {connector_id} — fragment.json not found, skipping.",
file=sys.stderr,
)
continue
with open(frag_path) as f:
fragment: dict = json.load(f)
folder_path = os.path.join(INDEX_DIR, connector_id)
files = scan_files(folder_path)
fragment["files"] = files
n_files = len(files)
print(f"✓ [{i+1}/{len(order)}] {connector_id}{n_files} file{'s' if n_files != 1 else ''}")
connectors.append(fragment)
return connectors
def write_index(connectors: list[dict]) -> None:
"""Write the compiled connectors.json."""
output = {"version": 1, "connectors": connectors}
out_path = os.path.join(INDEX_DIR, "connectors.json")
with open(out_path, "w") as f:
json.dump(output, f, indent=2)
f.write("\n")
print(f"\n✅ Scritto {out_path} ({len(connectors)} connector)")
def verify_index() -> bool:
"""Verify existing connectors.json matches what compilation would produce."""
with open(os.path.join(INDEX_DIR, "connectors.json")) as f:
current = json.load(f)
fresh = compile_index()
if current["connectors"] == fresh:
print("✅ L'indice è aggiornato — nessuna modifica.")
return True
else:
print("❌ L'indice NON è aggiornato. Esegui compile.py per rigenerarlo.")
return False
def main() -> None:
if "--verify" in sys.argv:
sys.exit(0 if verify_index() else 1)
connectors = compile_index()
write_index(connectors)
if __name__ == "__main__":
main()