From 955b1ba069558af09f7dafb895fd353eb3b48cf4 Mon Sep 17 00:00:00 2001 From: xavix-yo Date: Tue, 21 Jul 2026 23:43:24 +0100 Subject: [PATCH] feat: friendly tool names per MCP title field or manifest - Aggiunto campo 'title' a tools/list in tutti gli script MCP locali (Gmail, Gcal, Drive, Email, SSH, Weather, Wikipedia, WhatsApp) - Aggiunto tools[]/display_name nel manifest per connector remoti/package esterni (Firecrawl, HTTP Fetch, Exa, Tavily, SerpAPI Flights) - Documentata convenzione e resolution order in SKALD.md - Aggiornata manifest_guide.md per tools[] in connectors.json - Bumped version e sha256 per tutti i 13 connector --- SKALD.md | 17 +- connectors/connectors.json | 276 +++++++++++++++---- connectors/drive/connector.json | 10 +- connectors/drive/drive_mcp_server.py | 21 +- connectors/email/connector.json | 8 +- connectors/email/email_mcp_server.py | 10 + connectors/exa/connector.json | 22 +- connectors/firecrawl/connector.json | 114 +++++++- connectors/gcal/connector.json | 8 +- connectors/gcal/gcal_mcp_server.py | 8 + connectors/gmail/connector.json | 8 +- connectors/gmail/gmail_mcp_server.py | 10 + connectors/http-fetch/connector.json | 34 ++- connectors/serpapi-flights/connector.json | 16 +- connectors/ssh/connector.json | 8 +- connectors/ssh/ssh_mcp_server.py | 13 + connectors/tavily/connector.json | 30 +- connectors/weather/connector.json | 12 +- connectors/weather/weather_mcp_server.py | 4 + connectors/whatsapp/connector.json | 8 +- connectors/whatsapp/index.js | 7 + connectors/wikipedia/connector.json | 12 +- connectors/wikipedia/wikipedia_mcp_server.py | 2 + 23 files changed, 536 insertions(+), 122 deletions(-) diff --git a/SKALD.md b/SKALD.md index 8569588..d0bcf43 100644 --- a/SKALD.md +++ b/SKALD.md @@ -1,6 +1,6 @@ # Skald Connectors Marketplace -_Updated: 2026-07-19_ +_Updated: 2026-07-21_ **Remote**: `https://git.skaldagent.net/dguiducci/skald-connectors.git` **Live**: `https://connectors.skaldagent.net/` @@ -33,6 +33,21 @@ 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). +## Friendly tool names (2026-07-21) + +Ogni tool MCP deve esporre un nome friendly per la UI di Skald. Due modi, in ordine di preferenza: + +1. **Via script MCP (preferito)** — aggiungere `"title": "Friendly Name"` nella definizione di ogni tool dentro `tools/list`. Funziona per tutti gli script locali (Python/Node) che controlliamo. +2. **Via manifest (fallback)** — aggiungere `"tools": [{"name": "...", "display_name": "..."}]` in `connector.json` **e** in `connectors.json`. Usato solo per connector remoti o package esterni (es. `npx -y firecrawl-mcp`). + +**Ordine di risoluzione** (Skald li prova in quest'ordine): +1. `tools[].display_name` dal manifest +2. `title` dal `tools/list` dell'MCP server +3. Prettify automatico del nome raw (`send_message` → "Send Message") + +Stato attuale (2026-07-21): tutti i 13 connector del marketplace hanno `title` nello script o `tools[]` nel manifest. + + ## Struttura directory ``` diff --git a/connectors/connectors.json b/connectors/connectors.json index b6d2138..8543514 100644 --- a/connectors/connectors.json +++ b/connectors/connectors.json @@ -28,9 +28,9 @@ ] }, "folder": "gmail", - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19", + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21", "files": [ { "path": "connector.json", @@ -39,7 +39,7 @@ }, { "path": "gmail_mcp_server.py", - "sha256": "e96568dda3d0198be0a34092458dac2aaafee4a7e282a3fb427923f517e536e3", + "sha256": "4607ec1fee8fcbdb81619286900e44e4c04a479156f8959f553dce28b69bba66", "size": 47789 }, { @@ -85,9 +85,9 @@ ] }, "folder": "gcal", - "version": 1, - "version_string": "0.3.0", - "version_release_date": "2026-07-19", + "version": 2, + "version_string": "0.3.1", + "version_release_date": "2026-07-21", "files": [ { "path": "connector.json", @@ -96,7 +96,7 @@ }, { "path": "gcal_mcp_server.py", - "sha256": "c526751c8891a8d97ba37d14da282d223be7cd061eb67c76cea6a12672921db0", + "sha256": "a4a58a04b1df28fc45ea3bcdc5837ba00d740a9bae972a67c6c690dcd2c21bbe", "size": 38177 }, { @@ -149,9 +149,9 @@ ] }, "folder": "drive", - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19", + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21", "files": [ { "path": "connector.json", @@ -160,7 +160,7 @@ }, { "path": "drive_mcp_server.py", - "sha256": "d8cd3d96abebb2a2ab333c5489eb07d28d906c21a0aeaa7551dee49bdbebc527", + "sha256": "422b63e55b5d33aba0650cccd29def007dd4fd8d25497a94b051b2ba7eec3e44", "size": 19971 }, { @@ -207,9 +207,9 @@ "type": "password" }, "folder": "email", - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19", + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21", "files": [ { "path": "connector.json", @@ -218,7 +218,7 @@ }, { "path": "email_mcp_server.py", - "sha256": "e8e0efc7d07be0d743f73ae80b15c924a763e57fc19000b1ef1e98237465da0f", + "sha256": "3018e44460f10f41e303bfd2fbca0eee4f1f0ad58a13c5c480e28e4d6be126c3", "size": 54522 }, { @@ -256,13 +256,13 @@ "type": "api_key" }, "folder": "exa", - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19", + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21", "files": [ { "path": "connector.json", - "sha256": "65d979906e37daee32c0f9e53f29b62a2003f44c8c3ae7899c0bdab78e4c78c0", + "sha256": "7f5cd8fbd8aaa9e65b6b90411e3d1121e1d8be8d6c56a49930b1ccf83cd5c46c", "size": 1409 }, { @@ -280,6 +280,16 @@ "sha256": "a1b698035af2cb146dccd57f992155359d55a48bc85802e2a02e8148dcec1558", "size": 3730 } + ], + "tools": [ + { + "name": "web_search_exa", + "display_name": "Web Search" + }, + { + "name": "web_fetch_exa", + "display_name": "Web Fetch" + } ] }, { @@ -306,13 +316,13 @@ "type": "api_key" }, "folder": "firecrawl", - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19", + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21", "files": [ { "path": "connector.json", - "sha256": "39002ac49f6ebd93aabb9f80c1fa33c0298344f5e3a734151a6ea1e4d00639b9", + "sha256": "550dcee80d84833d4c0f9aa305096544dcff2f300a206120e640e0741c71ed89", "size": 2600 }, { @@ -325,6 +335,112 @@ "sha256": "3a4be30d4c16ce93a1d132e063dfdffb8bd27b6c97715c9f3b12414439aaeb01", "size": 6858 } + ], + "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" + } ] }, { @@ -351,13 +467,13 @@ "type": "none" }, "folder": "http-fetch", - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19", + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21", "files": [ { "path": "connector.json", - "sha256": "67d44752fddca27f6093193264963c6658d66ce36917591eba7bde9e904389f2", + "sha256": "82dd6405f0b2cebd5361a47f04c3366b64958e9fd0a5386d1b48997acc4c632a", "size": 1259 }, { @@ -370,6 +486,32 @@ "sha256": "3e5496d949062678ae44cd74430b29232bbfe28a7600038deb3159c4b26adee1", "size": 382 } + ], + "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" + } ] }, { @@ -391,13 +533,13 @@ "type": "api_key" }, "folder": "serpapi-flights", - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19", + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21", "files": [ { "path": "connector.json", - "sha256": "7c2bd621f461001483787036c5692021f34f3838b90e215be00cae470103526a", + "sha256": "14793ce1dd53440203f451d4fd43a24daa104403849c7d72dea8b36773ee72e2", "size": 1352 }, { @@ -415,6 +557,12 @@ "sha256": "5a2ffa7f2502fd27dc0027395db2c863bb544c8de1eef8131a5228d87402c8e6", "size": 574 } + ], + "tools": [ + { + "name": "serpapi_search_flights", + "display_name": "Search Flights" + } ] }, { @@ -440,9 +588,9 @@ "type": "none" }, "folder": "ssh", - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19", + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21", "files": [ { "path": "connector.json", @@ -451,7 +599,7 @@ }, { "path": "ssh_mcp_server.py", - "sha256": "fbd7aa9dfad0da57f4b3d9d437c76fd978145c8364ed5fdfdfc3ba7ccfaf117b", + "sha256": "68509094a35578ffaaf357e13b55e1bfcf397f16a3b993719c4c3b97ab2dc798", "size": 49764 }, { @@ -488,13 +636,13 @@ "type": "api_key" }, "folder": "tavily", - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19", + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21", "files": [ { "path": "connector.json", - "sha256": "40f191b9112f6e05e906836ead22db4c96a73c89a68db9c0ac5820473edcaad0", + "sha256": "c5ca9a7c848c0e55a8a55e482028e8607bd8adea3d94f25e210fce9833563e87", "size": 1072 }, { @@ -512,6 +660,28 @@ "sha256": "35a4f3b518c79363893c0438b1932b68e2dc5b4b61303037984488f6967b73a4", "size": 2057 } + ], + "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" + } ] }, { @@ -534,13 +704,13 @@ "type": "none" }, "folder": "weather", - "version": 3, - "version_string": "3.0.0", - "version_release_date": "2026-07-19", + "version": 4, + "version_string": "3.0.1", + "version_release_date": "2026-07-21", "files": [ { "path": "weather_mcp_server.py", - "sha256": "5927333dee45ec5db1134034ee5af51d9e2fd95b6d128834de9a882e499b0ce4", + "sha256": "2b1c40f927d3095806504ae3c82ace156e6079294cf15c6c2c47df1422068185", "size": 29865 }, { @@ -587,9 +757,9 @@ "type": "qr" }, "folder": "whatsapp", - "version": 2, - "version_string": "2.0.2", - "version_release_date": "2026-07-19", + "version": 3, + "version_string": "2.0.3", + "version_release_date": "2026-07-21", "files": [ { "path": "connector.json", @@ -598,7 +768,7 @@ }, { "path": "index.js", - "sha256": "1627f115a1bfb5a954abd412dba76c38f7202640258d3cbc08c313c00446a14a", + "sha256": "0bfaa3c5449f22a4e2c4c99c6e9402bb24651647eca9a36dbd7a639c95a6bfd6", "size": 21668 }, { @@ -638,13 +808,13 @@ "type": "none" }, "folder": "wikipedia", - "version": 3, - "version_string": "3.0.0", - "version_release_date": "2026-07-19", + "version": 4, + "version_string": "3.0.1", + "version_release_date": "2026-07-21", "files": [ { "path": "wikipedia_mcp_server.py", - "sha256": "e8dcf08a23c2b61c366acc1f46ca2d18332438b8a1d832d46d7b680641b68c59", + "sha256": "ce9feed6a8b0a29ed405dbfe90743816d7f0714f1b580671bac722112bb54146", "size": 12110 }, { @@ -670,4 +840,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/connectors/drive/connector.json b/connectors/drive/connector.json index 25ed6d3..4f8d295 100644 --- a/connectors/drive/connector.json +++ b/connectors/drive/connector.json @@ -1,9 +1,9 @@ { "id": "drive", "name": "Google Drive", - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19", + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21", "type": "mcp_local", "scope": "user", "launch_command": "python3 drive_mcp_server.py", @@ -31,7 +31,7 @@ "docs": [ { "lang": "en", - "description": "Full Google Drive integration: list, search, upload, download, delete files and folders. Uses the same OAuth pattern as Gmail and Google Calendar — your Google Drive credentials are managed by Skald.", + "description": "Full Google Drive integration: list, search, upload, download, delete files and folders. Uses the same OAuth pattern as Gmail and Google Calendar \u2014 your Google Drive credentials are managed by Skald.", "llm_short_description": "Google Drive MCP server: list_files, search_files, upload_file, download_file, delete_file, create_folder, get_file_metadata. Manages files and folders on the user's Google Drive. Requires OAuth setup." } ], @@ -60,4 +60,4 @@ "homepage": "https://drive.google.com", "icon_small": "icon_sm.svg", "icon_large": "icon_lg.svg" -} +} \ No newline at end of file diff --git a/connectors/drive/drive_mcp_server.py b/connectors/drive/drive_mcp_server.py index 4f43ed4..d79e88b 100644 --- a/connectors/drive/drive_mcp_server.py +++ b/connectors/drive/drive_mcp_server.py @@ -318,7 +318,7 @@ def _status() -> dict: # ── Tool registry ────────────────────────────────────────────────────────── -TOOLS: dict[str, tuple[Callable, str, dict]] = { +TOOLS: dict[str, tuple[Callable, str, dict, str]] = { "status": ( _status, "Check if the Drive API is reachable and credentials are valid.", @@ -327,7 +327,7 @@ TOOLS: dict[str, tuple[Callable, str, dict]] = { "properties": {}, "required": [], }, - ), + "Status"), "list_files": ( _list_files, "List files in a folder (or root if no folder_id given). Returns paginated results.", @@ -352,7 +352,7 @@ TOOLS: dict[str, tuple[Callable, str, dict]] = { }, "required": [], }, - ), + "List Files"), "search_files": ( _search_files, "Search files across Drive by name or content.", @@ -371,7 +371,7 @@ TOOLS: dict[str, tuple[Callable, str, dict]] = { }, "required": ["query"], }, - ), + "Search Files"), "get_file_metadata": ( _get_file_metadata, "Get detailed metadata for a specific file by ID.", @@ -385,7 +385,7 @@ TOOLS: dict[str, tuple[Callable, str, dict]] = { }, "required": ["file_id"], }, - ), + "Get File Metadata"), "upload_file": ( _upload_file, "Upload a local file to Google Drive.", @@ -409,7 +409,7 @@ TOOLS: dict[str, tuple[Callable, str, dict]] = { }, "required": ["local_path"], }, - ), + "Upload File"), "download_file": ( _download_file, "Download a file from Drive. Returns base64 content if no output_path, or saves to disk.", @@ -428,7 +428,7 @@ TOOLS: dict[str, tuple[Callable, str, dict]] = { }, "required": ["file_id"], }, - ), + "Download File"), "delete_file": ( _delete_file, "Permanently delete a file from Google Drive.", @@ -442,7 +442,7 @@ TOOLS: dict[str, tuple[Callable, str, dict]] = { }, "required": ["file_id"], }, - ), + "Delete File"), "create_folder": ( _create_folder, "Create a new folder in Google Drive.", @@ -461,7 +461,7 @@ TOOLS: dict[str, tuple[Callable, str, dict]] = { }, "required": ["name"], }, - ), + "Create Folder"), } @@ -496,10 +496,11 @@ def _handle_request(req: dict) -> None: # List available tools if method == "tools/list": tool_list = [] - for name, (fn, desc, schema) in sorted(TOOLS.items()): + for name, (fn, desc, schema, title) in sorted(TOOLS.items()): tool_list.append({ "name": name, "description": desc, + "title": title, "inputSchema": schema, }) _send_response(rid, {"tools": tool_list}) diff --git a/connectors/email/connector.json b/connectors/email/connector.json index 429e94b..58cf4fd 100644 --- a/connectors/email/connector.json +++ b/connectors/email/connector.json @@ -125,7 +125,7 @@ "auth": { "type": "password" }, - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19" -} + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21" +} \ No newline at end of file diff --git a/connectors/email/email_mcp_server.py b/connectors/email/email_mcp_server.py index 73630ab..5f724d9 100644 --- a/connectors/email/email_mcp_server.py +++ b/connectors/email/email_mcp_server.py @@ -1152,6 +1152,7 @@ def _email_download_attachments(args: dict) -> str: TOOLS = [ { "name": "status", + "title": "Status", "description": ( "Self-check that the email integration is operational: verifies IMAP and SMTP both " "authenticate with the configured credentials. Call this first whenever another email " @@ -1161,6 +1162,7 @@ TOOLS = [ }, { "name": "list_messages", + "title": "List Messages", "description": ( "List messages in a folder (default INBOX), newest first. The optional 'query' supports " "a Gmail-like mini-syntax: from:x, to:x, subject:x, since:YYYY-MM-DD, before:YYYY-MM-DD, " @@ -1180,6 +1182,7 @@ TOOLS = [ }, { "name": "get_message", + "title": "Get Message", "description": ( "Get the full content of a message by its UID, including body text (truncated at 10000 " "chars; HTML-only emails are converted to readable text). Attachment filenames are " @@ -1198,6 +1201,7 @@ TOOLS = [ }, { "name": "get_thread", + "title": "Get Thread", "description": ( "Best-effort thread reconstruction for a message UID: gathers messages in the same " "folder that share the Message-ID reference chain (In-Reply-To/References) or the same " @@ -1214,11 +1218,13 @@ TOOLS = [ }, { "name": "list_folders", + "title": "List Folders", "description": "List all IMAP folders/mailboxes with total and unread message counts. Use to discover folder names for the other tools.", "inputSchema": {"type": "object", "properties": {}}, }, { "name": "modify_message", + "title": "Modify Message", "description": ( "Change a message's state: add/remove flags, mark read/unread, move to another folder, " "archive or delete. Friendly flag names: 'read'/'seen', 'flagged'/'starred', 'answered', " @@ -1243,6 +1249,7 @@ TOOLS = [ }, { "name": "send_message", + "title": "Send Message", "description": ( "Send an email via SMTP. Supports in-thread replies by passing in_reply_to (the " "Message-ID of the message being replied to, with or without angle brackets), which sets " @@ -1267,11 +1274,13 @@ TOOLS = [ }, { "name": "get_profile", + "title": "Get Profile", "description": "Show the configured account: username, From address, IMAP/SMTP servers, folder count, and INBOX total/unread.", "inputSchema": {"type": "object", "properties": {}}, }, { "name": "create_folder", + "title": "Create Folder", "description": "Create a new IMAP folder/mailbox. Fails if it already exists.", "inputSchema": { "type": "object", @@ -1283,6 +1292,7 @@ TOOLS = [ }, { "name": "download_attachments", + "title": "Download Attachments", "description": ( "Download all attachments from a message to a local folder (default data/email_attachments/). " "Returns the absolute path and size of each saved file. Pass 'folder' if the message is not in INBOX." diff --git a/connectors/exa/connector.json b/connectors/exa/connector.json index ae21c0d..31d15be 100644 --- a/connectors/exa/connector.json +++ b/connectors/exa/connector.json @@ -1,9 +1,9 @@ { "id": "exa", "name": "Exa", - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19", + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21", "type": "mcp_remote", "scope": "global", "tags": [ @@ -15,7 +15,7 @@ "docs": [ { "lang": "en", - "description": "AI-powered web search, content extraction, and embeddings via Exa's neural search engine. Perfect for deep research, finding specific information, and analyzing page content. Works without an API key (free rate-limited tier) — add your own key for higher limits.", + "description": "AI-powered web search, content extraction, and embeddings via Exa's neural search engine. Perfect for deep research, finding specific information, and analyzing page content. Works without an API key (free rate-limited tier) \u2014 add your own key for higher limits.", "llm_short_description": "Search the web and extract page content using Exa's neural search engine. Tools: web_search_exa, web_fetch_exa." } ], @@ -42,5 +42,15 @@ }, "homepage": "https://exa.ai", "icon_small": "icon_sm.png", - "icon_large": "icon_lg.png" -} + "icon_large": "icon_lg.png", + "tools": [ + { + "name": "web_search_exa", + "display_name": "Web Search" + }, + { + "name": "web_fetch_exa", + "display_name": "Web Fetch" + } + ] +} \ No newline at end of file diff --git a/connectors/firecrawl/connector.json b/connectors/firecrawl/connector.json index bcf2d29..9712e48 100644 --- a/connectors/firecrawl/connector.json +++ b/connectors/firecrawl/connector.json @@ -60,7 +60,113 @@ "browser", "research" ], - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19" -} + "version": 2, + "version_string": "1.0.1", + "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" + } + ] +} \ No newline at end of file diff --git a/connectors/gcal/connector.json b/connectors/gcal/connector.json index 08b10f8..d9a7f9e 100644 --- a/connectors/gcal/connector.json +++ b/connectors/gcal/connector.json @@ -54,7 +54,7 @@ "homepage": "https://calendar.google.com", "icon_small": "icon_sm.svg", "icon_large": "icon_lg.svg", - "version": 1, - "version_string": "0.3.0", - "version_release_date": "2026-07-19" -} + "version": 2, + "version_string": "0.3.1", + "version_release_date": "2026-07-21" +} \ No newline at end of file diff --git a/connectors/gcal/gcal_mcp_server.py b/connectors/gcal/gcal_mcp_server.py index 72f266f..a84bd59 100755 --- a/connectors/gcal/gcal_mcp_server.py +++ b/connectors/gcal/gcal_mcp_server.py @@ -684,6 +684,7 @@ TOOLS = [ # ── Self-check ───────────────────────────────────────────────────────────── { "name": "status", + "title": "Status", "description": ( "Self-check that the Google Calendar integration is operational: verifies the OAuth " "credentials load, the access token refreshes when needed, and the Calendar API responds, " @@ -695,11 +696,13 @@ TOOLS = [ # ── Read-only ────────────────────────────────────────────────────────────── { "name": "list_calendars", + "title": "List Calendars", "description": "Lists all calendars accessible to the authenticated user. Use it to discover calendar_id values to pass to the other gcal tools.", "inputSchema": {"type": "object", "properties": {}}, }, { "name": "list_events", + "title": "List Events", "description": ( "Lists calendar events from a given calendar, ordered chronologically. " "If time_min is omitted, defaults to NOW (current UTC time) — so you never get past events by accident. " @@ -738,6 +741,7 @@ TOOLS = [ }, { "name": "get_event", + "title": "Get Event", "description": "Returns a single calendar event by ID, including attendees with their RSVP status.", "inputSchema": { "type": "object", @@ -757,6 +761,7 @@ TOOLS = [ # ── Write ────────────────────────────────────────────────────────────────── { "name": "create_event", + "title": "Create Event", "description": ( "Creates a new event in the specified calendar and returns its ID + HTML link. " "Use ISO 8601 for start/end (e.g. '2025-06-15T10:00:00' for timed events, " @@ -814,6 +819,7 @@ TOOLS = [ }, { "name": "update_event", + "title": "Update Event", "description": ( "Updates an existing event. Only fields provided are changed; omitted fields keep their " "current values. Returns the updated event ID." @@ -854,6 +860,7 @@ TOOLS = [ }, { "name": "delete_event", + "title": "Delete Event", "description": "Permanently deletes a calendar event. Irreversible.", "inputSchema": { "type": "object", @@ -872,6 +879,7 @@ TOOLS = [ }, { "name": "respond_to_event", + "title": "Respond to Event", "description": "Set your RSVP / attendance response (accepted, declined, tentative, needsAction) for a calendar event.", "inputSchema": { "type": "object", diff --git a/connectors/gmail/connector.json b/connectors/gmail/connector.json index 61b6f70..ce2980e 100644 --- a/connectors/gmail/connector.json +++ b/connectors/gmail/connector.json @@ -51,7 +51,7 @@ "env": "GMAIL_CREDS_JSON" } }, - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19" -} + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21" +} \ No newline at end of file diff --git a/connectors/gmail/gmail_mcp_server.py b/connectors/gmail/gmail_mcp_server.py index 7822fbf..aa77a94 100644 --- a/connectors/gmail/gmail_mcp_server.py +++ b/connectors/gmail/gmail_mcp_server.py @@ -936,6 +936,7 @@ def _gmail_download_attachments(args: dict) -> str: TOOLS = [ { "name": "status", + "title": "Status", "description": ( "Self-check that the Google Gmail integration is operational: verifies the OAuth " "credentials load, the access token refreshes when needed, and the Gmail API responds, " @@ -946,6 +947,7 @@ TOOLS = [ }, { "name": "list_messages", + "title": "List Messages", "description": ( "List Gmail messages with optional query and label filter. Returns summaries with " "subject, sender, date, message ID and thread ID. Use Gmail search syntax in 'query' " @@ -977,6 +979,7 @@ TOOLS = [ }, { "name": "get_message", + "title": "Get Message", "description": ( "Get full content of a Gmail message by ID, including body text (truncated at 10000 " "chars). HTML-only emails are converted to readable text, and any attachment filenames " @@ -999,6 +1002,7 @@ TOOLS = [ }, { "name": "get_thread", + "title": "Get Thread", "description": "Get all messages in a thread by thread ID, newest last.", "inputSchema": { "type": "object", @@ -1013,6 +1017,7 @@ TOOLS = [ }, { "name": "list_labels", + "title": "List Labels", "description": "List all Gmail labels/folders/categories with total and unread message counts. Use to resolve label IDs for modify_message.", "inputSchema": { "type": "object", @@ -1021,6 +1026,7 @@ TOOLS = [ }, { "name": "modify_message", + "title": "Modify Message", "description": ( "Modify message labels: mark read, archive, star, etc. Use label IDs like 'UNREAD', " "'STARRED', 'INBOX'. remove_labels=['UNREAD'] marks as read; remove_labels=['INBOX'] " @@ -1049,6 +1055,7 @@ TOOLS = [ }, { "name": "send_message", + "title": "Send Message", "description": ( "Send an email via Gmail. Supports in-thread replies via the optional in_reply_to " "(message ID) and thread_id parameters. For a reply, pass both for correct threading " @@ -1103,6 +1110,7 @@ TOOLS = [ }, { "name": "get_profile", + "title": "Get Profile", "description": "Get Gmail profile info: email address, total message/thread count, current history ID.", "inputSchema": { "type": "object", @@ -1111,6 +1119,7 @@ TOOLS = [ }, { "name": "create_label", + "title": "Create Label", "description": "Create a new Gmail label/folder. Returns the new label ID. Fails if a label with the same name already exists.", "inputSchema": { "type": "object", @@ -1135,6 +1144,7 @@ TOOLS = [ }, { "name": "download_attachments", + "title": "Download Attachments", "description": ( "Download all attachments from a Gmail message to a local folder. " "Defaults to data/gmail_attachments/ (served via /data/... in the frontend). " diff --git a/connectors/http-fetch/connector.json b/connectors/http-fetch/connector.json index 9936e72..0e4b197 100644 --- a/connectors/http-fetch/connector.json +++ b/connectors/http-fetch/connector.json @@ -42,7 +42,33 @@ "scraping", "youtube" ], - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19" -} + "version": 2, + "version_string": "1.0.1", + "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" + } + ] +} \ No newline at end of file diff --git a/connectors/serpapi-flights/connector.json b/connectors/serpapi-flights/connector.json index 6490395..50a6736 100644 --- a/connectors/serpapi-flights/connector.json +++ b/connectors/serpapi-flights/connector.json @@ -1,9 +1,9 @@ { "id": "serpapi-flights", "name": "SerpAPI Flights", - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19", + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21", "type": "mcp_remote", "scope": "global", "tags": [ @@ -43,5 +43,11 @@ }, "homepage": "https://serpapi.com/google-flights-api", "icon_small": "icon_sm.svg", - "icon_large": "icon_lg.svg" -} + "icon_large": "icon_lg.svg", + "tools": [ + { + "name": "serpapi_search_flights", + "display_name": "Search Flights" + } + ] +} \ No newline at end of file diff --git a/connectors/ssh/connector.json b/connectors/ssh/connector.json index 67ac4c2..aabd580 100644 --- a/connectors/ssh/connector.json +++ b/connectors/ssh/connector.json @@ -109,7 +109,7 @@ "auth": { "type": "none" }, - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19" -} + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21" +} \ No newline at end of file diff --git a/connectors/ssh/ssh_mcp_server.py b/connectors/ssh/ssh_mcp_server.py index 9a1585f..59df2d5 100644 --- a/connectors/ssh/ssh_mcp_server.py +++ b/connectors/ssh/ssh_mcp_server.py @@ -1044,11 +1044,13 @@ _SFTP_NOTE = ( TOOLS = [ { "name": "list_aliases", + "title": "List Aliases", "description": "List configured SSH host aliases (never reveals keys or sudo passwords).", "inputSchema": {"type": "object", "properties": {}}, }, { "name": "add_alias", + "title": "Add Alias", "description": "Register or update an SSH host alias. Login via SSH key/agent (default) or login password asked on demand via elicitation.", "inputSchema": { "type": "object", @@ -1070,11 +1072,13 @@ TOOLS = [ }, { "name": "remove_alias", + "title": "Remove Alias", "description": "Remove a host alias and close its pooled connection.", "inputSchema": {"type": "object", "properties": {"alias": _ALIAS}, "required": ["alias"]}, }, { "name": "read_file", + "title": "Read File", "description": "Read a remote file with 1-based line numbers (same format as the local read_file)." + _SFTP_NOTE, "inputSchema": { "type": "object", @@ -1090,6 +1094,7 @@ TOOLS = [ }, { "name": "list_files", + "title": "List Files", "description": "List files/dirs under a remote path; returns a JSON array of relative paths (same as local list_files).", "inputSchema": { "type": "object", @@ -1104,6 +1109,7 @@ TOOLS = [ }, { "name": "grep_files", + "title": "Grep Files", "description": "Search a remote path with a regex; output matches the local grep_files (uses remote grep -E).", "inputSchema": { "type": "object", @@ -1122,6 +1128,7 @@ TOOLS = [ }, { "name": "edit_file", + "title": "Edit File", "description": "Find & replace in a remote file (atomic). `old` must match exactly once unless replace_all." + _SFTP_NOTE, "inputSchema": { "type": "object", @@ -1137,6 +1144,7 @@ TOOLS = [ }, { "name": "replace_lines", + "title": "Replace Lines", "description": "Replace a 1-based inclusive line range in a remote file (atomic)." + _SFTP_NOTE, "inputSchema": { "type": "object", @@ -1152,6 +1160,7 @@ TOOLS = [ }, { "name": "exec", + "title": "Execute Command", "description": "Run a command on the remote host. Set sudo=true to run via sudo (method per alias).", "inputSchema": { "type": "object", @@ -1167,6 +1176,7 @@ TOOLS = [ }, { "name": "upload", + "title": "Upload File", "description": "Upload a local file or directory (recursive) to the remote host via SFTP." + _SFTP_NOTE, "inputSchema": { "type": "object", @@ -1180,6 +1190,7 @@ TOOLS = [ }, { "name": "download", + "title": "Download File", "description": "Download a remote file or directory (recursive) to the local host via SFTP.", "inputSchema": { "type": "object", @@ -1193,11 +1204,13 @@ TOOLS = [ }, { "name": "sysinfo", + "title": "System Info", "description": "Report OS, kernel, CPU count, RAM and root-disk usage, and uptime.", "inputSchema": {"type": "object", "properties": {"alias": _ALIAS}, "required": ["alias"]}, }, { "name": "systemd", + "title": "Manage Systemd Service", "description": "Manage a systemd service (status/start/stop/restart/reload/enable/disable) + last 10 journal lines. Mutating actions use sudo.", "inputSchema": { "type": "object", diff --git a/connectors/tavily/connector.json b/connectors/tavily/connector.json index 1ff1db2..c6a54a8 100644 --- a/connectors/tavily/connector.json +++ b/connectors/tavily/connector.json @@ -39,7 +39,29 @@ "mcp", "remote" ], - "version": 1, - "version_string": "1.0.0", - "version_release_date": "2026-07-19" -} + "version": 2, + "version_string": "1.0.1", + "version_release_date": "2026-07-21", + "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" + } + ] +} \ No newline at end of file diff --git a/connectors/weather/connector.json b/connectors/weather/connector.json index c3df84a..edea71c 100644 --- a/connectors/weather/connector.json +++ b/connectors/weather/connector.json @@ -25,7 +25,9 @@ "icon_small": "icon_sm.svg", "icon_large": "icon_lg.svg", "scope": "global", - "requires": ["PYTHON"], + "requires": [ + "PYTHON" + ], "tags": [ "weather", "mcp", @@ -40,7 +42,7 @@ "weather_mcp_server.py" ] }, - "version": 3, - "version_string": "3.0.0", - "version_release_date": "2026-07-19" -} + "version": 4, + "version_string": "3.0.1", + "version_release_date": "2026-07-21" +} \ No newline at end of file diff --git a/connectors/weather/weather_mcp_server.py b/connectors/weather/weather_mcp_server.py index 9b5c64a..8211522 100644 --- a/connectors/weather/weather_mcp_server.py +++ b/connectors/weather/weather_mcp_server.py @@ -544,6 +544,7 @@ def _weather_air_quality(args: dict[str, Any]) -> str | dict[str, Any]: TOOLS = [ { "name": "status", + "title": "Status", "description": ( "Self-check that the Weather integration is operational: verifies the " "Open-Meteo Geocoding and Forecast APIs are reachable by performing one " @@ -555,6 +556,7 @@ TOOLS = [ }, { "name": "get_current_weather", + "title": "Get Current Weather", "description": ( "Get current weather conditions for any city worldwide. " "Returns temperature, feels-like, humidity, wind (speed/direction/gusts), " @@ -579,6 +581,7 @@ TOOLS = [ }, { "name": "get_forecast", + "title": "Get Forecast", "description": ( "Get multi-day weather forecast for any city worldwide. " "Returns daily min/max temperature (and feels-like), conditions, rain probability, " @@ -607,6 +610,7 @@ TOOLS = [ }, { "name": "get_air_quality", + "title": "Get Air Quality", "description": ( "Get current air quality for any city worldwide. " "Returns European and US AQI indices, plus detailed pollutant levels: " diff --git a/connectors/whatsapp/connector.json b/connectors/whatsapp/connector.json index c7b1d89..c00d99d 100644 --- a/connectors/whatsapp/connector.json +++ b/connectors/whatsapp/connector.json @@ -44,7 +44,7 @@ "homepage": "https://github.com/WhiskeySockets/Baileys", "icon_small": "icon_sm.png", "icon_large": "icon_lg.png", - "version": 2, - "version_string": "2.0.2", - "version_release_date": "2026-07-19" -} + "version": 3, + "version_string": "2.0.3", + "version_release_date": "2026-07-21" +} \ No newline at end of file diff --git a/connectors/whatsapp/index.js b/connectors/whatsapp/index.js index 638a993..08b703a 100644 --- a/connectors/whatsapp/index.js +++ b/connectors/whatsapp/index.js @@ -363,21 +363,25 @@ async function toolSearchContacts(args) { const TOOLS = [ { name: 'login_status', + title: 'Login Status', description: 'Interactive-login status for this connector (used by the Skald login panel). Returns a JSON object {state, qr, message}: state is connecting|need_scan|ready|logged_out; qr is a data-URL PNG present only while a scan is needed. Safe to poll.', inputSchema: { type: 'object', properties: {} }, }, { name: 'status', + title: 'Status', description: 'WhatsApp connection status as a short human-readable report. Call this first when another WhatsApp tool fails.', inputSchema: { type: 'object', properties: {} }, }, { name: 'logout', + title: 'Logout', description: 'Log out of WhatsApp: end the session, clear the stored credentials, and generate a fresh QR code to link a (possibly different) phone. After calling, the user must scan the new QR in the Skald connector page.', inputSchema: { type: 'object', properties: {} }, }, { name: 'list_chats', + title: 'List Chats', description: 'List recent WhatsApp chats (contacts and groups) with name, ID and unread count. Only chats seen since sign-in / history sync are known.', inputSchema: { type: 'object', @@ -386,6 +390,7 @@ const TOOLS = [ }, { name: 'get_messages', + title: 'Get Messages', description: 'Get buffered messages from a chat. Identify it with EITHER chat_id (from list_chats) OR a phone number with country code for an individual contact. Only messages seen since sign-in are available (no deep history).', inputSchema: { type: 'object', @@ -399,6 +404,7 @@ const TOOLS = [ }, { name: 'send_message', + title: 'Send Message', description: 'Send a WhatsApp text message. Identify the recipient with EITHER chat_id (from list_chats, use for groups) OR a phone number with country code for an individual contact.', inputSchema: { type: 'object', @@ -412,6 +418,7 @@ const TOOLS = [ }, { name: 'search_contacts', + title: 'Search Contacts', description: 'Search known WhatsApp contacts by name or number. Use to find a contact ID to message.', inputSchema: { type: 'object', diff --git a/connectors/wikipedia/connector.json b/connectors/wikipedia/connector.json index 7504b37..7d401ce 100644 --- a/connectors/wikipedia/connector.json +++ b/connectors/wikipedia/connector.json @@ -25,7 +25,9 @@ "icon_small": "icon_sm.svg", "icon_large": "icon_lg.svg", "scope": "global", - "requires": ["PYTHON"], + "requires": [ + "PYTHON" + ], "tags": [ "wikipedia", "mcp", @@ -40,7 +42,7 @@ "wikipedia_mcp_server.py" ] }, - "version": 3, - "version_string": "3.0.0", - "version_release_date": "2026-07-19" -} + "version": 4, + "version_string": "3.0.1", + "version_release_date": "2026-07-21" +} \ No newline at end of file diff --git a/connectors/wikipedia/wikipedia_mcp_server.py b/connectors/wikipedia/wikipedia_mcp_server.py index 765721b..f6924e0 100644 --- a/connectors/wikipedia/wikipedia_mcp_server.py +++ b/connectors/wikipedia/wikipedia_mcp_server.py @@ -200,6 +200,7 @@ def _read_article(args: dict[str, Any]) -> str: TOOLS = [ { "name": "status", + "title": "Status", "description": ( "Self-check that the Wikipedia integration is operational: confirms " "the Wikipedia API is reachable by issuing a cheap siteinfo query. " @@ -209,6 +210,7 @@ TOOLS = [ }, { "name": "search", + "title": "Search Wikipedia", "description": ( "Search Wikipedia articles by keyword. Returns a list of matching " "article titles with short descriptions and URLs. Use this to find "