gmaps: fix missing dependency install + wire verify (v6 / 1.1.0)

The connector shipped no requirements.txt, so ensure_installed_host()
installed nothing and every tool call failed with "No module named
'googlemaps'" while the server still answered tools/list — skald logged
"connected — 6 tool(s)" on a connector that could not work.

- add requirements.txt (googlemaps>=4.10.0); deps were declared in the
  manifest's `dependencies` field, which skald only uses for the card
- wire the shipped verify.py through a `verify` manifest block, so a
  broken install fails visibly at enable time instead of silently
- verify.py puts .pydeps on sys.path: skald sets PYTHONPATH only for the
  server process, not for the `sh -c "python3 verify.py"` verify step
- drop the inert mcp_config.env {SECRET:…} placeholder — those tokens are
  substituted in the URL only, never in env values
- realign manifest/fragment versions (were 2/1.0.1 vs 5/1.0.4); skald
  prefers the manifest, so "update available" could never appear
- requires ENV -> API_KEY; drop deprecated secrets/ path from error text
- regenerate the index
This commit is contained in:
Daniele
2026-08-10 12:38:32 +01:00
parent 2ad3954e3a
commit 73d1a51b1f
7 changed files with 62 additions and 29 deletions
+15
View File
@@ -1,6 +1,21 @@
# Skald Connectors Marketplace # Skald Connectors Marketplace
### 2026-08-10 — gmaps: fix dipendenze + verify (v6 / 1.1.0)
- **Aggiunto `requirements.txt` (`googlemaps>=4.10.0`)** — era l'unico connector python senza. Le dipendenze erano dichiarate nel campo `dependencies` del manifest, che skald usa **solo per la card**: `ensure_installed_host` guarda esclusivamente `requirements.txt` / `package.json`. Risultato: `.pydeps` vuoto e log pieno di `No module named 'googlemaps'`, con il server che rispondeva comunque a `tools/list` (→ `connected — 6 tool(s)` su un connector non funzionante).
- **Cablato il `verify`** (`python3 verify.py`, 20s): `verify.py` era shippato ma il manifest non aveva il blocco `verify`, e skald legge `verify_command` solo da lì. Ora un'abilitazione con dipendenze rotte fallisce visibilmente invece di partire in silenzio.
- **`verify.py` si mette `.pydeps` su `sys.path`**: skald imposta `PYTHONPATH` solo per il processo *server* (`global_row_spec`), mentre il verify gira come `sh -c "python3 verify.py"` senza. Senza questa riga il verify fallirebbe con "Missing dependency" anche su un connector installato correttamente, disabilitando la riga. ⚠️ **Stesso rischio latente per ogni connector con `verify` che importa dipendenze non-stdlib** (gcal in container): da controllare.
- **Rimosso `mcp_config.env: {"GOOGLE_MAPS_API_KEY": "{SECRET:…}"}`** (introdotto il 2026-07-23): inerte. `apply_key_placeholder` sostituisce i token `{SECRET:}`/`{ENV:}` **solo nella URL**, mai nei valori di `env`. Funzionava perché la form admin manda `env` e quel payload sovrascrive `entry.env_json`; a form vuota il processo avrebbe ricevuto la stringa letterale. ⚠️ **La spec in questo file e in CLAUDE.md dice il contrario** — o si corregge la spec, o si estende la sostituzione ai valori di `env` lato skald.
- **Versioni riallineate** manifest↔fragment a `6` / `1.1.0` / `2026-08-10`: erano 2/1.0.1 vs 5/1.0.4, e skald preferisce il manifest (`manifest.version.or(entry.version)`) — quindi `installed_version` restava 2 e il badge "Update available" non sarebbe mai comparso.
- `requires`: `ENV``API_KEY`; messaggi d'errore del server ripuliti dai riferimenti a `secrets/gmaps_api_key.txt` (path deprecato).
- Indice rigenerato con compile.py ✅
### 2026-08-07 — Nuovo connector: LinkedIn
- Aggiunto connector `linkedin` (mcp_local, scope user): server.py + session.py + verify.py + icone PNG
- Aggiunto a `connectors/index.json`, indice rigenerato con compile.py (17 connector totali)
- `.gitignore` aggiornato per ignorare `.claude/`
- Deploy su connectors.skaldagent.net via alias `skaldserver` (192.168.1.100, LAN — niente Tailscale)
### 2026-07-23 — gmaps: fix env var injection ### 2026-07-23 — gmaps: fix env var injection
- Aggiunto `mcp_config.env` in `connector.json` per iniettare `GOOGLE_MAPS_API_KEY` nel processo MCP - Aggiunto `mcp_config.env` in `connector.json` per iniettare `GOOGLE_MAPS_API_KEY` nel processo MCP
- Il connector era dichiarato come `delivery: env` ma senza `mcp_config.env` Skald non sapeva passare la variabile al processo Python - Il connector era dichiarato come `delivery: env` ma senza `mcp_config.env` Skald non sapeva passare la variabile al processo Python
+15 -10
View File
@@ -920,7 +920,7 @@
"user_description": "Get transit, driving, walking and cycling directions, geocode addresses, search nearby places, and compute distance matrices \u2014 powered by Google Maps Platform.", "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": [ "requires": [
"PYTHON", "PYTHON",
"ENV" "API_KEY"
], ],
"tags": [ "tags": [
"maps", "maps",
@@ -936,9 +936,9 @@
"param": "GOOGLE_MAPS_API_KEY" "param": "GOOGLE_MAPS_API_KEY"
}, },
"folder": "gmaps", "folder": "gmaps",
"version": 5, "version": 6,
"version_string": "1.0.4", "version_string": "1.1.0",
"version_release_date": "2026-07-23", "version_release_date": "2026-08-10",
"tools": [ "tools": [
{ {
"name": "status", "name": "status",
@@ -968,13 +968,13 @@
"files": [ "files": [
{ {
"path": "connector.json", "path": "connector.json",
"sha256": "6b67291396e942ee5414b902d446606ccd65151badb43e2c769760d019dbb345", "sha256": "54d69f162d1c95631c17e89d05b00f470810fb7aeb24c160aaf72f4f87764972",
"size": 2524 "size": 2613
}, },
{ {
"path": "gmaps_mcp_server.py", "path": "gmaps_mcp_server.py",
"sha256": "98db82cc3f94d237c1675dbda97ec331d9b757f018c612b934a14c88143d9dd0", "sha256": "a16aa01fb55f118e422a756f56d2c6515bfbd6c39122b254e4f47d158b10d36b",
"size": 30987 "size": 31094
}, },
{ {
"path": "icon_lg.svg", "path": "icon_lg.svg",
@@ -986,10 +986,15 @@
"sha256": "796656d456681ef331ea9f3fa11419f37b8bb454ad7089de32f5583b2523abc4", "sha256": "796656d456681ef331ea9f3fa11419f37b8bb454ad7089de32f5583b2523abc4",
"size": 766 "size": 766
}, },
{
"path": "requirements.txt",
"sha256": "fdccc70a6db40b6f1fb1d7abc4e00e69070221329d8886a37460157b4ffbd456",
"size": 19
},
{ {
"path": "verify.py", "path": "verify.py",
"sha256": "f566e0a0d297bf636d43e89c4b0085cdbd5322f6d353ea3552f37373e8612f55", "sha256": "1550358f8fecaa7bed492912adf39297bf46920d6f0f44189e6b31b343f6ac24",
"size": 1903 "size": 2364
} }
] ]
}, },
+10 -8
View File
@@ -1,16 +1,16 @@
{ {
"id": "gmaps", "id": "gmaps",
"name": "Google Maps", "name": "Google Maps",
"version": 2, "version": 6,
"version_string": "1.0.1", "version_string": "1.1.0",
"version_release_date": "2026-07-23", "version_release_date": "2026-08-10",
"type": "mcp_local", "type": "mcp_local",
"scope": "global", "scope": "global",
"launch_command": "python3 gmaps_mcp_server.py", "launch_command": "python3 gmaps_mcp_server.py",
"transport": "stdio", "transport": "stdio",
"requires": [ "requires": [
"PYTHON", "PYTHON",
"ENV" "API_KEY"
], ],
"tags": [ "tags": [
"maps", "maps",
@@ -36,8 +36,12 @@
"setup_instructions": [ "setup_instructions": [
"Ensure the Google Maps APIs are enabled in your GCP project: Directions, Geocoding, Places, Distance Matrix.", "Ensure the Google Maps APIs are enabled in your GCP project: Directions, Geocoding, Places, Distance Matrix.",
"Create an API key in Google Cloud Console \u2192 Credentials, restricting it to those four APIs.", "Create an API key in Google Cloud Console \u2192 Credentials, restricting it to those four APIs.",
"Install the Python package: pip install googlemaps" "Paste the key into the connector form; the googlemaps package is installed automatically from requirements.txt."
], ],
"verify": {
"command": "python3 verify.py",
"timeout_secs": 20
},
"docs": [ "docs": [
{ {
"lang": "en", "lang": "en",
@@ -84,9 +88,7 @@
"args": [ "args": [
"gmaps_mcp_server.py" "gmaps_mcp_server.py"
], ],
"env": { "transport": "stdio"
"GOOGLE_MAPS_API_KEY": "{SECRET:GOOGLE_MAPS_API_KEY}"
}
}, },
"homepage": "https://maps.google.com", "homepage": "https://maps.google.com",
"icon_small": "icon_sm.svg", "icon_small": "icon_sm.svg",
+4 -4
View File
@@ -8,7 +8,7 @@
"user_description": "Get transit, driving, walking and cycling directions, geocode addresses, search nearby places, and compute distance matrices \u2014 powered by Google Maps Platform.", "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": [ "requires": [
"PYTHON", "PYTHON",
"ENV" "API_KEY"
], ],
"tags": [ "tags": [
"maps", "maps",
@@ -24,9 +24,9 @@
"param": "GOOGLE_MAPS_API_KEY" "param": "GOOGLE_MAPS_API_KEY"
}, },
"folder": "gmaps", "folder": "gmaps",
"version": 5, "version": 6,
"version_string": "1.0.4", "version_string": "1.1.0",
"version_release_date": "2026-07-23", "version_release_date": "2026-08-10",
"tools": [ "tools": [
{ {
"name": "status", "name": "status",
+9 -7
View File
@@ -9,8 +9,9 @@ Capabilities (callable as `mcp__gmaps__<tool>`):
distance_matrix — travel time & distance between multiple origins/destinations distance_matrix — travel time & distance between multiple origins/destinations
Auth: Auth:
API key is read from env var GOOGLE_MAPS_API_KEY, or from the file at API key is read from env var GOOGLE_MAPS_API_KEY, injected by Skald from the
GOOGLE_MAPS_API_KEY_FILE (default: ./secrets/gmaps_api_key.txt). connector's `env[]` form field. A file fallback (GOOGLE_MAPS_API_KEY_FILE)
exists for standalone runs only.
Required Google Cloud APIs to enable: Required Google Cloud APIs to enable:
- Directions API - Directions API
@@ -81,8 +82,8 @@ def _get_client():
if not api_key: if not api_key:
_init_error = ( _init_error = (
"Google Maps API key not found. " "Google Maps API key not found. "
"Set GOOGLE_MAPS_API_KEY env var or create secrets/gmaps_api_key.txt " "Open the Google Maps connector in Skald and paste the API key into "
"with just the key on the first line." "the 'Google Maps API key' field, then re-enable it."
) )
log(_init_error) log(_init_error)
return None return None
@@ -119,7 +120,7 @@ def _format_gmaps_error(e: Exception, api_label: str) -> str:
if status == "REQUEST_DENIED": if status == "REQUEST_DENIED":
return ( return (
f"Error: {api_label} API request denied (REQUEST_DENIED). " f"Error: {api_label} API request denied (REQUEST_DENIED). "
"Verify that the API key in secrets/gmaps_api_key.txt is valid and that " "Verify that the API key configured for this connector is valid and that "
f"the {api_label} API is enabled in the Google Cloud Console." f"the {api_label} API is enabled in the Google Cloud Console."
) )
if status == "INVALID_REQUEST": if status == "INVALID_REQUEST":
@@ -163,8 +164,9 @@ def _maps_status(args: dict) -> str:
if not api_key: if not api_key:
return ( return (
"Error: Google Maps API key not found. " "Error: Google Maps API key not found. "
"Set GOOGLE_MAPS_API_KEY env var or create secrets/gmaps_api_key.txt " "Ask the administrator to open the Google Maps connector in Skald and paste "
"with the key on the first line. No Google Maps tool will work until this is fixed." "the API key into the 'Google Maps API key' field. "
"No Google Maps tool will work until this is fixed."
) )
# Step 2: dependency present + client built? # Step 2: dependency present + client built?
+1
View File
@@ -0,0 +1 @@
googlemaps>=4.10.0
+8
View File
@@ -12,6 +12,14 @@ import json
import os import os
import sys import sys
# Skald installs our deps with `pip install --target .pydeps` beside this file and
# puts that dir on PYTHONPATH for the *server* process only — the verify step gets
# a bare `sh -c "python3 verify.py"`, so `import googlemaps` would fail here even
# on a correctly installed connector. Put .pydeps on sys.path ourselves.
_PYDEPS = os.path.join(os.path.dirname(os.path.abspath(__file__)), ".pydeps")
if os.path.isdir(_PYDEPS):
sys.path.insert(0, _PYDEPS)
def main() -> None: def main() -> None:
api_key = os.environ.get("GOOGLE_MAPS_API_KEY", "").strip() api_key = os.environ.get("GOOGLE_MAPS_API_KEY", "").strip()