Repository navigation
v0.9.30: mship improvements, mcp tool and skill discovery, docs refinements - #9270
Conversation
* fix(chat): prevent suggested follow-ups from shifting on send * fix(chat): preserve inactive question card layout
… paths in the command inventory (#9251) The worker builds its agent grammar from this inventory and did not know that sim runs files mv, workflows folders ls or kb as their commands, or still runs retired paths such as tables count create and workflows deployment list as the commands they were renamed to, so it refused or misread them. Each command now carries the commander aliases of its path segments (pathAliases, aligned with path) and the paths it was renamed from (renamedFrom).
…tials, selectors, and webhook triggers (#9252) * feat(helpscout): add Help Scout integration with OAuth and app credentials, selectors, and webhook triggers * fix(helpscout): publish triggers in the catalog, reject unsafe IDs, and address review findings * fix(helpscout): mark nullable trigger output fields
…ror everywhere it is recorded (#9254) A worker error frame carries a diagnostic `message` and an optional user-facing `displayMessage`. Only the live inline error tag honored `displayMessage`; the server-side error handler recorded `message`, so the persisted transcript, the republished terminal error, the execute API result and the inbox reply all fell back to the diagnostic text, and the client's chat error state did the same. One selector, `mothershipErrorText`, now picks the user-facing text for the tag, the server handler and the client handler, so a reload shows the same line the live turn showed.
… format (#9256) * docs(library): rework no-code AI agent builders roundup into the lean format * fix(library): correct pricing terms and caveats in no-code builders roundup * fix(library): update no-code builders reading time
…pages (#9255) * improvement(library): merge near-duplicate posts into their stronger pages * fix(library): tighten merged post wording * fix(library): clarify when MCP data stays local * fix(library): use the catalog-derived integration count in the Dust alternatives guide
* docs(library): tighten n8n alternatives and fix its tool count * fix(library): drop shut-down Pipedream Workflows and correct pricing in n8n alternatives * fix(library): use Lindy's default plan price in n8n alternatives
…d term (#9257) * docs(library): restructure open source AI agents guide around its head term * fix(library): correct plan, count, and framework details in open source agents guide
#9259) * docs(library): rework Zapier alternatives into the lean roundup format * fix(library): correct billing terms and restore Zapier task pricing
…12 more tools, and validation fixes (#9253) * fix(helpscout): explain empty-body 404 responses in the error extractor * feat(helpscout): add knowledge base connector and auto-registered webhook triggers * feat(helpscout): add 12 tools, team assignees, and validation fixes for triggers, connector, and errors * fix(helpscout): switch default and unexported contact type sets * fix(helpscout): strict custom field and snooze input, unsafe connector reconciliation, safe inbox IDs * fix(helpscout): serialize the connector change marker structurally * fix(helpscout): keep team assignee names in connector metadata and tool outputs * fix(helpscout): separate connector scan budget and full organization property fields * fix(helpscout): let cleanup finish for triggers without a managed webhook
… server fails or lists no tools (#9260) buildTaggedMcpToolSchemas discovered tagged servers with Promise.all and threw when a server listed no tools, and the integration catalog includes MCP on every unfiltered request. One deleted, disabled, unreachable, truncated or tool-less /-tagged server therefore failed every unfiltered integrations list, grep and search_integration_tools call for the rest of the chat. Discovery now settles per server and returns { tools, failures }. The catalog drops failed servers from unfiltered and query results, logging each server id and reason, and still throws that server's own error when the request targets it (service mcp:<id>, or a tool id on it that no healthy server provides). The MCP permission-group check still runs once up front and still throws. Also removes the unread defer_loading/executeLocally/params fields on MCP catalog operations, the test-only buildSelectedMcpToolSchemas and buildOrganizationTaggedMcpToolSchemas with their tests and stale mocks, and corrects the post.ts comment that said tagged MCP tools ride the tool array.
… name the invalid mcp argument (#9261) * fix(tools): advertise json and any params without an object type, and name the invalid mcp argument * fix(mcp): report the first invalid argument without collecting every error allErrors made Ajv collect every failure on untrusted input before the message kept three; validation stops at the first failure again and the message names it.
…at inventory (#9264) The mothership agent now sees workspace skills as a catalog, name, id and description, and loads a matching one with skills get <id>, as Agent Skills clients do; with names alone it could not judge relevance and had to search for an id first. Built-ins carry their builtin-<name> id. The generated protocol copy is synced from the worker contract, where both fields are optional so either side can ship first.
…#9263) The integration catalog only inspected MCP servers the user had /-tagged in the chat, so a configured server's tools were invisible to the agent until tagged. Claude Code, Codex, Cursor and OpenCode treat every configured server as available and discover tools lazily; built-in integrations here already did. In agent and plan chats, the catalog's MCP candidates are now every enabled, non-Credential-Group server the requester can list in the target workspace. Search stays MCP-free, and workflow-block requests (mcpExecution or selected operations) stay scoped to their explicit selections. - Untagged servers are discovered best-effort: cache-aside through the existing McpService discovery cache (in-flight deduped, negative cache honored), and a server that does not answer within 3s is skipped and logged while its discovery keeps running to warm the cache for the next query. - Tagged servers and an explicitly targeted server (service mcp:<id> or an exact tool id, which the worker re-resolves before executing) are still listed live and completely, and a targeted server still fails with its own error. - Tagged servers rank first among equally relevant matches via a preferredServices tie-break in projectIntegrationCatalog. - A permission group that disables MCP now drops MCP from broad requests and keeps built-in operations listed; targeted and workflow-block requests still fail with the permission error. Tagging persistence is unchanged; comments that said untagged servers stay unavailable now describe tags as a priority hint.
…cted services (#9262) Free-text integration discovery now ranks with Okapi BM25 over each operation's name, service, description and parameter names, instead of substring hits. Tokens drop stop words before and after folding plurals (-ies, -es with warehouses keeping their e, -s), so natural-language intents like "send an email to a customer" match on content words. Operations of services the requester can already authenticate have their score multiplied by 1.5. Connected providers come from the authorized target workspace (accessible plus enrolled managed OAuth credentials) or, without a workspace, the requester's own org-managed credentials. The lookup only hints ranking: it never adds or reveals an operation, and a failure is logged and discovery proceeds unboosted. Sort order: exact operation ID, then boosted BM25 score, then preferred (tagged MCP) service, then name. The connected providers join the existing preferredServices tie-break in one CatalogProjectionOptions object. A service filter now counts as targeted discovery and returns input schemas.
…ibrary audit (#9268) * docs(library): correct vendor facts and Flowise status found in the library audit * docs(library): drop superlatives and em dashes from the self-hosted platforms roundup * docs(library): match the Lindy table cell to its pricing paragraph
… catalog resilient (#9266) * fix(mothership): keep untagged mcp discovery side-effect free and the catalog resilient Broad agent and plan catalog queries now discover every usable workspace MCP server (#9263), but a server's status, failure count, cooldown and OAuth row are shared by the workspace while its credentials resolve per requester. A member without a personal {{VAR}} the server references made discovery fail, which stamped the server failing and put it in a workspace-wide cooldown, so another member's tagged or targeted discovery and call re-resolution failed with McpServerCooldownError. For an OAuth server the requester never connected, discovery inserted an empty OAuth row and marked the server disconnected for everyone. - Best-effort (untagged, broad) discovery is a McpService mode that only reads shared health state: on failure it writes no status, failure count, cooldown or cache eviction, and on success only warms the tool cache. - Before reading the cache or connecting, it skips a server the requester cannot authenticate to: a referenced variable they have no value for (findMissingMcpConfigEnvVars, which records no secret usage), or an OAuth server with no authorized tokens (read, never created). Another member's cached tools are not served to them. - Tagged and targeted discovery keep today's health bookkeeping. - A failure listing the workspace's servers no longer fails the whole catalog: broad requests log it and keep built-ins and tagged servers; targeted MCP requests still fail with it. - A query with no content terms after tokenization (stop words only, or a script the tokenizer does not split) returns the unranked listing, as an empty query does, instead of total 0. Exact-ID ranking is unchanged. - A tagged server that is no longer usable is logged when dropped. * fix(mothership): gate best-effort mcp discovery on side-effect-free credential reads The best-effort gate read the OAuth row with loadOauthRow, which clears a column it cannot decrypt, so a broad catalog query after a key rotation erased the one grant every member shares. hasDecryptableOauthTokens reads the tokens column and tries to decrypt it without writing anything. findMissingMcpConfigEnvVars took a variable that failed to decrypt (which the environment snapshot reports as '') as present, so best-effort discovery connected with an empty credential instead of skipping. An empty effective value now counts as missing. * fix(mothership): keep the shared mcp oauth grant intact on best-effort refresh failures Best-effort discovery could still run the SDK's OAuth recovery while listing tools. A rejected refresh made it clear the tokens (and, for a rejected client, the registration) and start a new authorization flow, which disconnected the shared grant for every member. Its OAuth clients now use a SimMcpOauthProvider with preserveGrant, which refuses to invalidate credentials, register a client or start authorization before any write, so a failed refresh skips the server. A successful refresh still persists. It keeps the grant valid for everyone and must be saved where the server rotates refresh tokens. These clients are pooled apart from tracked ones. findMissingMcpConfigEnvVars counted every empty value as missing, but an empty variable is valid. Only a key the snapshot names in decryptionFailures whose effective value is empty now counts as missing.
…ool self-hosting, and note the Zapier Agents migration (#9267) * fix(comparisons): lead Flowise copy with its end of life, qualify Retool self-hosting, and note the Zapier Agents migration * fix(comparisons): end generated FAQ summaries at real sentence boundaries * fix(comparisons): keep closing quotes in sentence summaries and scope Flowise's end of life to the open-source project * fix(comparisons): don't add a period after a quoted sentence ending
…rts (#9265) * improvement(insights): clarify unassigned usage and refresh usage charts * fix(insights): preserve sub-credit activity in the usage heatmap
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
There was a problem hiding this comment.
All reported issues were addressed across 202 files
Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.
Turn on auto-fix | Re-trigger cubic
[High impact] The PR reaches connected Help Scout accounts, chat tool discovery, and enterprise usage workflows. The constant-array requirement must be satisfied before merging; limiting background discovery is also recommended. FindingsSummaryAdds Help Scout tools, credentials, selectors, webhook triggers, and a knowledge-base connector. It also expands MCP discovery, improves integration search, adds skill details to chat requests, and refreshes usage charts and documentation.
|
… entries and positive IDs, and correct trigger and credential copy (#9271) * fix(helpscout): require explicit tags to clear, validate custom field entries and positive IDs, and correct trigger and credential copy * fix(helpscout): treat only a literal empty tag list as clearing every tag * fix(helpscout): keep bracketed tags on the comma-separated path and clear only on a literal []
…down server every query (#9273) * fix(mothership): bound best-effort mcp discovery and stop retrying a down server every query Broad chat catalog discovery started best-effort discovery for every usable workspace server at once. The 3s wait only ends the caller's wait, so each attempt kept its sockets open for up to ~2 min, and a workspace with many servers could burst past the connection pool and evict other users' warm connections. Best-effort failures write no shared cooldown, so a down server was reattempted (with its DB and Redis reads) on every query. - Run best-effort discovery through mapSettledWithConcurrency with 8 at once; each server's 3s wait counts from its own start, and servers still queued 3s into the query are skipped unstarted, bounding query latency at ~6s. - Remember, per process and per requester (workspace:server:user, 60s, capped at 1000 entries), a best-effort server that failed or outlived its wait, and skip it until the memo expires or the late discovery succeeds. Nothing is written to shared state. - Named servers are unchanged: listed at once, waited on to completion. * fix(mothership): keep the best-effort memo in lru-cache and let only its own attempt settle it - Replace the hand-rolled TTL map with LRUCache (max 1000, ttl 60s), per the repo's caching rule. - A timed-out attempt's late outcome now settles the memo only while the entry is still that attempt's: an older attempt's late success no longer erases a newer attempt's failure, and its late failure no longer recreates a memo after a newer attempt succeeded.
Uh oh!
There was an error while loading. Please reload this page.