Files
skald-connectors/CHANGELOG.md
T
Daniele fa8bbcb808 add playwright connector (v1 / 1.0.0) + commit pending docs reorganization
- new global mcp_local connector wrapping @playwright/mcp@0.0.79:
  index.js argv wrapper (--headless --isolated --no-sandbox) importing
  the package cli.js, postinstall downloads chromium-only browser,
  verify.js headless-launch probe, 24 tools with display names
- also carries the pending docs work: changelog extracted to
  CHANGELOG.md, manifest guide, SKALD.md/CLAUDE.md updates
2026-08-19 17:37:13 +01:00

10 KiB
Raw Blame History

Changelog

All notable changes to the Skald Connectors Marketplace are documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

2026-08-19

Added

  • New connector: Playwright (mcp_local, scope global, v1 / 1.0.0) — full browser automation via the official @playwright/mcp@0.0.79 (Microsoft), wrapped like http-fetch/firecrawl: package.json pins the package and index.js rewrites argv (--headless --isolated --no-sandbox, plus a process.argv.slice(2) passthrough) and imports the package's cli.js, which self-executes at import time. cli.js is not in the package exports map, so the wrapper resolves it from the exported package.json path.
    • auth: none, requires: ["NODE"]. Runs headless with an isolated in-memory profile: no cookies/login state persisted between sessions (chosen over the default persistent profile — a shared household browser must not accumulate per-user sessions, and a persistent profile also allows only one browser instance at a time).
    • Browser download: the upstream playwright package does NOT download browsers at npm install (verified on 1.63.0-alpha-2026-08-05), and @playwright/mcp 0.0.79 no longer ships the old browser_install tool (the README section is now empty). So the connector's package.json carries a postinstall hook — node node_modules/@playwright/mcp/cli.js install-browser chromium — which downloads Chromium + headless shell + ffmpeg only (~350 MB; a bare install-browser would also fetch Firefox and WebKit). Verified on a cold directory: npm install --omit=dev runs the hook and the browser launches.
    • verify.js (30s) resolves playwright-core relative to @playwright/mcp (it is a transitive dep, not declared by the connector's own package.json) and launches a real headless Chromium on about:blank — catches the two real failure modes (binary missing, system libraries missing on slim hosts) before the activation is saved.
    • Default tool set = 24 tools (no --caps extras); all get display_name in tools[] because @playwright/mcp does not emit MCP title fields in tools/list (the "Title:" lines in its README are not on the wire).
    • ⚠️ Security: the default set includes browser_run_code_unsafe (RCE-equivalent, arbitrary JS in the server process) and browser_evaluate (arbitrary JS in the page); there is no CLI flag to disable individual core tools. Consistent with the mcp_local trust model (guide §3) and declared in the manifest descriptions.
    • Icons: official Playwright SVG (Microsoft catalog), sized 48/96.
    • Tested E2E reproducing skald's path (npm install --omit=dev + node index.js): initialize, tools/list (24 tools), real browser_navigate + browser_snapshot on https://example.com , verify probe ok

2026-08-10

Fixed

  • http-fetch + firecrawl: npx launch was broken (v5 / 1.1.0) — both connectors declared mcp_config: {command: "npx", args: ["-y", "<package>"]} and shipped no code files (only connector.json + icons).

    • npx -y <package> is not expressible in skald. For a type: mcp_local, skald treats args[0] as the name of the file to run, not as an argument: at install it computes script_path = "<id>/" + args[0] and clears args_json (marketplace.rs::install), then global_enable (api/mcp.rs) resolves it to an absolute path and launches <command> <abs>. The real command became npx /…/connectors/http-fetch/-y — a nonexistent path, with -y and the package name lost. The process never answered initialize, so start_server failed.
    • The failure was silent: global_enable still returns HTTP 200 with an error field in the body, so the UI showed the connector as enabled while the runtime had no server. And render_mcp_list (loop_adapters/system.rs) builds the ## MCP servers table from mcp.tools(), i.e. the live runtime state, not the DB → the connector appeared activated and granted to the user but absent from the system context. ⚠️ This combination (200 + error in the body) makes any connector that fails to start invisible in the UI: worth surfacing on the skald side.
    • Fix — two-file wrapper for both: a package.json pinning the upstream package (mcp-fetch-server@1.1.2, firecrawl-mcp@3.23.7) and an index.js that imports it for side effects (the module starts the JSON-RPC loop on stdio at import). mcp_config becomes {command: "node", args: ["index.js"], transport: "stdio"}, i.e. a real local_script: ensure_installed_host runs npm ci --omit=dev || npm install --omit=dev in the connector folder before launch, exactly like whatsapp. No node_modules shipped, no lockfile (like whatsapp).
    • Removed legacy fields launch_command, top-level transport, and dependencies (dependencies is only for the card, as already seen on gmaps; transport belongs inside mcp_config).
    • firecrawl: removed mcp_config.env: {"FIRECRAWL_API_KEY": "{SECRET:FIRECRAWL_API_KEY}"} — inert, same case as gmaps on 2026-08-10: apply_key_placeholder substitutes tokens only in the URL, never in env values. It worked because the admin form sends env and that payload overwrites entry.env_json.
    • firecrawl: added firecrawl_developer_search to tools[] (27 live tools vs 26 declared, verified on 3.23.7); requires ["NODE"]["NODE", "API_KEY"].
    • Re-aligned manifest↔fragment versions to 5 / 1.1.0 / 2026-08-10 for both: they were 2/1.0.1 (manifest) vs 4/1.0.3 (fragment), and skald prefers the manifest — so installed_version stayed at 2 and the "Update available" badge would never have appeared.
    • Host requirement: these are scope: global connectors, they run on the host, not in the container. mcp-fetch-server wants Node ≥18, firecrawl-mcp wants Node ≥22.
    • Tested end-to-end reproducing skald's path (npm ci || npm install + node <abs>/index.js): initialize, tools/list, and a real tools/call, stdout only JSON-RPC, clean stderr
    • Index regenerated with compile.py
    • ⚠️ Applying this to an instance that already has the connector installed is not just an Update. refresh_connector_after_reinstall (skald/accessors.rs) updates only the description of the mcp_global_servers row, then restarts from that row: command and args_json stay the ones snapshotted at the first global_enable, i.e. still npx + /…/connectors/<id>/-y. Procedure: deploy → Update from the marketplace (rewrites script_path in the catalog) → open the connector page and re-save the config, the only call that recomputes command/args and runs ensure_installed_host. Same care already noted for gmaps. Whether the refresh should also re-derive command/args is open for evaluation on the skald side.
  • gmaps: missing dependency install + verify wired (v6 / 1.1.0)

    • Added requirements.txt (googlemaps>=4.10.0) — it was the only python connector without one. Dependencies were declared in the manifest dependencies field, which skald uses only for the card: ensure_installed_host looks exclusively at requirements.txt / package.json. Result: empty .pydeps and logs full of No module named 'googlemaps', with the server still answering tools/list (→ connected — 6 tool(s) on a broken connector).
    • Wired the verify (python3 verify.py, 20s): verify.py was shipped but the manifest had no verify block, and skald reads verify_command only from there. Now an activation with broken dependencies fails visibly instead of starting silently.
    • verify.py puts .pydeps on sys.path: skald sets PYTHONPATH only for the server process (global_row_spec), while verify runs as sh -c "python3 verify.py" without it. Without this line, verify would fail with "Missing dependency" even on a correctly installed connector, disabling the row. ⚠️ Same latent risk for every connector with a verify that imports non-stdlib dependencies (gcal in container): to be checked.
    • Removed mcp_config.env: {"GOOGLE_MAPS_API_KEY": "{SECRET:…}"} (introduced 2026-07-23): inert. apply_key_placeholder substitutes {SECRET:}/{ENV:} tokens only in the URL, never in env values. It worked because the admin form sends env and that payload overwrites entry.env_json; with an empty form the process would have received the literal string. ⚠️ The spec in this file and in CLAUDE.md says the opposite — either fix the spec, or extend the substitution to env values on the skald side.
    • Re-aligned manifest↔fragment versions to 6 / 1.1.0 / 2026-08-10: they were 2/1.0.1 vs 5/1.0.4, and skald prefers the manifest (manifest.version.or(entry.version)) — so installed_version stayed at 2 and the "Update available" badge would never have appeared.
    • requires: ENVAPI_KEY; server error messages cleaned of references to secrets/gmaps_api_key.txt (deprecated path).
    • Index regenerated with compile.py

2026-08-07

Added

  • New connector: LinkedIn (mcp_local, scope user): server.py + session.py + verify.py + PNG icons
  • Added to connectors/index.json, index regenerated with compile.py (17 connectors total)
  • .gitignore updated to ignore .claude/
  • Deploy to connectors.skaldagent.net via skaldserver alias (192.168.1.100, LAN — no Tailscale)

2026-07-23

Changed

  • gmaps: env var injection fix — added mcp_config.env in connector.json to inject GOOGLE_MAPS_API_KEY into the MCP process. The connector was declared as delivery: env but without mcp_config.env Skald could not pass the variable to the Python process. Version bump: fragment 4→5, connector 1→2. Index regenerated with compile.py
  • Context7 icon update (PNG) — replaced Context7 icons from SVG to PNG (new icon provided by the user): icon_sm.png — 48×48 (2.7 KB), icon_lg.png — 96×96 (4.5 KB). Old SVGs removed, references updated in fragment.json and connector.json. Version bump: fragment 3→4, connector 1→2. Index regenerated with compile.py
  • SerpAPI Flights icon update (PNG) — replaced SerpAPI Flights icons from SVG to PNG: icon_sm.png — 48×48 (2.9 KB), icon_lg.png — 96×96 (6.8 KB). Old SVGs removed, references updated in fragment.json and connector.json. Version bump: fragment 4→5, connector 2→3. Index regenerated with compile.py