From 24cd037b01d85c030f872dc7068adf51ecb239a5 Mon Sep 17 00:00:00 2001 From: jottakka <203343514+jottakka@users.noreply.github.com> Date: Sat, 13 Jun 2026 11:44:46 +0000 Subject: [PATCH] [AUTO] Adding MCP Servers docs update --- .../integrations/development/_meta.tsx | 4 + .../resources/integrations/search/_meta.tsx | 4 + .../data/toolkits/cursoragents.json | 1249 +++++++++++++++++ .../data/toolkits/glean.json | 120 ++ .../data/toolkits/gmail.json | 40 +- .../data/toolkits/googlesheets.json | 820 ++++++++++- .../data/toolkits/index.json | 26 +- 7 files changed, 2229 insertions(+), 34 deletions(-) create mode 100644 toolkit-docs-generator/data/toolkits/cursoragents.json create mode 100644 toolkit-docs-generator/data/toolkits/glean.json diff --git a/app/en/resources/integrations/development/_meta.tsx b/app/en/resources/integrations/development/_meta.tsx index 76455a7dc..9e482f71f 100644 --- a/app/en/resources/integrations/development/_meta.tsx +++ b/app/en/resources/integrations/development/_meta.tsx @@ -9,6 +9,10 @@ const meta: MetaRecord = { title: "Bright Data", href: "/en/resources/integrations/development/brightdata", }, + "cursor-agents": { + title: "Cursor Agents", + href: "/en/resources/integrations/development/cursor-agents", + }, datadog: { title: "Datadog", href: "/en/resources/integrations/development/datadog", diff --git a/app/en/resources/integrations/search/_meta.tsx b/app/en/resources/integrations/search/_meta.tsx index 1936cef66..ad1e60347 100644 --- a/app/en/resources/integrations/search/_meta.tsx +++ b/app/en/resources/integrations/search/_meta.tsx @@ -5,6 +5,10 @@ const meta: MetaRecord = { type: "separator", title: "Optimized", }, + glean: { + title: "Glean", + href: "/en/resources/integrations/search/glean", + }, google_finance: { title: "Google Finance", href: "/en/resources/integrations/search/google_finance", diff --git a/toolkit-docs-generator/data/toolkits/cursoragents.json b/toolkit-docs-generator/data/toolkits/cursoragents.json new file mode 100644 index 000000000..5375976d2 --- /dev/null +++ b/toolkit-docs-generator/data/toolkits/cursoragents.json @@ -0,0 +1,1249 @@ +{ + "id": "CursorAgents", + "label": "Cursor Agents", + "version": "0.1.0", + "description": "Arcade.dev tools for operating Cursor Cloud Agents", + "metadata": { + "category": "development", + "iconUrl": "https://design-system.arcade.dev/icons/cursor.svg", + "isBYOC": false, + "isPro": false, + "type": "arcade", + "docsLink": "https://docs.arcade.dev/en/resources/integrations/development/cursor-agents", + "isComingSoon": false, + "isHidden": false + }, + "auth": null, + "tools": [ + { + "name": "ArchiveAgent", + "qualifiedName": "CursorAgents.ArchiveAgent", + "fullyQualifiedName": "CursorAgents.ArchiveAgent@0.1.0", + "description": "Archive a cloud agent so it stops accepting new runs (reversible).\n\nThe archive is committed once accepted; if the follow-up read of the agent\nfails, the result carries only the agent id with an empty status, and a\nget_agent call returns the refreshed state.", + "parameters": [ + { + "name": "agent_id", + "type": "string", + "required": true, + "description": "The agent identifier (bc-).", + "enum": null, + "inferrable": true + } + ], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.ArchiveAgent", + "parameters": { + "agent_id": { + "value": "bc-3f7a1c2d-8e45-4b9f-a012-6d3e5f8c1b7a", + "type": "string", + "required": true + } + }, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "update" + ], + "readOnly": false, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "CancelRun", + "qualifiedName": "CursorAgents.CancelRun", + "fullyQualifiedName": "CursorAgents.CancelRun@0.1.0", + "description": "Cancel an active run; cancelling an already-terminal run returns an error.\n\nCancellation is accepted asynchronously: the returned status reflects the run's\nstate at the moment of the call and may still be non-terminal even though the\ncancel was accepted. Poll the run afterward to confirm it settles to CANCELLED;\ndo not treat a non-terminal status here as a failed cancel. If the post-cancel\nread of the run fails, the result carries an empty status instead of an error.\nUpstream failures carry a stable bracketed code before the message when Cursor\nsupplies one (an open set; the most common here is ``[run_not_cancellable]``,\nreturned when the run is already terminal).", + "parameters": [ + { + "name": "agent_id", + "type": "string", + "required": true, + "description": "The agent identifier (bc-).", + "enum": null, + "inferrable": true + }, + { + "name": "run_id", + "type": "string", + "required": true, + "description": "The active run identifier to cancel.", + "enum": null, + "inferrable": true + } + ], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.CancelRun", + "parameters": { + "agent_id": { + "value": "bc-a3f2e1d4-7c89-4b56-ae12-9f034d8c21b7", + "type": "string", + "required": true + }, + "run_id": { + "value": "run-5e6f7a8b-1234-4cde-9abc-def012345678", + "type": "string", + "required": true + } + }, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "update" + ], + "readOnly": false, + "destructive": false, + "idempotent": false, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "DeleteAgent", + "qualifiedName": "CursorAgents.DeleteAgent", + "fullyQualifiedName": "CursorAgents.DeleteAgent@0.1.0", + "description": "Permanently delete a cloud agent. This cannot be undone.", + "parameters": [ + { + "name": "agent_id", + "type": "string", + "required": true, + "description": "The agent identifier (bc-).", + "enum": null, + "inferrable": true + } + ], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.DeleteAgent", + "parameters": { + "agent_id": { + "value": "bc-f47ac10b-58cc-4372-a567-0e02b2c3d479", + "type": "string", + "required": true + } + }, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "delete" + ], + "readOnly": false, + "destructive": true, + "idempotent": false, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "DownloadArtifact", + "qualifiedName": "CursorAgents.DownloadArtifact", + "fullyQualifiedName": "CursorAgents.DownloadArtifact@0.1.0", + "description": "Get a time-limited download link for one uploaded artifact file.\n\nArtifacts are Cursor \"background composer\" uploads, not an agent's code changes;\nfor code output read the run's branch and PR instead.", + "parameters": [ + { + "name": "agent_id", + "type": "string", + "required": true, + "description": "The agent identifier (bc-).", + "enum": null, + "inferrable": true + }, + { + "name": "path", + "type": "string", + "required": true, + "description": "The artifact's path, as returned when listing artifacts.", + "enum": null, + "inferrable": true + } + ], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.DownloadArtifact", + "parameters": { + "agent_id": { + "value": "bc-a3f7c2d1-84e6-4b2f-9c31-d5e08f1a6b72", + "type": "string", + "required": true + }, + "path": { + "value": "outputs/report_summary.pdf", + "type": "string", + "required": true + } + }, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "read" + ], + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "GetAgent", + "qualifiedName": "CursorAgents.GetAgent", + "fullyQualifiedName": "CursorAgents.GetAgent@0.1.0", + "description": "Get a cloud agent's configuration and latest run pointer.", + "parameters": [ + { + "name": "agent_id", + "type": "string", + "required": true, + "description": "The agent identifier (bc-).", + "enum": null, + "inferrable": true + } + ], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.GetAgent", + "parameters": { + "agent_id": { + "value": "bc-f47ac10b-58cc-4372-a567-0e02b2c3d479", + "type": "string", + "required": true + } + }, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "read" + ], + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "GetAgentUsage", + "qualifiedName": "CursorAgents.GetAgentUsage", + "fullyQualifiedName": "CursorAgents.GetAgentUsage@0.1.0", + "description": "Get token usage for an agent, summed and broken down per run.", + "parameters": [ + { + "name": "agent_id", + "type": "string", + "required": true, + "description": "The agent identifier (bc-).", + "enum": null, + "inferrable": true + }, + { + "name": "run_id", + "type": "string", + "required": false, + "description": "Scope usage to a single run. Leave empty to total across all of the agent's runs.", + "enum": null, + "inferrable": true + } + ], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.GetAgentUsage", + "parameters": { + "agent_id": { + "value": "bc-a3f2e1d4-7b8c-4e5f-9a0b-123456789abc", + "type": "string", + "required": true + }, + "run_id": { + "value": "run-9c1d2e3f-4a5b-6c7d-8e9f-0a1b2c3d4e5f", + "type": "string", + "required": false + } + }, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "read" + ], + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "GetRun", + "qualifiedName": "CursorAgents.GetRun", + "fullyQualifiedName": "CursorAgents.GetRun@0.1.0", + "description": "Get a run's current status, and its result, branches, and PR once terminal.", + "parameters": [ + { + "name": "agent_id", + "type": "string", + "required": true, + "description": "The agent identifier (bc-).", + "enum": null, + "inferrable": true + }, + { + "name": "run_id", + "type": "string", + "required": true, + "description": "The run identifier to read.", + "enum": null, + "inferrable": true + } + ], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.GetRun", + "parameters": { + "agent_id": { + "value": "bc-a3f7c2d1-84e6-4b19-9f02-d5c813e76a40", + "type": "string", + "required": true + }, + "run_id": { + "value": "run_7x9mKpQr2LnVwZ4T", + "type": "string", + "required": true + } + }, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "read" + ], + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "LaunchAgent", + "qualifiedName": "CursorAgents.LaunchAgent", + "fullyQualifiedName": "CursorAgents.LaunchAgent@0.1.0", + "description": "Launch a Cursor cloud agent on a repository or named environment.\n\nThis single call starts the agent and its first run; follow it to completion\nwith the run tools.", + "parameters": [ + { + "name": "prompt", + "type": "string", + "required": true, + "description": "The coding task for the agent, in natural language.", + "enum": null, + "inferrable": true + }, + { + "name": "repository_url", + "type": "string", + "required": false, + "description": "GitHub repository the agent works on (https://github.com/org/repo; the schemeless github.com/org/repo form returned by list_repositories is also accepted). Leave empty when launching into a named environment, which already pins its repository.", + "enum": null, + "inferrable": true + }, + { + "name": "starting_ref", + "type": "string", + "required": false, + "description": "Branch, tag, or commit to start from. Only valid with a repository url; a named environment pins its own repository and ref. Leave empty to use the repository default branch.", + "enum": null, + "inferrable": true + }, + { + "name": "environment", + "type": "string", + "required": false, + "description": "Named cloud environment to run in. Leave empty to run on the given repository. Cannot be combined with a repository url.", + "enum": null, + "inferrable": true + }, + { + "name": "model", + "type": "string", + "required": false, + "description": "Model id to use. Leave empty to use the account default model.", + "enum": null, + "inferrable": true + }, + { + "name": "mcp_servers", + "type": "array", + "innerType": "json", + "required": false, + "description": "MCP servers to pre-wire into the agent. Leave empty for none. Each item is an object with fields: name (str, required); type (str: \"http\", \"sse\", or \"stdio\"); url (str, for http/sse servers); headers (object of str to str, optional, for http/sse servers); command (str, for stdio servers, run inside the agent VM); args (list of str, optional, for stdio servers); env (object of str to str, optional, for stdio servers).", + "enum": null, + "inferrable": true + }, + { + "name": "env_vars", + "type": "json", + "required": false, + "description": "Environment variables injected into the agent shell, as name/value pairs. At most 50 entries; names cannot start with CURSOR_. Leave empty for none.", + "enum": null, + "inferrable": true + }, + { + "name": "mode", + "type": "string", + "required": false, + "description": "Whether the agent edits code or only produces a plan. Defaults to AGENT.", + "enum": [ + "agent", + "plan" + ], + "inferrable": true + }, + { + "name": "auto_create_pr", + "type": "boolean", + "required": false, + "description": "Open a pull request with the agent's changes when it finishes. Defaults to false.", + "enum": null, + "inferrable": true + }, + { + "name": "work_on_current_branch", + "type": "boolean", + "required": false, + "description": "Commit to the starting branch instead of a new branch. Defaults to false.", + "enum": null, + "inferrable": true + }, + { + "name": "name", + "type": "string", + "required": false, + "description": "Display name for the agent (max 100 characters). Leave empty to auto-name it.", + "enum": null, + "inferrable": true + } + ], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.LaunchAgent", + "parameters": { + "prompt": { + "value": "Refactor the authentication module to use JWT tokens instead of session cookies, and add unit tests for the new implementation.", + "type": "string", + "required": true + }, + "repository_url": { + "value": "https://github.com/acme-corp/backend-api", + "type": "string", + "required": false + }, + "starting_ref": { + "value": "feature/auth-refactor", + "type": "string", + "required": false + }, + "environment": { + "value": "", + "type": "string", + "required": false + }, + "model": { + "value": "claude-3-5-sonnet", + "type": "string", + "required": false + }, + "mcp_servers": { + "value": [ + { + "name": "github-mcp", + "type": "http", + "url": "https://mcp.github.com/v1", + "headers": { + "Authorization": "Bearer ghp_exampletoken123" + } + }, + { + "name": "local-linter", + "type": "stdio", + "command": "npx", + "args": [ + "eslint", + "--stdin" + ], + "env": { + "NODE_ENV": "development" + } + } + ], + "type": "array", + "required": false + }, + "env_vars": { + "value": { + "APP_ENV": "staging", + "LOG_LEVEL": "debug", + "DATABASE_URL": "postgres://user:pass@localhost:5432/mydb" + }, + "type": "string", + "required": false + }, + "mode": { + "value": "AGENT", + "type": "string", + "required": false + }, + "auto_create_pr": { + "value": true, + "type": "boolean", + "required": false + }, + "work_on_current_branch": { + "value": false, + "type": "boolean", + "required": false + }, + "name": { + "value": "JWT Auth Refactor Agent", + "type": "string", + "required": false + } + }, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "create" + ], + "readOnly": false, + "destructive": false, + "idempotent": false, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "ListAgents", + "qualifiedName": "CursorAgents.ListAgents", + "fullyQualifiedName": "CursorAgents.ListAgents@0.1.0", + "description": "List your cloud agents, newest first.", + "parameters": [ + { + "name": "include_archived", + "type": "boolean", + "required": false, + "description": "Include archived agents in the results. Defaults to true.", + "enum": null, + "inferrable": true + }, + { + "name": "pr_url", + "type": "string", + "required": false, + "description": "Only return agents associated with this pull request url. Leave empty for no filter.", + "enum": null, + "inferrable": true + }, + { + "name": "limit", + "type": "integer", + "required": false, + "description": "Maximum agents to return (1-100; values outside the range are clamped). Defaults to 20.", + "enum": null, + "inferrable": true + }, + { + "name": "cursor", + "type": "string", + "required": false, + "description": "Pagination cursor from a previous call. Leave empty for the first page.", + "enum": null, + "inferrable": true + } + ], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.ListAgents", + "parameters": { + "include_archived": { + "value": false, + "type": "boolean", + "required": false + }, + "pr_url": { + "value": "https://github.com/example-org/example-repo/pull/42", + "type": "string", + "required": false + }, + "limit": { + "value": 25, + "type": "integer", + "required": false + }, + "cursor": { + "value": "eyJpZCI6IjEyMyIsInRpbWVzdGFtcCI6MTY5ODc2NTQzMn0=", + "type": "string", + "required": false + } + }, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "read" + ], + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "ListArtifacts", + "qualifiedName": "CursorAgents.ListArtifacts", + "fullyQualifiedName": "CursorAgents.ListArtifacts@0.1.0", + "description": "List the artifact files a cloud agent explicitly uploaded.\n\nArtifacts are Cursor \"background composer\" uploads. Code an agent writes to a repo\nlands on the run's branch and PR (see the run's ``branches``), not here, so this is\nempty for typical fix-a-repo / open-a-PR tasks.", + "parameters": [ + { + "name": "agent_id", + "type": "string", + "required": true, + "description": "The agent identifier (bc-).", + "enum": null, + "inferrable": true + } + ], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.ListArtifacts", + "parameters": { + "agent_id": { + "value": "bc-3f7a1c2e-85b4-4d9f-ae62-1c0d2e3f4a5b", + "type": "string", + "required": true + } + }, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "read" + ], + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "ListModels", + "qualifiedName": "CursorAgents.ListModels", + "fullyQualifiedName": "CursorAgents.ListModels@0.1.0", + "description": "List the LLM models available to launch a cloud agent with.\n\nReturns the model ids (e.g. Claude, GPT, and Gemini family models) accepted\nby the launch tool's model parameter, with display names and aliases.", + "parameters": [], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.ListModels", + "parameters": {}, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "read" + ], + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "ListRepositories", + "qualifiedName": "CursorAgents.ListRepositories", + "fullyQualifiedName": "CursorAgents.ListRepositories@0.1.0", + "description": "List every GitHub repository Cursor can reach, as repository urls.\n\nThe upstream returns the full set in one response, so this is always the\ncomplete list and never a partial page.", + "parameters": [], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.ListRepositories", + "parameters": {}, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "read" + ], + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "ListRuns", + "qualifiedName": "CursorAgents.ListRuns", + "fullyQualifiedName": "CursorAgents.ListRuns@0.1.0", + "description": "List an agent's runs, newest first.\n\nListing omits each run's final result text; read an individual run to get it.", + "parameters": [ + { + "name": "agent_id", + "type": "string", + "required": true, + "description": "The agent identifier (bc-).", + "enum": null, + "inferrable": true + }, + { + "name": "limit", + "type": "integer", + "required": false, + "description": "Maximum runs to return (1-100; values outside the range are clamped). Defaults to 20.", + "enum": null, + "inferrable": true + }, + { + "name": "cursor", + "type": "string", + "required": false, + "description": "Pagination cursor from a previous call. Leave empty for the first page.", + "enum": null, + "inferrable": true + } + ], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.ListRuns", + "parameters": { + "agent_id": { + "value": "bc-a3f7c2d1-84be-4e91-b35f-9d02c1e76a50", + "type": "string", + "required": true + }, + "limit": { + "value": 25, + "type": "integer", + "required": false + }, + "cursor": { + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJydW5faWQiOiJydW4tMDAxMjMifQ", + "type": "string", + "required": false + } + }, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "read" + ], + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "SendFollowupRun", + "qualifiedName": "CursorAgents.SendFollowupRun", + "fullyQualifiedName": "CursorAgents.SendFollowupRun@0.1.0", + "description": "Send a follow-up prompt to an existing agent, starting a new run.\n\nAn agent runs one turn at a time. Upstream failures carry a stable bracketed\ncode before the message when Cursor supplies one (an open set; the most\ncommon here is ``[agent_busy]``). If this returns ``[agent_busy]``, the agent\nalready has an active run: poll get_run until is_terminal, then resend the\nfollow-up.", + "parameters": [ + { + "name": "agent_id", + "type": "string", + "required": true, + "description": "The agent identifier (bc-) to steer.", + "enum": null, + "inferrable": true + }, + { + "name": "prompt", + "type": "string", + "required": true, + "description": "Follow-up instructions for the agent, in natural language.", + "enum": null, + "inferrable": true + }, + { + "name": "mcp_servers", + "type": "array", + "innerType": "json", + "required": false, + "description": "MCP servers scoped to this run only. Leave empty for none. Each item is an object with fields: name (str, required); type (str: \"http\", \"sse\", or \"stdio\"); url (str, for http/sse servers); headers (object of str to str, optional, for http/sse servers); command (str, for stdio servers, run inside the agent VM); args (list of str, optional, for stdio servers); env (object of str to str, optional, for stdio servers).", + "enum": null, + "inferrable": true + }, + { + "name": "mode", + "type": "string", + "required": false, + "description": "Whether the agent edits code or only produces a plan. Defaults to AGENT.", + "enum": [ + "agent", + "plan" + ], + "inferrable": true + } + ], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.SendFollowupRun", + "parameters": { + "agent_id": { + "value": "bc-a3f7c821-4d92-4b3e-9f10-d65e882c1047", + "type": "string", + "required": true + }, + "prompt": { + "value": "Please refactor the authentication module to use JWT tokens instead of session cookies, and add unit tests for each new function.", + "type": "string", + "required": true + }, + "mcp_servers": { + "value": [ + { + "name": "filesystem-server", + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-filesystem", + "/workspace" + ], + "env": { + "NODE_ENV": "development" + } + }, + { + "name": "github-server", + "type": "http", + "url": "https://mcp.github.example.com/v1", + "headers": { + "Authorization": "Bearer ghp_exampletoken123", + "X-Org": "my-org" + } + } + ], + "type": "array", + "required": false + }, + "mode": { + "value": "AGENT", + "type": "string", + "required": false + } + }, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "create" + ], + "readOnly": false, + "destructive": false, + "idempotent": false, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "UnarchiveAgent", + "qualifiedName": "CursorAgents.UnarchiveAgent", + "fullyQualifiedName": "CursorAgents.UnarchiveAgent@0.1.0", + "description": "Restore an archived cloud agent to active.\n\nThe restore is committed once accepted; if the follow-up read of the agent\nfails, the result carries only the agent id with an empty status, and a\nget_agent call returns the refreshed state.", + "parameters": [ + { + "name": "agent_id", + "type": "string", + "required": true, + "description": "The agent identifier (bc-).", + "enum": null, + "inferrable": true + } + ], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.UnarchiveAgent", + "parameters": { + "agent_id": { + "value": "bc-3f7a1c2e-85d4-4b6f-9e0a-12c3d456ef78", + "type": "string", + "required": true + } + }, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "update" + ], + "readOnly": false, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "WhoAmI", + "qualifiedName": "CursorAgents.WhoAmI", + "fullyQualifiedName": "CursorAgents.WhoAmI@0.1.0", + "description": "Return the Cursor account the API key authenticates as.\n\nCall this first in a session to confirm which account you are acting on\nbefore launching or managing any cloud agents.", + "parameters": [], + "auth": null, + "secrets": [ + "CURSOR_AGENTS_API_KEY" + ], + "secretsInfo": [ + { + "name": "CURSOR_AGENTS_API_KEY", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "No description provided." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "CursorAgents.WhoAmI", + "parameters": {}, + "requiresAuth": false, + "tabLabel": "Call the Tool" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "read" + ], + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + } + ], + "documentationChunks": [], + "customImports": [], + "subPages": [], + "generatedAt": "2026-06-13T11:44:28.485Z", + "summary": "Arcade toolkit for operating [Cursor](https://cursor.com) Cloud Agents — AI-powered coding agents that run on repositories in the cloud. This toolkit enables full programmatic lifecycle management of agents and their runs via the Cursor Cloud Agents API.\n\n## Capabilities\n\n- **Agent lifecycle**: Launch agents on GitHub repositories or named environments, retrieve config and status, list all agents, archive/unarchive (reversible), and permanently delete agents.\n- **Run management**: List runs, get real-time status and terminal results (branches, PRs, result text), cancel active runs, and send follow-up prompts to chain multi-turn interactions — including handling `[agent_busy]` polling patterns.\n- **Artifacts**: List files a cloud agent explicitly uploaded via Cursor's background composer, and obtain time-limited download URLs for individual artifact files.\n- **Discovery & introspection**: List all LLM models available for launch (Claude, GPT, Gemini families), list all reachable GitHub repositories, query per-agent token usage broken down by run, and confirm the authenticated Cursor account identity.\n\n## Secrets\n\n`CURSOR_AGENTS_API_KEY` — A Cursor API key that authenticates all requests to the Cursor Cloud Agents API. Obtain it from your Cursor account dashboard under API keys/settings. The key must have permission to manage cloud agents; verify the correct account is in scope by calling `CursorAgents.WhoAmI` at the start of a session before launching or modifying agents.\n\nSee the Arcade secrets docs for how to store and reference secrets in tools: https://docs.arcade.dev/en/guides/create-tools/tool-basics/create-tool-secrets — you can also manage secrets directly at https://api.arcade.dev/dashboard/auth/secrets." +} \ No newline at end of file diff --git a/toolkit-docs-generator/data/toolkits/glean.json b/toolkit-docs-generator/data/toolkits/glean.json new file mode 100644 index 000000000..f7d53e225 --- /dev/null +++ b/toolkit-docs-generator/data/toolkits/glean.json @@ -0,0 +1,120 @@ +{ + "id": "Glean", + "label": "Glean", + "version": "0.2.0", + "description": "Arcade MCP server exposing Glean Client API search over custom OAuth2.", + "metadata": { + "category": "search", + "iconUrl": "https://design-system.arcade.dev/icons/glean.svg", + "isBYOC": true, + "isPro": false, + "type": "arcade", + "docsLink": "https://docs.arcade.dev/en/resources/integrations/search/glean", + "isComingSoon": false, + "isHidden": false + }, + "auth": { + "type": "oauth2", + "providerId": null, + "allScopes": [ + "search" + ] + }, + "tools": [ + { + "name": "Search", + "qualifiedName": "Glean.Search", + "fullyQualifiedName": "Glean.Search@0.2.0", + "description": "Search the user's Glean enterprise index and return ranked results.\n\nResults are permission-filtered to the authorized user. Use 'offset' with\n'limit' to page; 'has_next_page' indicates more results remain. Offset\npaging is supported up to roughly 2000 results (20 pages x 100 items);\ndeeper offsets raise an error rather than return a misleading empty page.\nWhen the fetch budget is exhausted before the requested window is filled,\nthe tool raises rather than return a partial page (fail loud over mislead).\nThe result list is trimmed to a size budget when items are large;\n'truncated' flags it and 'has_next_page' stays true so the caller can page\nor narrow the query.", + "parameters": [ + { + "name": "query", + "type": "string", + "required": true, + "description": "Natural-language search query to run against the user's Glean index.", + "enum": null, + "inferrable": true + }, + { + "name": "limit", + "type": "integer", + "required": false, + "description": "Maximum number of results to return (1-100). Defaults to 10.", + "enum": null, + "inferrable": true + }, + { + "name": "offset", + "type": "integer", + "required": false, + "description": "0-indexed position of the first result to return. Defaults to 0 (first result).", + "enum": null, + "inferrable": true + } + ], + "auth": { + "providerId": null, + "providerType": "oauth2", + "scopes": [ + "search" + ] + }, + "secrets": [ + "GLEAN_API_URL" + ], + "secretsInfo": [ + { + "name": "GLEAN_API_URL", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "Ranked Glean results plus pagination metadata. 'has_next_page' is true when more results are available (page with a larger 'offset'); 'truncated' is true when the result list was trimmed to fit a response-size budget." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "Glean.Search", + "parameters": { + "query": { + "value": "quarterly engineering roadmap Q3 2024", + "type": "string", + "required": true + }, + "limit": { + "value": 25, + "type": "integer", + "required": false + }, + "offset": { + "value": 0, + "type": "integer", + "required": false + } + }, + "requiresAuth": true, + "tabLabel": "Call the Tool with User Authorization" + }, + "metadata": { + "classification": { + "serviceDomains": [] + }, + "behavior": { + "operations": [ + "read" + ], + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + } + ], + "documentationChunks": [], + "customImports": [], + "subPages": [], + "generatedAt": "2026-06-13T11:44:24.869Z", + "summary": "The Glean toolkit connects Arcade to a Glean enterprise deployment, exposing the Glean Client API so agents can search an organization's indexed content with results permission-filtered to the authenticated user.\n\n## Capabilities\n\n- **Enterprise search** — Query the Glean index via `Glean.Search`; results are ranked and scoped to the authorized user's permissions.\n- **Pagination** — Supports offset/limit paging (up to ~2000 results, ~20 pages × 100 items); `has_next_page` signals more results; offsets beyond the supported range raise an explicit error.\n- **Result-size budgeting** — Response payloads are trimmed when items are large; `truncated` flags a trimmed page while `has_next_page` remains `true` so callers can continue paging or narrow their query.\n- **Fail-loud semantics** — The tool raises an error rather than return a partial or misleading page when the fetch budget is exhausted or an unsupported offset is requested.\n\n## OAuth\n\nThis toolkit uses OAuth 2.0 against a **custom/self-hosted Glean OAuth provider**. Because the provider ID is specific to your Glean deployment, consult your Glean administrator for client credentials and authorization endpoint details. Arcade's general OAuth provider reference is at [https://docs.arcade.dev/en/references/auth-providers](https://docs.arcade.dev/en/references/auth-providers).\n\n## Secrets\n\n- **`GLEAN_API_URL`** — The base URL of your organization's Glean API endpoint (e.g., `https://.glean.com/api`). This value is deployment-specific and is **not** the public Glean website. Obtain it from your Glean administrator or from the Glean admin console under **Setup → API** (exact path may vary by Glean version). It is required so the toolkit knows which Glean instance to route requests to.\n\nStore secrets in Arcade using the [Arcade secrets guide](https://docs.arcade.dev/en/guides/create-tools/tool-basics/create-tool-secrets) or manage them directly at [https://api.arcade.dev/dashboard/auth/secrets](https://api.arcade.dev/dashboard/auth/secrets)." +} \ No newline at end of file diff --git a/toolkit-docs-generator/data/toolkits/gmail.json b/toolkit-docs-generator/data/toolkits/gmail.json index 128d1dc38..9e53b842d 100644 --- a/toolkit-docs-generator/data/toolkits/gmail.json +++ b/toolkit-docs-generator/data/toolkits/gmail.json @@ -1,7 +1,7 @@ { "id": "Gmail", "label": "Gmail", - "version": "7.1.0", + "version": "7.3.0", "description": "Arcade.dev LLM tools for Gmail", "metadata": { "category": "productivity", @@ -30,7 +30,7 @@ { "name": "ChangeEmailLabels", "qualifiedName": "Gmail.ChangeEmailLabels", - "fullyQualifiedName": "Gmail.ChangeEmailLabels@7.1.0", + "fullyQualifiedName": "Gmail.ChangeEmailLabels@7.3.0", "description": "Add and remove labels from an email using the Gmail API.", "parameters": [ { @@ -124,7 +124,7 @@ { "name": "CreateLabel", "qualifiedName": "Gmail.CreateLabel", - "fullyQualifiedName": "Gmail.CreateLabel@7.1.0", + "fullyQualifiedName": "Gmail.CreateLabel@7.3.0", "description": "Create a new label in the user's mailbox.", "parameters": [ { @@ -184,7 +184,7 @@ { "name": "DeleteDraftEmail", "qualifiedName": "Gmail.DeleteDraftEmail", - "fullyQualifiedName": "Gmail.DeleteDraftEmail@7.1.0", + "fullyQualifiedName": "Gmail.DeleteDraftEmail@7.3.0", "description": "Delete a draft email using the Gmail API.", "parameters": [ { @@ -244,7 +244,7 @@ { "name": "GetThread", "qualifiedName": "Gmail.GetThread", - "fullyQualifiedName": "Gmail.GetThread@7.1.0", + "fullyQualifiedName": "Gmail.GetThread@7.3.0", "description": "Get the specified thread by ID.", "parameters": [ { @@ -304,7 +304,7 @@ { "name": "ListDraftEmails", "qualifiedName": "Gmail.ListDraftEmails", - "fullyQualifiedName": "Gmail.ListDraftEmails@7.1.0", + "fullyQualifiedName": "Gmail.ListDraftEmails@7.3.0", "description": "Lists draft emails in the user's draft mailbox using the Gmail API.", "parameters": [ { @@ -364,7 +364,7 @@ { "name": "ListEmails", "qualifiedName": "Gmail.ListEmails", - "fullyQualifiedName": "Gmail.ListEmails@7.1.0", + "fullyQualifiedName": "Gmail.ListEmails@7.3.0", "description": "Read emails from a Gmail account and extract plain text content.\n\nBy default, obvious automated emails are excluded from results using\nno-reply sender patterns and Gmail's non-primary category filters\n(promotions, social, updates, forums). Set exclude_automated=False to\ninclude all emails regardless of source.", "parameters": [ { @@ -437,7 +437,7 @@ { "name": "ListEmailsByHeader", "qualifiedName": "Gmail.ListEmailsByHeader", - "fullyQualifiedName": "Gmail.ListEmailsByHeader@7.1.0", + "fullyQualifiedName": "Gmail.ListEmailsByHeader@7.3.0", "description": "Search for emails by header using the Gmail API.\n\nBy default, obvious automated emails are excluded from results using\nno-reply sender patterns and Gmail's non-primary category filters\n(promotions, social, updates, forums). Set exclude_automated=False to\ninclude all emails regardless of source.", "parameters": [ { @@ -596,7 +596,7 @@ { "name": "ListLabels", "qualifiedName": "Gmail.ListLabels", - "fullyQualifiedName": "Gmail.ListLabels@7.1.0", + "fullyQualifiedName": "Gmail.ListLabels@7.3.0", "description": "List all the labels in the user's mailbox.", "parameters": [], "auth": { @@ -641,7 +641,7 @@ { "name": "ListThreads", "qualifiedName": "Gmail.ListThreads", - "fullyQualifiedName": "Gmail.ListThreads@7.1.0", + "fullyQualifiedName": "Gmail.ListThreads@7.3.0", "description": "List threads in the user's mailbox.\n\nBy default, obvious automated threads are excluded from results using\nno-reply sender patterns and Gmail's non-primary category filters\n(promotions, social, updates, forums). Set exclude_automated=False to\ninclude all threads regardless of source.", "parameters": [ { @@ -740,7 +740,7 @@ { "name": "ReplyToEmail", "qualifiedName": "Gmail.ReplyToEmail", - "fullyQualifiedName": "Gmail.ReplyToEmail@7.1.0", + "fullyQualifiedName": "Gmail.ReplyToEmail@7.3.0", "description": "Send a reply to an email message, optionally with one or more file attachments.\n\nTo attach files, pass ``attachments`` and give each file's local path as a\n``file://`` URI in ``source`` (formatted ``file:///absolute/path/to/file``). The\nfile's bytes are read and substituted on the client before the request is sent, so\nthe contents never pass through this conversation. Do not read, encode, or inline\nthe bytes yourself.", "parameters": [ { @@ -905,7 +905,7 @@ { "name": "SearchThreads", "qualifiedName": "Gmail.SearchThreads", - "fullyQualifiedName": "Gmail.SearchThreads@7.1.0", + "fullyQualifiedName": "Gmail.SearchThreads@7.3.0", "description": "Search for threads in the user's mailbox.\n\nBy default, obvious automated threads are excluded from results using\nno-reply sender patterns and Gmail's non-primary category filters\n(promotions, social, updates, forums). Set exclude_automated=False to\ninclude all threads regardless of source.", "parameters": [ { @@ -1094,7 +1094,7 @@ { "name": "SendDraftEmail", "qualifiedName": "Gmail.SendDraftEmail", - "fullyQualifiedName": "Gmail.SendDraftEmail@7.1.0", + "fullyQualifiedName": "Gmail.SendDraftEmail@7.3.0", "description": "Send a draft email using the Gmail API.", "parameters": [ { @@ -1154,7 +1154,7 @@ { "name": "SendEmail", "qualifiedName": "Gmail.SendEmail", - "fullyQualifiedName": "Gmail.SendEmail@7.1.0", + "fullyQualifiedName": "Gmail.SendEmail@7.3.0", "description": "Send an email using the Gmail API, optionally with one or more file attachments.\n\nTo attach files, pass ``attachments`` and give each file's local path as a\n``file://`` URI in ``source`` (formatted ``file:///absolute/path/to/file``). The\nfile's bytes are read and substituted on the client before the request is sent, so\nthe contents never pass through this conversation. Do not read, encode, or inline\nthe bytes yourself.", "parameters": [ { @@ -1315,7 +1315,7 @@ { "name": "TrashEmail", "qualifiedName": "Gmail.TrashEmail", - "fullyQualifiedName": "Gmail.TrashEmail@7.1.0", + "fullyQualifiedName": "Gmail.TrashEmail@7.3.0", "description": "Move an email to the trash folder using the Gmail API.", "parameters": [ { @@ -1375,7 +1375,7 @@ { "name": "UpdateDraftEmail", "qualifiedName": "Gmail.UpdateDraftEmail", - "fullyQualifiedName": "Gmail.UpdateDraftEmail@7.1.0", + "fullyQualifiedName": "Gmail.UpdateDraftEmail@7.3.0", "description": "Update an existing email draft using the Gmail API.\n\nSingle-part ``text/plain`` and single-part ``text/html`` drafts both support full\nbody replacement; the rebuild follows the existing draft's content type, so a\nplain draft stays plain and an HTML draft stays HTML. Plain-text input supplied\nagainst an HTML draft is auto-converted to HTML, and HTML input supplied against\na plain draft is stored verbatim as ``text/plain``. Reply drafts preserve their\nreply-quote tail (``> `` lines for plain, ``
`` for HTML) when the\nbody is supplied as a top-only update.\n\nMultipart drafts and drafts with attachments still fail when the body changes;\nin those cases the tool succeeds only when the effective body is unchanged\n(metadata-only update preserving the existing MIME tree). Edit those drafts in\nGmail directly.\n\nFor each of subject, body, recipient, cc, and bcc, omitting the parameter or passing\n``None`` leaves that part of the draft unchanged (for cc/bcc, existing headers are kept;\npass an empty list to clear).", "parameters": [ { @@ -1507,7 +1507,7 @@ { "name": "WhoAmI", "qualifiedName": "Gmail.WhoAmI", - "fullyQualifiedName": "Gmail.WhoAmI@7.1.0", + "fullyQualifiedName": "Gmail.WhoAmI@7.3.0", "description": "Get comprehensive user profile and Gmail account information.\n\nThis tool provides detailed information about the authenticated user including\ntheir name, email, profile picture, Gmail account statistics, and other\nimportant profile details from Google services.", "parameters": [], "auth": { @@ -1554,7 +1554,7 @@ { "name": "WriteDraftEmail", "qualifiedName": "Gmail.WriteDraftEmail", - "fullyQualifiedName": "Gmail.WriteDraftEmail@7.1.0", + "fullyQualifiedName": "Gmail.WriteDraftEmail@7.3.0", "description": "Compose a new email draft using the Gmail API, optionally with file attachments.\n\nTo attach files, pass ``attachments`` and give each file's local path as a\n``file://`` URI in ``source`` (formatted ``file:///absolute/path/to/file``). The\nfile's bytes are read and substituted on the client before the request is sent, so\nthe contents never pass through this conversation. Do not read, encode, or inline\nthe bytes yourself.", "parameters": [ { @@ -1715,7 +1715,7 @@ { "name": "WriteDraftReplyEmail", "qualifiedName": "Gmail.WriteDraftReplyEmail", - "fullyQualifiedName": "Gmail.WriteDraftReplyEmail@7.1.0", + "fullyQualifiedName": "Gmail.WriteDraftReplyEmail@7.3.0", "description": "Compose a draft reply to an email message, optionally with one or more file attachments.\n\nTo attach files, pass ``attachments`` and give each file's local path as a\n``file://`` URI in ``source`` (formatted ``file:///absolute/path/to/file``). The\nfile's bytes are read and substituted on the client before the request is sent, so\nthe contents never pass through this conversation. Do not read, encode, or inline\nthe bytes yourself.", "parameters": [ { @@ -1891,6 +1891,6 @@ "import ScopePicker from \"@/app/_components/scope-picker\";" ], "subPages": [], - "generatedAt": "2026-06-10T12:11:53.002Z", + "generatedAt": "2026-06-13T11:44:22.760Z", "summary": "The Gmail toolkit provides Arcade LLM tools for interacting with a user's Gmail account via the Gmail API. It enables reading, composing, sending, organizing, and searching email — covering the full message and draft lifecycle.\n\n## Capabilities\n\n- **Reading & searching:** List emails, threads, and drafts with built-in automated-email filtering (no-reply senders, non-primary categories); search threads by query or header; retrieve full threads by ID; toggle automated filtering with `exclude_automated=False`.\n- **Composing & sending:** Send emails directly or via draft, reply to messages (including draft replies), with support for file attachments supplied as `file://` URIs — file bytes are read client-side and never pass through the conversation.\n- **Draft management:** Create, update, list, send, and delete drafts; update supports subject, body, recipients, cc, and bcc with partial updates (omit fields to preserve them); body replacement handles plain-text and single-part HTML drafts with auto-conversion; multipart/attachment drafts support metadata-only updates.\n- **Label management:** List, create, and apply/remove labels on messages.\n- **Account info:** Retrieve the authenticated user's profile, email address, Gmail statistics, and profile picture via `WhoAmI`.\n- **Trash:** Move messages to trash.\n\n## OAuth\n\nThis toolkit uses OAuth 2.0 via Google. See the [Arcade Google auth provider docs](https://docs.arcade.dev/en/references/auth-providers/google) for setup details." } \ No newline at end of file diff --git a/toolkit-docs-generator/data/toolkits/googlesheets.json b/toolkit-docs-generator/data/toolkits/googlesheets.json index aedb0d195..2bd2202dd 100644 --- a/toolkit-docs-generator/data/toolkits/googlesheets.json +++ b/toolkit-docs-generator/data/toolkits/googlesheets.json @@ -1,7 +1,7 @@ { "id": "GoogleSheets", "label": "Google Sheets", - "version": "8.0.0", + "version": "8.2.0", "description": "Arcade.dev LLM tools for Google Sheets.", "metadata": { "category": "productivity", @@ -23,10 +23,193 @@ ] }, "tools": [ + { + "name": "CheckSpreadsheetAccess", + "qualifiedName": "GoogleSheets.CheckSpreadsheetAccess", + "fullyQualifiedName": "GoogleSheets.CheckSpreadsheetAccess@8.2.0", + "description": "Check whether this app can already read each of several spreadsheets, in one\nbatched pre-flight call, before attempting to read them.\n\nUse this when the user references multiple spreadsheets so any that are not yet\naccessible can be granted together in a single picker step, instead of hitting a\nseparate access error and grant prompt for each one. Each input may be a bare file id\nor a full Google Sheets/Drive URL.\n\nReturns ``spreadsheets`` (a per-id list with ``accessible``, the ``title`` and\n``mime_type`` when the file was read, and a ``reason`` when not usable),\n``all_accessible`` (true only when every id is an already-accessible spreadsheet),\n``connected_account_email`` (the connected Google account, empty when unknown), and a\n``grant`` block. ``grant`` is empty when nothing needs granting; otherwise it lists the\nungranted ids (``ungranted_ids``) plus, when the inline picker is enabled, a single\npicker URL covering them all.\n\nA ``reason`` of ``not_accessible_or_not_found`` is either a file not granted to this app\nyet or one that does not exist (indistinguishable here) — the picker resolves the\nformer. ``not_a_spreadsheet`` is an accessible file of another type (a Doc, PDF, image,\nor Excel/CSV file); granting cannot change a type, so for an Excel/CSV file ask the user\nto open it in Google Sheets and use File, Save as Google Sheets, then share the\nconverted file. ``invalid_reference`` is an input that is not a Drive id or link at all;\nask the user to re-check it.", + "parameters": [ + { + "name": "spreadsheets", + "type": "array", + "innerType": "string", + "required": true, + "description": "The spreadsheets to check access for, each given as a bare spreadsheet id or a full Google Sheets/Drive URL (the id is extracted from the URL). Provide at most 50 per call; split larger lists across multiple calls.", + "enum": null, + "inferrable": true + } + ], + "auth": { + "providerId": "google", + "providerType": "oauth2", + "scopes": [ + "https://www.googleapis.com/auth/drive.file" + ] + }, + "secrets": [ + "ENABLE_GOOGLE_DRIVE_INLINE_PICKER_URL" + ], + "secretsInfo": [ + { + "name": "ENABLE_GOOGLE_DRIVE_INLINE_PICKER_URL", + "type": "token" + } + ], + "output": { + "type": "json", + "description": "Per-id accessibility (`spreadsheets`), an `all_accessible` flag, the `connected_account_email` (the Google account this app is connected through), and a `grant` block — empty when nothing needs granting, otherwise listing the ungranted ids with one consolidated picker URL covering them all." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "GoogleSheets.CheckSpreadsheetAccess", + "parameters": { + "spreadsheets": { + "value": [ + "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms", + "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms/edit", + "https://drive.google.com/file/d/1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R9S0T/view", + "1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R9S0T" + ], + "type": "array", + "required": true + } + }, + "requiresAuth": true, + "authProvider": "google", + "tabLabel": "Call the Tool with User Authorization" + }, + "metadata": { + "classification": { + "serviceDomains": [ + "spreadsheets" + ] + }, + "behavior": { + "operations": [ + "read" + ], + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "CommentOnSpreadsheet", + "qualifiedName": "GoogleSheets.CommentOnSpreadsheet", + "fullyQualifiedName": "GoogleSheets.CommentOnSpreadsheet@8.2.0", + "description": "Create a comment on a spreadsheet, edit a comment's body, or resolve/reopen it.\n\nComments are created at the file level: the Drive API cannot anchor a NEW Sheets comment to a\nspecific cell or range. Cell/range-anchored comments made in the Sheets UI are still readable\nvia list_spreadsheet_comments (which returns their anchor). Editing a comment's body is\nallowed only for the comment's author.", + "parameters": [ + { + "name": "spreadsheet_id", + "type": "string", + "required": true, + "description": "The id of the spreadsheet to comment on.", + "enum": null, + "inferrable": true + }, + { + "name": "comment_id", + "type": "string", + "required": false, + "description": "Omit to CREATE a new comment. Provide an existing comment id to edit it (pass content) or to resolve/reopen it (pass status).", + "enum": null, + "inferrable": true + }, + { + "name": "content", + "type": "string", + "required": false, + "description": "The comment text. Required when creating. When editing an existing comment (comment_id set, no status) this replaces the body (author-only). When a status is set, this is the optional text of the resolving/reopening reply.", + "enum": null, + "inferrable": true + }, + { + "name": "status", + "type": "string", + "required": false, + "description": "Resolve or reopen an existing comment (requires comment_id). Implemented as a reply with an action. Omit to create or edit instead.", + "enum": [ + "resolve", + "reopen" + ], + "inferrable": true + } + ], + "auth": { + "providerId": "google", + "providerType": "oauth2", + "scopes": [ + "https://www.googleapis.com/auth/drive.file" + ] + }, + "secrets": [ + "ENABLE_GOOGLE_DRIVE_INLINE_PICKER_URL" + ], + "secretsInfo": [ + { + "name": "ENABLE_GOOGLE_DRIVE_INLINE_PICKER_URL", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "The affected comment id, any created reply id, the action taken, the resolved state, and the spreadsheet URL." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "GoogleSheets.CommentOnSpreadsheet", + "parameters": { + "spreadsheet_id": { + "value": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms", + "type": "string", + "required": true + }, + "comment_id": { + "value": "AAAABhJGg3E", + "type": "string", + "required": false + }, + "content": { + "value": "Please review the Q3 figures in this section.", + "type": "string", + "required": false + }, + "status": { + "value": "resolved", + "type": "string", + "required": false + } + }, + "requiresAuth": true, + "authProvider": "google", + "tabLabel": "Call the Tool with User Authorization" + }, + "metadata": { + "classification": { + "serviceDomains": [ + "spreadsheets" + ] + }, + "behavior": { + "operations": [ + "create", + "update" + ], + "readOnly": false, + "destructive": false, + "idempotent": false, + "openWorld": true + }, + "extras": null + } + }, { "name": "CreateOrEditSpreadsheet", "qualifiedName": "GoogleSheets.CreateOrEditSpreadsheet", - "fullyQualifiedName": "GoogleSheets.CreateOrEditSpreadsheet@8.0.0", + "fullyQualifiedName": "GoogleSheets.CreateOrEditSpreadsheet@8.2.0", "description": "Create a new spreadsheet or batch-edit an existing one.\n\nOmit `spreadsheet_id` to create; provide it to edit. All writes flow through\n`requests[]` — typed operations like updateCells, addSheet, sortRange,\naddConditionalFormatRule, autoResizeDimensions, and more.\n\nFor updateCells use ExtendedValue with an explicit type field (stringValue,\nnumberValue, boolValue, formulaValue).\n\nBy default, build clean, professional-looking tables with restrained, consistent\nformatting and plain-text tab names/headers (no emojis); only use emojis or\ndecorative styling when the user explicitly asks for it.", "parameters": [ { @@ -474,11 +657,91 @@ "extras": null } }, + { + "name": "DeleteComment", + "qualifiedName": "GoogleSheets.DeleteComment", + "fullyQualifiedName": "GoogleSheets.DeleteComment@8.2.0", + "description": "Delete a comment from a spreadsheet.\n\nOnly the comment's author can delete it (enforced by Google Drive); deleting marks the\nwhole thread (the comment and its replies) as deleted.", + "parameters": [ + { + "name": "spreadsheet_id", + "type": "string", + "required": true, + "description": "The id of the spreadsheet the comment belongs to.", + "enum": null, + "inferrable": true + }, + { + "name": "comment_id", + "type": "string", + "required": true, + "description": "The id of the comment to delete.", + "enum": null, + "inferrable": true + } + ], + "auth": { + "providerId": "google", + "providerType": "oauth2", + "scopes": [ + "https://www.googleapis.com/auth/drive.file" + ] + }, + "secrets": [ + "ENABLE_GOOGLE_DRIVE_INLINE_PICKER_URL" + ], + "secretsInfo": [ + { + "name": "ENABLE_GOOGLE_DRIVE_INLINE_PICKER_URL", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "Confirmation of deletion and the spreadsheet URL." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "GoogleSheets.DeleteComment", + "parameters": { + "spreadsheet_id": { + "value": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms", + "type": "string", + "required": true + }, + "comment_id": { + "value": "AAAABmfu3hk", + "type": "string", + "required": true + } + }, + "requiresAuth": true, + "authProvider": "google", + "tabLabel": "Call the Tool with User Authorization" + }, + "metadata": { + "classification": { + "serviceDomains": [ + "spreadsheets" + ] + }, + "behavior": { + "operations": [ + "delete" + ], + "readOnly": false, + "destructive": true, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, { "name": "GenerateGoogleFilePickerUrl", "qualifiedName": "GoogleSheets.GenerateGoogleFilePickerUrl", - "fullyQualifiedName": "GoogleSheets.GenerateGoogleFilePickerUrl@8.0.0", - "description": "Generate a URL where the user can grant this app access to specific Drive files.\n\nOpens Google's first-party Drive picker. The user selects which files to share\nwith this application — it is not a sign-in or credential prompt.\n\nUse this when a prior tool reported that a file was not found or access was denied,\nand the user expects the file to exist. After the user completes the picker flow,\nretry the prior tool.", + "fullyQualifiedName": "GoogleSheets.GenerateGoogleFilePickerUrl@8.2.0", + "description": "Generate a URL where the user can grant this app access to spreadsheets.\n\nOpens Google's first-party Drive picker, filtered to Google Sheets, where the user\nbrowses and selects which spreadsheets to share with this application — it is not a\nsign-in or credential prompt.\n\nUse this when a prior tool reported that a file was not found or access was denied, and\nthe user expects the file to exist. After the user completes the picker flow, retry the\nprior operation.", "parameters": [], "auth": { "providerId": "google", @@ -520,7 +783,7 @@ { "name": "GetSpreadsheetEditHistory", "qualifiedName": "GoogleSheets.GetSpreadsheetEditHistory", - "fullyQualifiedName": "GoogleSheets.GetSpreadsheetEditHistory@8.0.0", + "fullyQualifiedName": "GoogleSheets.GetSpreadsheetEditHistory@8.2.0", "description": "Report who edited a spreadsheet and when, from Google Drive revisions.\n\nReports the \"who\" and \"when\" only — not which cells changed, and it can't revert.\n\n'summary' (default) answers \"who last edited this and when\" (read from the file's head,\nso always accurate), plus per-window aggregates (revisions read, contributors, first\nedit) and a preview of recent edits — computed over a bounded window of history per call.\nThese aggregates describe the whole history only when `is_incomplete` is false; it is\ntrue when the scan was resumed from a token and/or more history remains. To answer\n\"when was this first edited?\" or \"who contributed?\" reliably, call from the beginning\n(no `pagination_token`) and check `is_incomplete` is false. `pagination_token` is\nreturned when more pages remain so you can resume.\n\n'list' returns one page of individual revisions, oldest first. Drive can't sort\nnewest-first, so the most recent individual revisions are on the final page.", "parameters": [ { @@ -629,7 +892,7 @@ { "name": "InspectSpreadsheet", "qualifiedName": "GoogleSheets.InspectSpreadsheet", - "fullyQualifiedName": "GoogleSheets.InspectSpreadsheet@8.0.0", + "fullyQualifiedName": "GoogleSheets.InspectSpreadsheet@8.2.0", "description": "Inspect a Google Sheets spreadsheet's structure or read a range of cells.\n\nUse the default 'structure' mode to understand a workbook cheaply before reading.\nSwitch to 'read' mode to pull a range as a grid of rows, optionally with\nper-cell annotations and a rendered markdown/csv/tsv export.\n\nIn 'read' mode the response's per-tab 'sheets' block reports only tab identity and\nthe allocated grid; its scan-derived fields (used_range, populated_cell_count,\nformula_cell_count, first_row, table_regions) are placeholders (0/empty) because read\nmode does not scan the tab — they do NOT mean the tab is empty or that it has no\ntables. The data you read is in the top-level 'range' and 'rows'. Call 'structure'\nmode for those aggregates and for the workbook's charts, merges, protected ranges, and\nconditional formats.\n\nWorkflow for a tab that holds multiple tables, or a table that does not start at A1:\ncall 'structure' first and use that tab's estimated 'table_regions' to choose the\na1_range to read or filter, so you target one table instead of a glued multi-table\nrange.\n\nAlways check the response's top-level 'warnings' list: read mode reports there when a\nresult was capped or trimmed (cell budget, the per-cell annotation cap, or an empty\nfilter scan) and tells you how to recover (page 'next_range', narrow 'a1_range',\n'select_columns', or request fewer annotation kinds).", "parameters": [ { @@ -908,10 +1171,547 @@ "extras": null } }, + { + "name": "ListSpreadsheetComments", + "qualifiedName": "GoogleSheets.ListSpreadsheetComments", + "fullyQualifiedName": "GoogleSheets.ListSpreadsheetComments@8.2.0", + "description": "List a spreadsheet's comment threads, or the full replies of a single comment.\n\nIn 'comments' mode each comment includes up to a few trimmed reply previews plus the total reply_count; use 'thread' mode for a comment's complete reply list. Without filters/ordering, pagination walks every comment. Client-side filters (has_replies, resolved) and order_by are applied only within a bounded scan of the first 500 comments, so on larger sheets drop them and page through everything with the native (unbounded) pagination. Each comment's Drive anchor is returned when it was cell/range-anchored in the Sheets UI; comments created via the API are file-level. Filtering, ordering, and offset pagination are best-effort: results can drift if comments are added or removed between paginated calls.", + "parameters": [ + { + "name": "spreadsheet_id", + "type": "string", + "required": true, + "description": "The id of the spreadsheet whose comments to list.", + "enum": null, + "inferrable": true + }, + { + "name": "mode", + "type": "string", + "required": false, + "description": "'comments' (default) lists top-level comments, each with a capped reply preview and a reply_count. 'thread' lists the FULL replies of one comment (set comment_id).", + "enum": [ + "comments", + "thread" + ], + "inferrable": true + }, + { + "name": "comment_id", + "type": "string", + "required": false, + "description": "Required when mode='thread': the comment whose replies to list.", + "enum": null, + "inferrable": true + }, + { + "name": "limit", + "type": "integer", + "required": false, + "description": "Max comments (or replies, in thread mode) to return. Clamped to [1, 50].", + "enum": null, + "inferrable": true + }, + { + "name": "page_token", + "type": "string", + "required": false, + "description": "Opaque token from a previous call's page_token to fetch the next page.", + "enum": null, + "inferrable": true + }, + { + "name": "include_deleted", + "type": "boolean", + "required": false, + "description": "Include deleted comments/replies (their bodies are blank). Defaults to False.", + "enum": null, + "inferrable": true + }, + { + "name": "modified_after", + "type": "string", + "required": false, + "description": "Server-side filter: only comments modified at/after this RFC3339 time (e.g. '2025-01-01T00:00:00Z'). Comments mode only.", + "enum": null, + "inferrable": true + }, + { + "name": "has_replies", + "type": "boolean", + "required": false, + "description": "Client-side filter (comments mode): keep only comments that have (True) or lack (False) replies.", + "enum": null, + "inferrable": true + }, + { + "name": "resolved", + "type": "boolean", + "required": false, + "description": "Client-side filter (comments mode): keep only resolved (True) or unresolved (False) comments.", + "enum": null, + "inferrable": true + }, + { + "name": "comment_ids", + "type": "array", + "innerType": "string", + "required": false, + "description": "Fetch exactly these comments by id (comments mode), instead of paging. Replaces a dedicated get tool. At most 50 ids per call, and not combined with page_token.", + "enum": null, + "inferrable": true + }, + { + "name": "order_by", + "type": "string", + "required": false, + "description": "Client-side ordering (comments mode) by created/modified time, ascending or descending. Defaults to Drive's native order.", + "enum": [ + "created_time_asc", + "created_time_desc", + "modified_time_asc", + "modified_time_desc" + ], + "inferrable": true + }, + { + "name": "max_length", + "type": "integer", + "required": false, + "description": "Cap each returned comment/reply body (and quoted text) at this many characters. A longer body becomes '…(+N chars)' (suffix not counted; N = hidden chars). Pass 0 for full, untruncated text; a positive value below the floor (or negative) clamps up to the floor. Filtering still matches the FULL text. Defaults to 280.", + "enum": null, + "inferrable": true + } + ], + "auth": { + "providerId": "google", + "providerType": "oauth2", + "scopes": [ + "https://www.googleapis.com/auth/drive.file" + ] + }, + "secrets": [ + "ENABLE_GOOGLE_DRIVE_INLINE_PICKER_URL" + ], + "secretsInfo": [ + { + "name": "ENABLE_GOOGLE_DRIVE_INLINE_PICKER_URL", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "The matching comments (or replies) with pagination info." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "GoogleSheets.ListSpreadsheetComments", + "parameters": { + "spreadsheet_id": { + "value": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms", + "type": "string", + "required": true + }, + "mode": { + "value": "comments", + "type": "string", + "required": false + }, + "comment_id": { + "value": "AAAABx3Kz7E", + "type": "string", + "required": false + }, + "limit": { + "value": 25, + "type": "integer", + "required": false + }, + "page_token": { + "value": "CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA", + "type": "string", + "required": false + }, + "include_deleted": { + "value": false, + "type": "boolean", + "required": false + }, + "modified_after": { + "value": "2025-01-01T00:00:00Z", + "type": "string", + "required": false + }, + "has_replies": { + "value": true, + "type": "boolean", + "required": false + }, + "resolved": { + "value": false, + "type": "boolean", + "required": false + }, + "comment_ids": { + "value": [ + "AAAABx3Kz7E", + "AAAACy4Lw8F", + "AAAADz5Mx9G" + ], + "type": "array", + "required": false + }, + "order_by": { + "value": "modifiedTime desc", + "type": "string", + "required": false + }, + "max_length": { + "value": 280, + "type": "integer", + "required": false + } + }, + "requiresAuth": true, + "authProvider": "google", + "tabLabel": "Call the Tool with User Authorization" + }, + "metadata": { + "classification": { + "serviceDomains": [ + "spreadsheets" + ] + }, + "behavior": { + "operations": [ + "read" + ], + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "ReplyToComment", + "qualifiedName": "GoogleSheets.ReplyToComment", + "fullyQualifiedName": "GoogleSheets.ReplyToComment@8.2.0", + "description": "Add a reply to an existing comment on a spreadsheet.\n\nTo resolve or reopen the comment instead, use comment_on_spreadsheet with a status.", + "parameters": [ + { + "name": "spreadsheet_id", + "type": "string", + "required": true, + "description": "The id of the spreadsheet the comment belongs to.", + "enum": null, + "inferrable": true + }, + { + "name": "comment_id", + "type": "string", + "required": true, + "description": "The id of the comment to reply to.", + "enum": null, + "inferrable": true + }, + { + "name": "reply_text", + "type": "string", + "required": true, + "description": "The text of the reply.", + "enum": null, + "inferrable": true + } + ], + "auth": { + "providerId": "google", + "providerType": "oauth2", + "scopes": [ + "https://www.googleapis.com/auth/drive.file" + ] + }, + "secrets": [ + "ENABLE_GOOGLE_DRIVE_INLINE_PICKER_URL" + ], + "secretsInfo": [ + { + "name": "ENABLE_GOOGLE_DRIVE_INLINE_PICKER_URL", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "The created reply id, its comment id, and the URL." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "GoogleSheets.ReplyToComment", + "parameters": { + "spreadsheet_id": { + "value": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms", + "type": "string", + "required": true + }, + "comment_id": { + "value": "AAAABmFtCjc", + "type": "string", + "required": true + }, + "reply_text": { + "value": "Thanks for the note! I've updated the values in column C to reflect the latest figures.", + "type": "string", + "required": true + } + }, + "requiresAuth": true, + "authProvider": "google", + "tabLabel": "Call the Tool with User Authorization" + }, + "metadata": { + "classification": { + "serviceDomains": [ + "spreadsheets" + ] + }, + "behavior": { + "operations": [ + "create" + ], + "readOnly": false, + "destructive": false, + "idempotent": false, + "openWorld": true + }, + "extras": null + } + }, + { + "name": "ScanForDataIssues", + "qualifiedName": "GoogleSheets.ScanForDataIssues", + "fullyQualifiedName": "GoogleSheets.ScanForDataIssues@8.2.0", + "description": "Deterministically flag 'weird'/bad cells in spreadsheet data.\n\nNo LLM judgement: the same input always returns the same flags. Each cell-level finding\ncarries a coord, a 0-based row_index/column_index (ready for a Sheets GridRange), the rule,\na severity (high -> red, medium/low -> yellow), and a note-ready reason — so the output\ndrops straight into an annotate/format recipe. In the default `mode='grouped'` these are\naggregated per rule+column within each table into `groups` (with A1 `coords`); use\n`mode='list'` to get every flagged cell in `flags` with its 0-based indices.\n\nProvide `spreadsheet_id` to scan a live sheet (scan one tab via sheet_id/sheet_title, or\nevery tab when both are omitted). Set `orientation='rows'` for transposed tables whose\nfields run down a column instead of across a row. Findings come back as flags (cell-level,\nhigh certainty) and alerts (table-level, lower certainty), grouped sheet -> table -> rule.\n\nIn all-sheets mode an unreadable tab never aborts the scan: its title is collected in\n`failed_sheets` (and echoed as a `warnings` entry) while every other tab still returns.\n`failed_sheets` is empty for a single-tab scan and whenever every tab reads cleanly.", + "parameters": [ + { + "name": "spreadsheet_id", + "type": "string", + "required": true, + "description": "The id of the spreadsheet to scan. Scan one tab via sheet_id/sheet_title, or every tab when both are omitted.", + "enum": null, + "inferrable": true + }, + { + "name": "sheet_id", + "type": "integer", + "required": false, + "description": "Scan only this tab (by numeric sheetId). Mutually exclusive with sheet_title. Omit both to scan every tab, grouped by sheet.", + "enum": null, + "inferrable": true + }, + { + "name": "sheet_title", + "type": "string", + "required": false, + "description": "Scan only this tab (by name). Mutually exclusive with sheet_id. Omit both to scan every tab.", + "enum": null, + "inferrable": true + }, + { + "name": "a1_range", + "type": "string", + "required": false, + "description": "Single-sheet only: limit the analysis window (e.g. 'A1:F100'). Table detection still runs inside it; scope it to a single table's range for a precise scan. Defaults to the tab's used range.", + "enum": null, + "inferrable": true + }, + { + "name": "treat_range_as_single_table", + "type": "boolean", + "required": false, + "description": "Single-sheet only: treat the whole a1_range as ONE table, skipping auto-detection. Use when detection would over-split a table that has an interior blank row. Defaults to False.", + "enum": null, + "inferrable": true + }, + { + "name": "mode", + "type": "string", + "required": false, + "description": "'grouped' (default) aggregates findings per rule+column within each table with counts; 'list' enumerates every flagged cell.", + "enum": [ + "list", + "grouped" + ], + "inferrable": true + }, + { + "name": "rules", + "type": "array", + "innerType": "string", + "required": false, + "description": "Which deterministic checks to run. Omit to run every check. Each is fully reproducible (no LLM judgement).", + "enum": [ + "error_value", + "text_sentinel", + "parenthesized_number", + "number_stored_as_text", + "whitespace", + "type_outlier", + "formula_outlier", + "date_serial", + "gap", + "repeated_header", + "inconsistent_column" + ], + "inferrable": true + }, + { + "name": "has_header", + "type": "boolean", + "required": false, + "description": "Treat each detected table's first row as labels (never flagged as a type outlier). Defaults to True.", + "enum": null, + "inferrable": true + }, + { + "name": "orientation", + "type": "string", + "required": false, + "description": "'columns' (default): records are rows, fields are columns. 'rows': the table is transposed — records are columns and fields are rows (row labels down column A). Applies to the whole scan, not per-table (one setting for every table on the tab). Coords are always reported in the sheet's real coordinates.", + "enum": [ + "columns", + "rows" + ], + "inferrable": true + }, + { + "name": "max_items_per_group", + "type": "integer", + "required": false, + "description": "Grouped mode: max cell coords listed per rule+column (within a table) before an 'omitted' count. Defaults to 10, hard-capped at 50.", + "enum": null, + "inferrable": true + }, + { + "name": "max_rows", + "type": "integer", + "required": false, + "description": "Max rows scanned per tab (applies to every scanned tab). Defaults to 200, floored to 1.", + "enum": null, + "inferrable": true + } + ], + "auth": { + "providerId": "google", + "providerType": "oauth2", + "scopes": [ + "https://www.googleapis.com/auth/drive.file" + ] + }, + "secrets": [ + "ENABLE_GOOGLE_DRIVE_INLINE_PICKER_URL" + ], + "secretsInfo": [ + { + "name": "ENABLE_GOOGLE_DRIVE_INLINE_PICKER_URL", + "type": "api_key" + } + ], + "output": { + "type": "json", + "description": "Deterministic data-issue flags, grouped sheet -> table -> rule." + }, + "documentationChunks": [], + "codeExample": { + "toolName": "GoogleSheets.ScanForDataIssues", + "parameters": { + "spreadsheet_id": { + "value": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms", + "type": "string", + "required": true + }, + "sheet_id": { + "value": 0, + "type": "integer", + "required": false + }, + "sheet_title": { + "value": "Sales Data Q1", + "type": "string", + "required": false + }, + "a1_range": { + "value": "A1:F100", + "type": "string", + "required": false + }, + "treat_range_as_single_table": { + "value": false, + "type": "boolean", + "required": false + }, + "mode": { + "value": "grouped", + "type": "string", + "required": false + }, + "rules": { + "value": [ + "blank", + "type_outlier", + "duplicate", + "out_of_range" + ], + "type": "array", + "required": false + }, + "has_header": { + "value": true, + "type": "boolean", + "required": false + }, + "orientation": { + "value": "columns", + "type": "string", + "required": false + }, + "max_items_per_group": { + "value": 10, + "type": "integer", + "required": false + }, + "max_rows": { + "value": 200, + "type": "integer", + "required": false + } + }, + "requiresAuth": true, + "authProvider": "google", + "tabLabel": "Call the Tool with User Authorization" + }, + "metadata": { + "classification": { + "serviceDomains": [ + "spreadsheets" + ] + }, + "behavior": { + "operations": [ + "read" + ], + "readOnly": true, + "destructive": false, + "idempotent": true, + "openWorld": true + }, + "extras": null + } + }, { "name": "SearchSpreadsheets", "qualifiedName": "GoogleSheets.SearchSpreadsheets", - "fullyQualifiedName": "GoogleSheets.SearchSpreadsheets@8.0.0", + "fullyQualifiedName": "GoogleSheets.SearchSpreadsheets@8.2.0", "description": "Searches for spreadsheets in the user's Google Drive based on the titles and content and\nreturns the title, ID, and URL for each matching spreadsheet.\n\nDoes not return the content/data of the sheets in the spreadsheets - only the metadata.\nExcludes spreadsheets that are in the trash.", "parameters": [ { @@ -1104,7 +1904,7 @@ { "name": "WhoAmI", "qualifiedName": "GoogleSheets.WhoAmI", - "fullyQualifiedName": "GoogleSheets.WhoAmI@8.0.0", + "fullyQualifiedName": "GoogleSheets.WhoAmI@8.2.0", "description": "Get comprehensive user profile and Google Sheets environment information.\n\nThis tool provides detailed information about the authenticated user including\ntheir name, email, profile picture, Google Sheets access permissions, and other\nimportant profile details from Google services.", "parameters": [], "auth": { @@ -1154,6 +1954,6 @@ "import ScopePicker from \"@/app/_components/scope-picker\";" ], "subPages": [], - "generatedAt": "2026-06-10T12:12:15.675Z", - "summary": "**Google Sheets toolkit** connects Arcade to Google Sheets (and Drive), enabling LLMs to create, read, edit, search, and audit spreadsheets on behalf of authenticated users.\n\n## Capabilities\n\n- **Spreadsheet creation & editing** — Create new spreadsheets or batch-edit existing ones using typed cell operations (updateCells, addSheet, sortRange, addConditionalFormatRule, autoResizeDimensions, and more); supports formulas, formatting, and structured table layouts.\n- **Structure inspection & data reading** — Inspect workbook structure (tabs, charts, merges, conditional formats, table regions) cheaply before reading, then pull specific cell ranges as grids with optional annotations and markdown/CSV/TSV export.\n- **Search & discovery** — Search a user's Google Drive for spreadsheets by title or content, returning metadata (title, ID, URL); excludes trashed files.\n- **Edit history auditing** — Retrieve revision history (contributor identity and timestamps) from Drive; supports summary mode (aggregates, recent preview) and paginated list mode for full history traversal.\n- **Drive file picker integration** — Generate a first-party Google Drive Picker URL to let users grant file-level access when a file is not found or access is denied, enabling retry flows.\n- **User profile & permissions** — Retrieve the authenticated user's name, email, profile picture, and Google Sheets access permissions.\n\n## OAuth\n\nThis toolkit uses **OAuth 2.0** via Google. See the [Arcade Google auth provider docs](https://docs.arcade.dev/en/references/auth-providers/google) for setup details.\n\n## Secrets\n\n`ENABLE_GOOGLE_DRIVE_INLINE_PICKER_URL`\n\nThis secret is a **URL override or feature flag value** that controls the behavior of the inline Google Drive Picker flow used by `GoogleSheets.GenerateGoogleFilePickerUrl`. It is not a credential issued by Google — it is a configuration value set by the developer (or Arcade platform operator) to enable or customize the picker URL endpoint used internally. Set this in your Arcade secrets configuration; no specific Google dashboard page issues it.\n\nSee the [Arcade secrets configuration docs](https://docs.arcade.dev/en/guides/create-tools/tool-basics/create-tool-secrets) for how to define and manage secrets, and the [Arcade secrets dashboard](https://api.arcade.dev/dashboard/auth/secrets) to set values." + "generatedAt": "2026-06-13T11:44:29.054Z", + "summary": "**Google Sheets** is an Arcade toolkit that lets LLM agents read, write, and manage Google Sheets spreadsheets and their metadata through the Google Drive and Sheets APIs.\n\n## Capabilities\n\n- **Spreadsheet discovery & access checks** — search Drive for spreadsheets by title/content, pre-flight batch-check access to multiple files before reading, and retrieve authenticated user profile and permission info.\n- **Read & inspect** — inspect workbook structure (tabs, charts, merges, conditional formats, table regions) or read arbitrary cell ranges as grids with optional per-cell annotations and markdown/CSV/TSV export.\n- **Write & create** — create new spreadsheets or batch-edit existing ones via the full Sheets batchUpdate API (cell values, formatting, sheets, sorting, conditional rules, auto-resize, and more).\n- **Data quality scanning** — deterministically flag bad/weird cells (nulls, type mismatches, outliers, etc.) with severity levels and GridRange-ready coordinates for downstream annotation workflows.\n- **Edit history** — retrieve revision history summarized or paginated, reporting contributors and timestamps (not cell-level diffs).\n- **Comments & collaboration** — list, create, edit, resolve/reopen, reply to, and delete comment threads; generate a Google Drive file-picker URL to grant spreadsheet access inline.\n\n## OAuth\n\nUses OAuth 2.0 via the **Google** provider. See the [Arcade Google auth provider docs](https://docs.arcade.dev/en/references/auth-providers/google) for setup details.\n\n## Secrets\n\n### `ENABLE_GOOGLE_DRIVE_INLINE_PICKER_URL`\n\nA feature-flag secret that controls whether the inline Google Drive file-picker URL is generated and returned inside the `grant` block of `CheckSpreadsheetAccess` and `GenerateGoogleFilePickerUrl`. When set, those tools can return a single picker URL that lets users grant access to one or more spreadsheets without leaving the agent conversation flow.\n\nThis is **not** a credential issued by Google — it is a configuration value you set yourself in your Arcade deployment to opt in to the inline picker feature. Set it to a truthy value (e.g. `\"true\"` or `\"1\"`) in your Arcade secrets store to enable the behavior. No specific Google dashboard page or OAuth scope is required to obtain it.\n\nSee the [Arcade secrets guide](https://docs.arcade.dev/en/guides/create-tools/tool-basics/create-tool-secrets) for how to configure secrets, and manage your values at [https://api.arcade.dev/dashboard/auth/secrets](https://api.arcade.dev/dashboard/auth/secrets)." } \ No newline at end of file diff --git a/toolkit-docs-generator/data/toolkits/index.json b/toolkit-docs-generator/data/toolkits/index.json index 773a9dac0..ff80af4d6 100644 --- a/toolkit-docs-generator/data/toolkits/index.json +++ b/toolkit-docs-generator/data/toolkits/index.json @@ -1,5 +1,5 @@ { - "generatedAt": "2026-06-12T12:12:05.661Z", + "generatedAt": "2026-06-13T11:44:44.967Z", "version": "1.0.0", "toolkits": [ { @@ -137,6 +137,15 @@ "toolCount": 14, "authType": "oauth2" }, + { + "id": "CursorAgents", + "label": "Cursor Agents", + "version": "0.1.0", + "category": "development", + "type": "arcade", + "toolCount": 16, + "authType": "none" + }, { "id": "CursorAgentsApi", "label": "Cursor Agents API", @@ -326,10 +335,19 @@ "toolCount": 818, "authType": "oauth2" }, + { + "id": "Glean", + "label": "Glean", + "version": "0.2.0", + "category": "search", + "type": "arcade", + "toolCount": 1, + "authType": "oauth2" + }, { "id": "Gmail", "label": "Gmail", - "version": "7.1.0", + "version": "7.3.0", "category": "productivity", "type": "arcade", "toolCount": 18, @@ -437,10 +455,10 @@ { "id": "GoogleSheets", "label": "Google Sheets", - "version": "8.0.0", + "version": "8.2.0", "category": "productivity", "type": "arcade", - "toolCount": 6, + "toolCount": 12, "authType": "oauth2" }, {