@mcp-s/connectors 0.0.20261022190708 → 0.0.20261024071613

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"id":"gmail","status":"active","internal_status":"tool-works","applications":["gmail"],"definition":{"display":{"name":"Gmail","description":"Gmail is a web-based email service developed by Google.","icon":"gmail.svg","website":"https://www.gmail.com","category":"communication-messaging","docs_url":"https://docs.withwillow.ai/docs/mcp-servers/built-in/gmail"},"api":{"base_url":"https://gmail.googleapis.com/gmail/v1"},"auth":{"methods":{"oauth":{"authUrl":"https://accounts.google.com/o/oauth2/v2/auth","tokenUrl":"https://oauth2.googleapis.com/token","authInitUrlParams":{"access_type":"offline","prompt":"consent"},"scopes":["https://www.googleapis.com/auth/gmail.addons.current.action.compose","https://www.googleapis.com/auth/gmail.addons.current.message.action","https://www.googleapis.com/auth/gmail.addons.current.message.metadata","https://www.googleapis.com/auth/gmail.addons.current.message.readonly","https://www.googleapis.com/auth/gmail.labels","https://www.googleapis.com/auth/gmail.send","https://www.googleapis.com/auth/gmail.readonly","https://www.googleapis.com/auth/gmail.compose","https://www.googleapis.com/auth/gmail.insert","https://www.googleapis.com/auth/gmail.modify","https://www.googleapis.com/auth/gmail.metadata","https://www.googleapis.com/auth/gmail.settings.basic","https://www.googleapis.com/auth/gmail.settings.sharing"],"defaultScopes":["https://www.googleapis.com/auth/gmail.modify","https://www.googleapis.com/auth/gmail.settings.basic"],"codeExchangeConfig":{"modelCredentialsMapping":"{\n \"access_token\": access_token, \n \"expires_at\": $fromMillis($millis() + expires_in * 1000),\n \"refresh_token\": refresh_token,\n \"refresh_token_expires_at\": $fromMillis($millis() + refresh_token_expires_in * 1000),\n \"scope\": scope,\n \"token_type\": token_type\n }"}}}},"conditions":[{"id":"block-labeled-messages","name":"Block messages with restricted labels","description":"Before reading an email, fetch its label ids and block the call when the message carries one of the configured restricted labels (e.g. a 'Confidential' label).","action":{"path":"/users/me/messages/{messageId}","method":"GET","mapping":{"params":"{ \"messageId\": arguments.messageId }","query":"{ \"format\": \"metadata\" }"}},"mapping":"$count(response.labelIds[$ in $$.variables.blockedLabelIds]) > 0","message":"This email carries a restricted label and cannot be accessed by this tool.","variables":[{"key":"blockedLabelIds","label":"Restricted label ids","description":"Gmail label ids (e.g. SPAM, CATEGORY_PERSONAL, or a custom Label_xxx) that block access to a message.","type":"string[]","required":true,"placeholder":"SPAM, Label_12345"}],"appliesTo":["read-email","list-gmail-attachments","get-gmail-attachment"]}],"tools":[{"name":"sendGmailMessage","enabled":true,"description":"Send an email message using Gmail.","slug":"send-gmail-message","ai_risk":{"level":"medium","score":6,"reasoning":"This tool sends an email message, which can be considered high risk as it can potentially lead to spam or misuse if misconfigured.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"to":{"type":"string","description":"Comma-separated list of recipient email addresses."},"cc":{"type":"string","description":"Comma-separated list of CC email addresses."},"bcc":{"type":"string","description":"Comma-separated list of BCC email addresses."},"subject":{"type":"string","description":"The subject line of the email."},"body":{"type":"string","description":"The plain text body of the email."},"threadId":{"type":"string","description":"Optional thread ID to send the message as a reply."},"labelIds":{"type":"array","items":{"type":"string"},"description":"Optional list of label IDs to apply to the sent message."}},"required":["to","subject","body"]},"risk":"high","action":{"path":"/users/me/messages/send","method":"POST","mapping":{"body":"{\n \"raw\": $base64encode(\n \"To: \" & arguments.to & \"\r\n\" &\n ($exists(arguments.cc) and arguments.cc ? \"Cc: \" & arguments.cc & \"\r\n\" : \"\") &\n ($exists(arguments.bcc) and arguments.bcc ? \"Bcc: \" & arguments.bcc & \"\r\n\" : \"\") &\n \"Subject: \" & arguments.subject & \"\r\n\" &\n \"\r\n\" &\n arguments.body\n ),\n \"threadId\": arguments.threadId,\n \"labelIds\": arguments.labelIds\n}"}},"annotations":{"destructiveHint":true,"openWorldHint":true}},{"name":"createGmailDraft","enabled":true,"description":"Create a draft email message using Gmail.","slug":"create-gmail-draft","ai_risk":{"level":"medium","score":5,"reasoning":"Creating a draft email is a standard write operation, posing medium risk as it modifies user data but does not send it.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"to":{"type":"string","description":"Comma-separated list of recipient email addresses."},"cc":{"type":"string","description":"Comma-separated list of CC email addresses."},"bcc":{"type":"string","description":"Comma-separated list of BCC email addresses."},"subject":{"type":"string","description":"The subject line of the email."},"body":{"type":"string","description":"The plain text body of the email."},"threadId":{"type":"string","description":"Optional thread ID to send the message as a reply."},"labelIds":{"type":"array","items":{"type":"string"},"description":"Optional list of label IDs to apply to the sent message."}},"required":["to","subject","body"]},"action":{"path":"/users/me/drafts","method":"POST","mapping":{"body":"{\n \"message\": {\n \"raw\": $base64encode(\n \"To: \" & arguments.to & \"\r\n\" &\n ($exists(arguments.cc) and arguments.cc ? \"Cc: \" & arguments.cc & \"\r\n\" : \"\") &\n ($exists(arguments.bcc) and arguments.bcc ? \"Bcc: \" & arguments.bcc & \"\r\n\" : \"\") &\n \"Subject: \" & arguments.subject & \"\r\n\" &\n \"\r\n\" &\n arguments.body\n ),\n \"threadId\": arguments.threadId,\n \"labelIds\": arguments.labelIds\n}\n }"}},"annotations":{"destructiveHint":true}},{"name":"readEmail","enabled":true,"description":"Read an email message using Gmail.","slug":"read-email","ai_risk":{"level":"low","score":1,"reasoning":"This tool reads an email message, making it low risk as it only fetches data without modifying anything.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"messageId":{"type":"string","description":"The ID of the email message to read."}}},"action":{"path":"/users/me/messages/{messageId}","method":"GET","mapping":{"params":"{\n \"messageId\": arguments.messageId\n }","response":"(\n $header := function($name) { response.payload.headers[name = $name].value };\n $body := response.payload.body.data\n ? $base64decode(response.payload.body.data)\n : $join(response.payload.parts.(body.data ? $base64decode(body.data) : ''), '\n');\n {\n \"id\": response.id,\n \"threadId\": response.threadId,\n \"labelIds\": response.labelIds,\n \"snippet\": response.snippet,\n \"from\": $header(\"From\"),\n \"to\": $header(\"To\"),\n \"cc\": $header(\"Cc\"),\n \"subject\": $header(\"Subject\"),\n \"date\": $header(\"Date\"),\n \"internalDate\": response.internalDate,\n \"mimeType\": response.payload.mimeType,\n \"body\": $body\n }\n )"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"listGmailAttachments","enabled":true,"description":"List file attachments on a Gmail message. Returns metadata for each attachment including filename, MIME type, attachment ID, and size. Use 'getGmailAttachment' with the attachment ID to download the file content. Optionally filter by MIME type (e.g. 'application/pdf' for PDF files).","slug":"list-gmail-attachments","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists attachment metadata on an email message without downloading file content.","calculated_at":"2026-07-28T08:00:00.000Z"},"inputSchema":{"type":"object","properties":{"messageId":{"type":"string","description":"The ID of the email message to list attachments from."},"mimeType":{"type":"string","description":"Optional MIME type filter (e.g. 'application/pdf' to list only PDF attachments)."}},"required":["messageId"]},"action":{"path":"/users/me/messages/{messageId}","method":"GET","mapping":{"params":"{\n \"messageId\": arguments.messageId\n }","query":"{\n \"format\": \"full\"\n }","response":"(\n $flatten := function($parts) { (\n $direct := $parts[filename or body.attachmentId].{\n \"filename\": filename,\n \"mimeType\": mimeType,\n \"attachmentId\": body.attachmentId,\n \"size\": body.size,\n \"hasInlineData\": $boolean(body.data)\n };\n $nested := $parts.parts.($count($) > 0 ? $flatten($) : []);\n $append($direct, $nested)\n )};\n $attachments := response.payload.parts\n ? $flatten(response.payload.parts)\n : (\n response.payload.filename or response.payload.body.attachmentId\n )\n ? [{\n \"filename\": response.payload.filename,\n \"mimeType\": response.payload.mimeType,\n \"attachmentId\": response.payload.body.attachmentId,\n \"size\": response.payload.body.size,\n \"hasInlineData\": $boolean(response.payload.body.data)\n }]\n : [];\n $filtered := $filter($attachments, function($a) {\n $not($exists($$.arguments.mimeType) and $$.arguments.mimeType)\n or $a.mimeType = $$.arguments.mimeType\n });\n {\n \"messageId\": response.id,\n \"attachments\": $filtered\n }\n )"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"getGmailAttachment","enabled":true,"description":"Download a file attachment from a Gmail message. Returns the attachment content as a base64url-encoded string in the 'data' field. Use 'listGmailAttachments' first to find the attachment ID. Decode the data with a base64url decoder to save the file locally.","slug":"get-gmail-attachment","ai_risk":{"level":"low","score":1,"reasoning":"This tool downloads an email attachment and is read-only.","calculated_at":"2026-07-28T08:00:00.000Z"},"inputSchema":{"type":"object","properties":{"messageId":{"type":"string","description":"The ID of the email message containing the attachment."},"attachmentId":{"type":"string","description":"The attachment ID from 'listGmailAttachments'. Required for attachments stored separately from the message body."}},"required":["messageId","attachmentId"]},"action":{"path":"/users/me/messages/{messageId}/attachments/{attachmentId}","method":"GET","mapping":{"params":"{\n \"messageId\": arguments.messageId,\n \"attachmentId\": arguments.attachmentId\n }","response":"{\n \"attachmentId\": response.attachmentId ? response.attachmentId : arguments.attachmentId,\n \"size\": response.size,\n \"data\": response.data,\n \"encoding\": \"base64url\"\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"listEmails","enabled":true,"description":"List email messages using Gmail.","slug":"list-emails","ai_risk":{"level":"low","score":1,"reasoning":"Listing email messages is a read-only operation, posing low risk as it does not alter any data.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"The query to search for email messages. Only return messages matching the specified query. Supports the same query format as the Gmail search box. For example, 'from:someuser@example.com rfc822msgid:<somemsgid@example.com> is:unread'."},"maxResults":{"type":"number","description":"The maximum number of results to return.","default":10}}},"action":{"path":"/users/me/messages","method":"GET","mapping":{"query":"{\n \"q\": arguments.query,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 10\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"listGmailDrafts","enabled":true,"description":"Lists draft emails from the authenticated user's Gmail account. Supports filtering by query string and pagination.","slug":"list-gmail-drafts","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists draft emails, which is a read-only operation and therefore low risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Optional query string to filter drafts, using the same format as the Gmail search bar (e.g. 'subject:Update', 'from:user@example.com', 'is:unread', 'has:attachment', 'after:YYYY/MM/DD'). If omitted, all drafts (excluding spam and trash by default) are listed."},"maxResults":{"type":"number","description":"The maximum number of drafts to return. Defaults to 20. The maximum allowed value is 50.","default":20,"minimum":1,"maximum":50},"pageToken":{"type":"string","description":"A token received from a previous list_drafts call to retrieve the next page of results. Leave empty to fetch the first page."},"includeSpamTrash":{"type":"boolean","description":"Include drafts from SPAM and TRASH in the results. Defaults to false."}}},"action":{"path":"/users/me/drafts","method":"GET","mapping":{"query":"{\n \"q\": arguments.query,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 20,\n \"pageToken\": arguments.pageToken,\n \"includeSpamTrash\": arguments.includeSpamTrash\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"getGmailThread","enabled":true,"description":"Retrieves a specific email thread from the authenticated user's Gmail account, including a list of its messages. Accepts either an API thread ID or a Gmail web link to the thread.","slug":"get-gmail-thread","ai_risk":{"level":"low","score":1,"reasoning":"Retrieving a specific email thread is a read-only action, posing low risk as it does not modify any data.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"threadId":{"type":"string","description":"The unique identifier of the thread to fetch, as returned by other Gmail tools. Provide this or url."},"url":{"type":"string","description":"A Gmail web link to the thread, e.g. https://mail.google.com/mail/u/0/#inbox/FMfcgz... Use this when the user pastes a Gmail link; the ID in the link is not an API thread ID. Provide this or threadId."},"format":{"type":"string","enum":["full","metadata","minimal"],"description":"The format to return the messages in. Defaults to 'full'.","default":"full"}}},"action":{"path":"/users/me/threads/{threadId}","method":"GET","mapping":{"params":"(\n $rebase := function($digits, $from, $to) {\n $count($digits) = 0 ? [] : (\n $step := $reduce($digits, function($acc, $d) {(\n $n := $acc.r * $from + $d;\n $q := $floor($n / $to);\n {\n \"q\": $count($acc.q) = 0 and $q = 0 ? $acc.q : $append($acc.q, $q),\n \"r\": $n % $to\n }\n )}, { \"q\": [], \"r\": 0 });\n $append($rebase($step.q, $from, $to), $step.r)\n )\n };\n $encode := function($s, $from, $to, $fromAlphabet, $toAlphabet) {\n $join(\n $rebase(\n [$map($split($s, \"\"), function($c) { $length($substringBefore($fromAlphabet, $c)) })],\n $from,\n $to\n ).$substring($toAlphabet, $, 1)\n )\n };\n $threadFromUrl := function($url) {(\n $token := $split($substringBefore($substringAfter($url, \"#\"), \"?\"), \"/\")[-1];\n $contains($token, /^[0-9a-f]{16}$/) ? $token : (\n $decoded := $contains($token, /^[BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz]+$/)\n ? $base64decode($encode(\n $token, 40, 64,\n \"BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz\",\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"\n ));\n $number := $substringAfter($decoded, \"f:\");\n $contains($number, /^[0-9]+$/)\n ? $encode($number, 10, 16, \"0123456789\", \"0123456789abcdef\")\n : $error(\"This Gmail link does not contain a thread ID. Find the thread with search-gmail-threads instead.\")\n )\n )};\n {\n \"threadId\": arguments.threadId\n ? arguments.threadId\n : arguments.url\n ? $threadFromUrl(arguments.url)\n : $error(\"Provide threadId or url.\")\n }\n )","query":"{\n \"format\": arguments.format ? arguments.format : \"full\"\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"searchGmailThreads","enabled":true,"description":"Lists email threads from the authenticated user's Gmail account. Supports filtering by query string and pagination. Returns thread IDs and snippets; use 'getGmailThread' to fetch full message bodies.","slug":"search-gmail-threads","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists email threads, which is a read-only operation and thus low risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Optional query string to filter threads, using the same format as the Gmail search bar (e.g. 'subject:Update', 'from:user@example.com', 'is:unread', 'has:attachment', 'after:YYYY/MM/DD'). If omitted, all threads (excluding spam and trash by default) are listed."},"maxResults":{"type":"number","description":"The maximum number of threads to return. Defaults to 20. The maximum allowed value is 50.","default":20,"minimum":1,"maximum":50},"pageToken":{"type":"string","description":"Page token to retrieve a specific page of results. Leave empty to fetch the first page."},"labelIds":{"type":"array","items":{"type":"string"},"description":"Only return threads with labels that match all of the specified label IDs."},"includeSpamTrash":{"type":"boolean","description":"Include threads from SPAM and TRASH in the results. Defaults to false."}}},"action":{"path":"/users/me/threads","method":"GET","mapping":{"query":"{\n \"q\": arguments.query,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 20,\n \"pageToken\": arguments.pageToken,\n \"labelIds\": arguments.labelIds,\n \"includeSpamTrash\": arguments.includeSpamTrash\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"labelGmailThread","enabled":true,"description":"Adds labels to an entire thread. Affects all messages currently in the thread and any future messages added to it. Use 'searchGmailThreads' to find a thread ID and 'listGmailLabels' to discover label IDs. System label IDs include: INBOX, TRASH, SPAM, STARRED, UNREAD, IMPORTANT.","slug":"label-gmail-thread","ai_risk":{"level":"low","score":4,"reasoning":"Adding labels to a thread modifies the state of the emails, which is a standard write operation and poses medium risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"threadId":{"type":"string","description":"The unique identifier of the thread to add labels to."},"labelIds":{"type":"array","items":{"type":"string"},"description":"The unique identifiers of the labels to add. Can be a system label ID (e.g., 'INBOX', 'TRASH', 'SPAM', 'STARRED', 'UNREAD') or a user-defined label ID.","minItems":1,"maxItems":100}},"required":["threadId","labelIds"]},"action":{"path":"/users/me/threads/{threadId}/modify","method":"POST","mapping":{"params":"{\n \"threadId\": arguments.threadId\n }","body":"{\n \"addLabelIds\": arguments.labelIds\n }"}},"annotations":{"idempotentHint":true,"openWorldHint":true}},{"name":"unlabelGmailThread","enabled":true,"description":"Removes labels from an entire thread. Use 'searchGmailThreads' to find a thread ID and 'listGmailLabels' to discover label IDs.","slug":"unlabel-gmail-thread","ai_risk":{"level":"medium","score":5,"reasoning":"Removing labels from a thread is a destructive action that modifies user data, posing medium risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"threadId":{"type":"string","description":"The unique identifier of the thread to remove labels from."},"labelIds":{"type":"array","items":{"type":"string"},"description":"The unique identifiers of the labels to remove.","minItems":1,"maxItems":100}},"required":["threadId","labelIds"]},"action":{"path":"/users/me/threads/{threadId}/modify","method":"POST","mapping":{"params":"{\n \"threadId\": arguments.threadId\n }","body":"{\n \"removeLabelIds\": arguments.labelIds\n }"}},"annotations":{"destructiveHint":true,"idempotentHint":true}},{"name":"listGmailLabels","enabled":true,"description":"Lists all labels available in the authenticated user's Gmail account. Use this tool to discover the ID of a user label before calling label/unlabel tools. System labels can be used with their well-known IDs: INBOX, TRASH, SPAM, STARRED, UNREAD, IMPORTANT, CHAT, DRAFT, SENT.","slug":"list-gmail-labels","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists all labels, which is a read-only operation and therefore low risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{}},"action":{"path":"/users/me/labels","method":"GET","mapping":{}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"labelGmailMessage","enabled":true,"description":"Adds one or more labels to a specific message. Use 'searchGmailThreads' or 'getGmailThread' to find message IDs and 'listGmailLabels' to discover label IDs.","slug":"label-gmail-message","ai_risk":{"level":"low","score":4,"reasoning":"Adding labels to a specific message modifies its state, which is a standard write operation and poses medium risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"messageId":{"type":"string","description":"The ID of the message to add the labels to."},"labelIds":{"type":"array","items":{"type":"string"},"description":"The IDs of the labels to add. Can be a system label ID (e.g., 'INBOX', 'TRASH', 'SPAM', 'STARRED', 'UNREAD') or a user-defined label ID.","minItems":1,"maxItems":100}},"required":["messageId","labelIds"]},"action":{"path":"/users/me/messages/{messageId}/modify","method":"POST","mapping":{"params":"{\n \"messageId\": arguments.messageId\n }","body":"{\n \"addLabelIds\": arguments.labelIds\n }"}},"annotations":{"idempotentHint":true,"openWorldHint":true}},{"name":"unlabelGmailMessage","enabled":true,"description":"Removes one or more labels from a specific message. Use 'searchGmailThreads' or 'getGmailThread' to find message IDs and 'listGmailLabels' to discover label IDs.","slug":"unlabel-gmail-message","ai_risk":{"level":"medium","score":5,"reasoning":"Removing labels from a specific message is a destructive action that modifies user data, posing medium risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"messageId":{"type":"string","description":"The ID of the message to remove the labels from."},"labelIds":{"type":"array","items":{"type":"string"},"description":"The IDs of the labels to remove.","minItems":1,"maxItems":100}},"required":["messageId","labelIds"]},"action":{"path":"/users/me/messages/{messageId}/modify","method":"POST","mapping":{"params":"{\n \"messageId\": arguments.messageId\n }","body":"{\n \"removeLabelIds\": arguments.labelIds\n }"}},"annotations":{"destructiveHint":true,"idempotentHint":true}},{"name":"createGmailLabel","enabled":true,"description":"Creates a new user label in the authenticated user's Gmail account.","slug":"create-gmail-label","ai_risk":{"level":"low","score":4,"reasoning":"Creating a new user label modifies the user's account settings, which is a standard write operation and poses medium risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"displayName":{"type":"string","description":"The display name of the label to create."},"labelListVisibility":{"type":"string","enum":["labelShow","labelShowIfUnread","labelHide"],"description":"The visibility of the label in the label list of the Gmail web interface. Defaults to 'labelShow'."},"messageListVisibility":{"type":"string","enum":["show","hide"],"description":"The visibility of messages with this label in the message list. Defaults to 'show'."}},"required":["displayName"]},"action":{"path":"/users/me/labels","method":"POST","mapping":{"body":"{\n \"name\": arguments.displayName,\n \"labelListVisibility\": arguments.labelListVisibility,\n \"messageListVisibility\": arguments.messageListVisibility\n }"}},"annotations":{"openWorldHint":true}},{"name":"createGmailFilter","enabled":true,"description":"Creates a Gmail filter (inbox rule) that automatically applies actions to incoming messages matching the given criteria. Provide at least one criterion (e.g. 'query', 'from', 'subject') and at least one action (e.g. 'addLabelIds', 'removeLabelIds', 'forward'). To auto-archive messages, remove the 'INBOX' label via 'removeLabelIds'. Use 'listGmailLabels' to discover label IDs and 'createGmailLabel' to create new ones. You can create up to 1,000 filters per user.","slug":"create-gmail-filter","ai_risk":{"level":"medium","score":5,"reasoning":"Creating a filter persistently changes how future incoming mail is handled (labeling, archiving, forwarding), which is a write operation that modifies account behavior and poses medium risk.","calculated_at":"2026-08-26T00:00:00.000Z"},"inputSchema":{"type":"object","properties":{"criteria":{"type":"object","description":"The conditions a message must match for the filter to apply. Provide at least one field.","properties":{"from":{"type":"string","description":"The sender's email address to match. Supports the same format as the Gmail search box, e.g. 'notifications@github.com' or 'from:(a@x.com OR b@x.com)'."},"to":{"type":"string","description":"The recipient's email address to match."},"subject":{"type":"string","description":"Text that must appear in the subject line."},"query":{"type":"string","description":"A Gmail search query that matches the message, using the same format as the Gmail search box (e.g. 'from:(notifications@github.com) list:(repo.org.github.com)')."},"negatedQuery":{"type":"string","description":"A Gmail search query whose matching messages are excluded from the filter."},"hasAttachment":{"type":"boolean","description":"Whether the message must have an attachment."},"excludeChats":{"type":"boolean","description":"Whether to exclude chat messages from matching."},"size":{"type":"number","description":"The size of the message in bytes, compared using 'sizeComparison'."},"sizeComparison":{"type":"string","enum":["larger","smaller"],"description":"How the message size is compared against 'size': 'larger' or 'smaller'."}},"additionalProperties":false},"action":{"type":"object","description":"The actions to apply to messages matching the criteria. Provide at least one field.","properties":{"addLabelIds":{"type":"array","items":{"type":"string"},"description":"Label IDs to add to matching messages. Can be a system label ID (e.g. 'STARRED', 'IMPORTANT') or a user-defined label ID from 'listGmailLabels'."},"removeLabelIds":{"type":"array","items":{"type":"string"},"description":"Label IDs to remove from matching messages. Remove 'INBOX' to auto-archive, or 'UNREAD' to mark as read."},"forward":{"type":"string","description":"An email address to forward matching messages to. The address must already be a verified forwarding address on the account."}},"additionalProperties":false}},"required":["criteria","action"]},"action":{"path":"/users/me/settings/filters","method":"POST","mapping":{"body":"{\n \"criteria\": arguments.criteria,\n \"action\": arguments.action\n }"}},"annotations":{"openWorldHint":true}},{"name":"listGmailFilters","enabled":true,"description":"Lists all filters (inbox rules) configured in the authenticated user's Gmail account, including each filter's ID, criteria, and actions. Use the returned filter ID with 'getGmailFilter' or 'deleteGmailFilter'.","slug":"list-gmail-filters","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists existing filters, which is a read-only operation and therefore low risk.","calculated_at":"2026-08-26T00:00:00.000Z"},"inputSchema":{"type":"object","properties":{}},"action":{"path":"/users/me/settings/filters","method":"GET","mapping":{"response":"{\n \"filters\": response.filter ? response.filter : []\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"getGmailFilter","enabled":true,"description":"Retrieves a single Gmail filter (inbox rule) by its ID, including its criteria and actions. Use 'listGmailFilters' to discover filter IDs.","slug":"get-gmail-filter","ai_risk":{"level":"low","score":1,"reasoning":"This tool fetches a single filter, which is a read-only operation and therefore low risk.","calculated_at":"2026-08-26T00:00:00.000Z"},"inputSchema":{"type":"object","properties":{"filterId":{"type":"string","description":"The ID of the filter to fetch."}},"required":["filterId"]},"action":{"path":"/users/me/settings/filters/{filterId}","method":"GET","mapping":{"params":"{\n \"filterId\": arguments.filterId\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"deleteGmailFilter","enabled":true,"description":"Immediately and permanently deletes a Gmail filter (inbox rule) by its ID. This does not affect messages already processed by the filter. Use 'listGmailFilters' to discover filter IDs.","slug":"delete-gmail-filter","ai_risk":{"level":"medium","score":5,"reasoning":"Deleting a filter permanently removes an inbox rule, which is a destructive change to account configuration and poses medium risk.","calculated_at":"2026-08-26T00:00:00.000Z"},"inputSchema":{"type":"object","properties":{"filterId":{"type":"string","description":"The ID of the filter to delete."}},"required":["filterId"]},"action":{"path":"/users/me/settings/filters/{filterId}","method":"DELETE","mapping":{"params":"{\n \"filterId\": arguments.filterId\n }","response":"{\n \"success\": true,\n \"filterId\": arguments.filterId\n }"}},"annotations":{"destructiveHint":true,"idempotentHint":true}}]}}
1
+ {"id":"gmail","status":"active","internal_status":"tool-works","applications":["gmail"],"definition":{"display":{"name":"Gmail","description":"Gmail is a web-based email service developed by Google.","icon":"gmail.svg","website":"https://www.gmail.com","category":"communication-messaging","docs_url":"https://docs.withwillow.ai/docs/mcp-servers/built-in/gmail"},"api":{"base_url":"https://gmail.googleapis.com/gmail/v1"},"auth":{"methods":{"oauth":{"authUrl":"https://accounts.google.com/o/oauth2/v2/auth","tokenUrl":"https://oauth2.googleapis.com/token","authInitUrlParams":{"access_type":"offline","prompt":"consent"},"scopes":["https://www.googleapis.com/auth/gmail.addons.current.action.compose","https://www.googleapis.com/auth/gmail.addons.current.message.action","https://www.googleapis.com/auth/gmail.addons.current.message.metadata","https://www.googleapis.com/auth/gmail.addons.current.message.readonly","https://www.googleapis.com/auth/gmail.labels","https://www.googleapis.com/auth/gmail.send","https://www.googleapis.com/auth/gmail.readonly","https://www.googleapis.com/auth/gmail.compose","https://www.googleapis.com/auth/gmail.insert","https://www.googleapis.com/auth/gmail.modify","https://www.googleapis.com/auth/gmail.metadata","https://www.googleapis.com/auth/gmail.settings.basic","https://www.googleapis.com/auth/gmail.settings.sharing"],"defaultScopes":["https://www.googleapis.com/auth/gmail.modify","https://www.googleapis.com/auth/gmail.settings.basic"],"scopeTemplates":[{"id":"read-only","name":"Read-only","description":"Read and search messages, threads, drafts, labels and filters. Can't send, label or delete mail.","scopes":["https://www.googleapis.com/auth/gmail.readonly"]},{"id":"send-only","name":"Send only","description":"Send email as the user without access to read the mailbox. For agents that only deliver notifications or reports.","scopes":["https://www.googleapis.com/auth/gmail.send"]},{"id":"read-and-compose","name":"Read and compose","description":"Read mail and create, edit and send drafts. Can't change labels, archive or delete.","scopes":["https://www.googleapis.com/auth/gmail.readonly","https://www.googleapis.com/auth/gmail.compose"]},{"id":"full-access","name":"Full access","description":"Read, send, label, archive and trash mail, and manage labels and filters.","scopes":["https://www.googleapis.com/auth/gmail.modify","https://www.googleapis.com/auth/gmail.settings.basic"]}],"codeExchangeConfig":{"modelCredentialsMapping":"{\n \"access_token\": access_token, \n \"expires_at\": $fromMillis($millis() + expires_in * 1000),\n \"refresh_token\": refresh_token,\n \"refresh_token_expires_at\": $fromMillis($millis() + refresh_token_expires_in * 1000),\n \"scope\": scope,\n \"token_type\": token_type\n }"}}}},"conditions":[{"id":"block-labeled-messages","name":"Block messages with restricted labels","description":"Before reading an email, fetch its label ids and block the call when the message carries one of the configured restricted labels (e.g. a 'Confidential' label).","action":{"path":"/users/me/messages/{messageId}","method":"GET","mapping":{"params":"{ \"messageId\": arguments.messageId }","query":"{ \"format\": \"metadata\" }"}},"mapping":"$count(response.labelIds[$ in $$.variables.blockedLabelIds]) > 0","message":"This email carries a restricted label and cannot be accessed by this tool.","variables":[{"key":"blockedLabelIds","label":"Restricted label ids","description":"Gmail label ids (e.g. SPAM, CATEGORY_PERSONAL, or a custom Label_xxx) that block access to a message.","type":"string[]","required":true,"placeholder":"SPAM, Label_12345"}],"appliesTo":["read-email","list-gmail-attachments","get-gmail-attachment"]}],"tools":[{"name":"sendGmailMessage","enabled":true,"description":"Send an email message using Gmail.","slug":"send-gmail-message","ai_risk":{"level":"medium","score":6,"reasoning":"This tool sends an email message, which can be considered high risk as it can potentially lead to spam or misuse if misconfigured.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"to":{"type":"string","description":"Comma-separated list of recipient email addresses."},"cc":{"type":"string","description":"Comma-separated list of CC email addresses."},"bcc":{"type":"string","description":"Comma-separated list of BCC email addresses."},"subject":{"type":"string","description":"The subject line of the email."},"body":{"type":"string","description":"The plain text body of the email."},"threadId":{"type":"string","description":"Optional thread ID to send the message as a reply."},"labelIds":{"type":"array","items":{"type":"string"},"description":"Optional list of label IDs to apply to the sent message."}},"required":["to","subject","body"]},"risk":"high","action":{"path":"/users/me/messages/send","method":"POST","mapping":{"body":"{\n \"raw\": $base64encode(\n \"To: \" & arguments.to & \"\r\n\" &\n ($exists(arguments.cc) and arguments.cc ? \"Cc: \" & arguments.cc & \"\r\n\" : \"\") &\n ($exists(arguments.bcc) and arguments.bcc ? \"Bcc: \" & arguments.bcc & \"\r\n\" : \"\") &\n \"Subject: \" & arguments.subject & \"\r\n\" &\n \"\r\n\" &\n arguments.body\n ),\n \"threadId\": arguments.threadId,\n \"labelIds\": arguments.labelIds\n}"}},"annotations":{"destructiveHint":true,"openWorldHint":true}},{"name":"createGmailDraft","enabled":true,"description":"Create a draft email message using Gmail.","slug":"create-gmail-draft","ai_risk":{"level":"medium","score":5,"reasoning":"Creating a draft email is a standard write operation, posing medium risk as it modifies user data but does not send it.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"to":{"type":"string","description":"Comma-separated list of recipient email addresses."},"cc":{"type":"string","description":"Comma-separated list of CC email addresses."},"bcc":{"type":"string","description":"Comma-separated list of BCC email addresses."},"subject":{"type":"string","description":"The subject line of the email."},"body":{"type":"string","description":"The plain text body of the email."},"threadId":{"type":"string","description":"Optional thread ID to send the message as a reply."},"labelIds":{"type":"array","items":{"type":"string"},"description":"Optional list of label IDs to apply to the sent message."}},"required":["to","subject","body"]},"action":{"path":"/users/me/drafts","method":"POST","mapping":{"body":"{\n \"message\": {\n \"raw\": $base64encode(\n \"To: \" & arguments.to & \"\r\n\" &\n ($exists(arguments.cc) and arguments.cc ? \"Cc: \" & arguments.cc & \"\r\n\" : \"\") &\n ($exists(arguments.bcc) and arguments.bcc ? \"Bcc: \" & arguments.bcc & \"\r\n\" : \"\") &\n \"Subject: \" & arguments.subject & \"\r\n\" &\n \"\r\n\" &\n arguments.body\n ),\n \"threadId\": arguments.threadId,\n \"labelIds\": arguments.labelIds\n}\n }"}},"annotations":{"destructiveHint":true}},{"name":"readEmail","enabled":true,"description":"Read an email message using Gmail.","slug":"read-email","ai_risk":{"level":"low","score":1,"reasoning":"This tool reads an email message, making it low risk as it only fetches data without modifying anything.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"messageId":{"type":"string","description":"The ID of the email message to read."}}},"action":{"path":"/users/me/messages/{messageId}","method":"GET","mapping":{"params":"{\n \"messageId\": arguments.messageId\n }","response":"(\n $header := function($name) { response.payload.headers[name = $name].value };\n $body := response.payload.body.data\n ? $base64decode(response.payload.body.data)\n : $join(response.payload.parts.(body.data ? $base64decode(body.data) : ''), '\n');\n {\n \"id\": response.id,\n \"threadId\": response.threadId,\n \"labelIds\": response.labelIds,\n \"snippet\": response.snippet,\n \"from\": $header(\"From\"),\n \"to\": $header(\"To\"),\n \"cc\": $header(\"Cc\"),\n \"subject\": $header(\"Subject\"),\n \"date\": $header(\"Date\"),\n \"internalDate\": response.internalDate,\n \"mimeType\": response.payload.mimeType,\n \"body\": $body\n }\n )"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"listGmailAttachments","enabled":true,"description":"List file attachments on a Gmail message. Returns metadata for each attachment including filename, MIME type, attachment ID, and size. Use 'getGmailAttachment' with the attachment ID to download the file content. Optionally filter by MIME type (e.g. 'application/pdf' for PDF files).","slug":"list-gmail-attachments","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists attachment metadata on an email message without downloading file content.","calculated_at":"2026-07-28T08:00:00.000Z"},"inputSchema":{"type":"object","properties":{"messageId":{"type":"string","description":"The ID of the email message to list attachments from."},"mimeType":{"type":"string","description":"Optional MIME type filter (e.g. 'application/pdf' to list only PDF attachments)."}},"required":["messageId"]},"action":{"path":"/users/me/messages/{messageId}","method":"GET","mapping":{"params":"{\n \"messageId\": arguments.messageId\n }","query":"{\n \"format\": \"full\"\n }","response":"(\n $flatten := function($parts) { (\n $direct := $parts[filename or body.attachmentId].{\n \"filename\": filename,\n \"mimeType\": mimeType,\n \"attachmentId\": body.attachmentId,\n \"size\": body.size,\n \"hasInlineData\": $boolean(body.data)\n };\n $nested := $parts.parts.($count($) > 0 ? $flatten($) : []);\n $append($direct, $nested)\n )};\n $attachments := response.payload.parts\n ? $flatten(response.payload.parts)\n : (\n response.payload.filename or response.payload.body.attachmentId\n )\n ? [{\n \"filename\": response.payload.filename,\n \"mimeType\": response.payload.mimeType,\n \"attachmentId\": response.payload.body.attachmentId,\n \"size\": response.payload.body.size,\n \"hasInlineData\": $boolean(response.payload.body.data)\n }]\n : [];\n $filtered := $filter($attachments, function($a) {\n $not($exists($$.arguments.mimeType) and $$.arguments.mimeType)\n or $a.mimeType = $$.arguments.mimeType\n });\n {\n \"messageId\": response.id,\n \"attachments\": $filtered\n }\n )"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"getGmailAttachment","enabled":true,"description":"Download a file attachment from a Gmail message. Returns the attachment content as a base64url-encoded string in the 'data' field. Use 'listGmailAttachments' first to find the attachment ID. Decode the data with a base64url decoder to save the file locally.","slug":"get-gmail-attachment","ai_risk":{"level":"low","score":1,"reasoning":"This tool downloads an email attachment and is read-only.","calculated_at":"2026-07-28T08:00:00.000Z"},"inputSchema":{"type":"object","properties":{"messageId":{"type":"string","description":"The ID of the email message containing the attachment."},"attachmentId":{"type":"string","description":"The attachment ID from 'listGmailAttachments'. Required for attachments stored separately from the message body."}},"required":["messageId","attachmentId"]},"action":{"path":"/users/me/messages/{messageId}/attachments/{attachmentId}","method":"GET","mapping":{"params":"{\n \"messageId\": arguments.messageId,\n \"attachmentId\": arguments.attachmentId\n }","response":"{\n \"attachmentId\": response.attachmentId ? response.attachmentId : arguments.attachmentId,\n \"size\": response.size,\n \"data\": response.data,\n \"encoding\": \"base64url\"\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"listEmails","enabled":true,"description":"List email messages using Gmail.","slug":"list-emails","ai_risk":{"level":"low","score":1,"reasoning":"Listing email messages is a read-only operation, posing low risk as it does not alter any data.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"The query to search for email messages. Only return messages matching the specified query. Supports the same query format as the Gmail search box. For example, 'from:someuser@example.com rfc822msgid:<somemsgid@example.com> is:unread'."},"maxResults":{"type":"number","description":"The maximum number of results to return.","default":10}}},"action":{"path":"/users/me/messages","method":"GET","mapping":{"query":"{\n \"q\": arguments.query,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 10\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"listGmailDrafts","enabled":true,"description":"Lists draft emails from the authenticated user's Gmail account. Supports filtering by query string and pagination.","slug":"list-gmail-drafts","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists draft emails, which is a read-only operation and therefore low risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Optional query string to filter drafts, using the same format as the Gmail search bar (e.g. 'subject:Update', 'from:user@example.com', 'is:unread', 'has:attachment', 'after:YYYY/MM/DD'). If omitted, all drafts (excluding spam and trash by default) are listed."},"maxResults":{"type":"number","description":"The maximum number of drafts to return. Defaults to 20. The maximum allowed value is 50.","default":20,"minimum":1,"maximum":50},"pageToken":{"type":"string","description":"A token received from a previous list_drafts call to retrieve the next page of results. Leave empty to fetch the first page."},"includeSpamTrash":{"type":"boolean","description":"Include drafts from SPAM and TRASH in the results. Defaults to false."}}},"action":{"path":"/users/me/drafts","method":"GET","mapping":{"query":"{\n \"q\": arguments.query,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 20,\n \"pageToken\": arguments.pageToken,\n \"includeSpamTrash\": arguments.includeSpamTrash\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"getGmailThread","enabled":true,"description":"Retrieves a specific email thread from the authenticated user's Gmail account, including a list of its messages. Accepts either an API thread ID or a Gmail web link to the thread.","slug":"get-gmail-thread","ai_risk":{"level":"low","score":1,"reasoning":"Retrieving a specific email thread is a read-only action, posing low risk as it does not modify any data.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"threadId":{"type":"string","description":"The unique identifier of the thread to fetch, as returned by other Gmail tools. Provide this or url."},"url":{"type":"string","description":"A Gmail web link to the thread, e.g. https://mail.google.com/mail/u/0/#inbox/FMfcgz... Use this when the user pastes a Gmail link; the ID in the link is not an API thread ID. Provide this or threadId."},"format":{"type":"string","enum":["full","metadata","minimal"],"description":"The format to return the messages in. Defaults to 'full'.","default":"full"}}},"action":{"path":"/users/me/threads/{threadId}","method":"GET","mapping":{"params":"(\n $rebase := function($digits, $from, $to) {\n $count($digits) = 0 ? [] : (\n $step := $reduce($digits, function($acc, $d) {(\n $n := $acc.r * $from + $d;\n $q := $floor($n / $to);\n {\n \"q\": $count($acc.q) = 0 and $q = 0 ? $acc.q : $append($acc.q, $q),\n \"r\": $n % $to\n }\n )}, { \"q\": [], \"r\": 0 });\n $append($rebase($step.q, $from, $to), $step.r)\n )\n };\n $encode := function($s, $from, $to, $fromAlphabet, $toAlphabet) {\n $join(\n $rebase(\n [$map($split($s, \"\"), function($c) { $length($substringBefore($fromAlphabet, $c)) })],\n $from,\n $to\n ).$substring($toAlphabet, $, 1)\n )\n };\n $threadFromUrl := function($url) {(\n $token := $split($substringBefore($substringAfter($url, \"#\"), \"?\"), \"/\")[-1];\n $contains($token, /^[0-9a-f]{16}$/) ? $token : (\n $decoded := $contains($token, /^[BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz]+$/)\n ? $base64decode($encode(\n $token, 40, 64,\n \"BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz\",\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"\n ));\n $number := $substringAfter($decoded, \"f:\");\n $contains($number, /^[0-9]+$/)\n ? $encode($number, 10, 16, \"0123456789\", \"0123456789abcdef\")\n : $error(\"This Gmail link does not contain a thread ID. Find the thread with search-gmail-threads instead.\")\n )\n )};\n {\n \"threadId\": arguments.threadId\n ? arguments.threadId\n : arguments.url\n ? $threadFromUrl(arguments.url)\n : $error(\"Provide threadId or url.\")\n }\n )","query":"{\n \"format\": arguments.format ? arguments.format : \"full\"\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"searchGmailThreads","enabled":true,"description":"Lists email threads from the authenticated user's Gmail account. Supports filtering by query string and pagination. Returns thread IDs and snippets; use 'getGmailThread' to fetch full message bodies.","slug":"search-gmail-threads","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists email threads, which is a read-only operation and thus low risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Optional query string to filter threads, using the same format as the Gmail search bar (e.g. 'subject:Update', 'from:user@example.com', 'is:unread', 'has:attachment', 'after:YYYY/MM/DD'). If omitted, all threads (excluding spam and trash by default) are listed."},"maxResults":{"type":"number","description":"The maximum number of threads to return. Defaults to 20. The maximum allowed value is 50.","default":20,"minimum":1,"maximum":50},"pageToken":{"type":"string","description":"Page token to retrieve a specific page of results. Leave empty to fetch the first page."},"labelIds":{"type":"array","items":{"type":"string"},"description":"Only return threads with labels that match all of the specified label IDs."},"includeSpamTrash":{"type":"boolean","description":"Include threads from SPAM and TRASH in the results. Defaults to false."}}},"action":{"path":"/users/me/threads","method":"GET","mapping":{"query":"{\n \"q\": arguments.query,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 20,\n \"pageToken\": arguments.pageToken,\n \"labelIds\": arguments.labelIds,\n \"includeSpamTrash\": arguments.includeSpamTrash\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"labelGmailThread","enabled":true,"description":"Adds labels to an entire thread. Affects all messages currently in the thread and any future messages added to it. Use 'searchGmailThreads' to find a thread ID and 'listGmailLabels' to discover label IDs. System label IDs include: INBOX, TRASH, SPAM, STARRED, UNREAD, IMPORTANT.","slug":"label-gmail-thread","ai_risk":{"level":"low","score":4,"reasoning":"Adding labels to a thread modifies the state of the emails, which is a standard write operation and poses medium risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"threadId":{"type":"string","description":"The unique identifier of the thread to add labels to."},"labelIds":{"type":"array","items":{"type":"string"},"description":"The unique identifiers of the labels to add. Can be a system label ID (e.g., 'INBOX', 'TRASH', 'SPAM', 'STARRED', 'UNREAD') or a user-defined label ID.","minItems":1,"maxItems":100}},"required":["threadId","labelIds"]},"action":{"path":"/users/me/threads/{threadId}/modify","method":"POST","mapping":{"params":"{\n \"threadId\": arguments.threadId\n }","body":"{\n \"addLabelIds\": arguments.labelIds\n }"}},"annotations":{"idempotentHint":true,"openWorldHint":true}},{"name":"unlabelGmailThread","enabled":true,"description":"Removes labels from an entire thread. Use 'searchGmailThreads' to find a thread ID and 'listGmailLabels' to discover label IDs.","slug":"unlabel-gmail-thread","ai_risk":{"level":"medium","score":5,"reasoning":"Removing labels from a thread is a destructive action that modifies user data, posing medium risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"threadId":{"type":"string","description":"The unique identifier of the thread to remove labels from."},"labelIds":{"type":"array","items":{"type":"string"},"description":"The unique identifiers of the labels to remove.","minItems":1,"maxItems":100}},"required":["threadId","labelIds"]},"action":{"path":"/users/me/threads/{threadId}/modify","method":"POST","mapping":{"params":"{\n \"threadId\": arguments.threadId\n }","body":"{\n \"removeLabelIds\": arguments.labelIds\n }"}},"annotations":{"destructiveHint":true,"idempotentHint":true}},{"name":"listGmailLabels","enabled":true,"description":"Lists all labels available in the authenticated user's Gmail account. Use this tool to discover the ID of a user label before calling label/unlabel tools. System labels can be used with their well-known IDs: INBOX, TRASH, SPAM, STARRED, UNREAD, IMPORTANT, CHAT, DRAFT, SENT.","slug":"list-gmail-labels","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists all labels, which is a read-only operation and therefore low risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{}},"action":{"path":"/users/me/labels","method":"GET","mapping":{}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"labelGmailMessage","enabled":true,"description":"Adds one or more labels to a specific message. Use 'searchGmailThreads' or 'getGmailThread' to find message IDs and 'listGmailLabels' to discover label IDs.","slug":"label-gmail-message","ai_risk":{"level":"low","score":4,"reasoning":"Adding labels to a specific message modifies its state, which is a standard write operation and poses medium risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"messageId":{"type":"string","description":"The ID of the message to add the labels to."},"labelIds":{"type":"array","items":{"type":"string"},"description":"The IDs of the labels to add. Can be a system label ID (e.g., 'INBOX', 'TRASH', 'SPAM', 'STARRED', 'UNREAD') or a user-defined label ID.","minItems":1,"maxItems":100}},"required":["messageId","labelIds"]},"action":{"path":"/users/me/messages/{messageId}/modify","method":"POST","mapping":{"params":"{\n \"messageId\": arguments.messageId\n }","body":"{\n \"addLabelIds\": arguments.labelIds\n }"}},"annotations":{"idempotentHint":true,"openWorldHint":true}},{"name":"unlabelGmailMessage","enabled":true,"description":"Removes one or more labels from a specific message. Use 'searchGmailThreads' or 'getGmailThread' to find message IDs and 'listGmailLabels' to discover label IDs.","slug":"unlabel-gmail-message","ai_risk":{"level":"medium","score":5,"reasoning":"Removing labels from a specific message is a destructive action that modifies user data, posing medium risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"messageId":{"type":"string","description":"The ID of the message to remove the labels from."},"labelIds":{"type":"array","items":{"type":"string"},"description":"The IDs of the labels to remove.","minItems":1,"maxItems":100}},"required":["messageId","labelIds"]},"action":{"path":"/users/me/messages/{messageId}/modify","method":"POST","mapping":{"params":"{\n \"messageId\": arguments.messageId\n }","body":"{\n \"removeLabelIds\": arguments.labelIds\n }"}},"annotations":{"destructiveHint":true,"idempotentHint":true}},{"name":"createGmailLabel","enabled":true,"description":"Creates a new user label in the authenticated user's Gmail account.","slug":"create-gmail-label","ai_risk":{"level":"low","score":4,"reasoning":"Creating a new user label modifies the user's account settings, which is a standard write operation and poses medium risk.","calculated_at":"2026-05-22T10:03:01.160Z"},"inputSchema":{"type":"object","properties":{"displayName":{"type":"string","description":"The display name of the label to create."},"labelListVisibility":{"type":"string","enum":["labelShow","labelShowIfUnread","labelHide"],"description":"The visibility of the label in the label list of the Gmail web interface. Defaults to 'labelShow'."},"messageListVisibility":{"type":"string","enum":["show","hide"],"description":"The visibility of messages with this label in the message list. Defaults to 'show'."}},"required":["displayName"]},"action":{"path":"/users/me/labels","method":"POST","mapping":{"body":"{\n \"name\": arguments.displayName,\n \"labelListVisibility\": arguments.labelListVisibility,\n \"messageListVisibility\": arguments.messageListVisibility\n }"}},"annotations":{"openWorldHint":true}},{"name":"createGmailFilter","enabled":true,"description":"Creates a Gmail filter (inbox rule) that automatically applies actions to incoming messages matching the given criteria. Provide at least one criterion (e.g. 'query', 'from', 'subject') and at least one action (e.g. 'addLabelIds', 'removeLabelIds', 'forward'). To auto-archive messages, remove the 'INBOX' label via 'removeLabelIds'. Use 'listGmailLabels' to discover label IDs and 'createGmailLabel' to create new ones. You can create up to 1,000 filters per user.","slug":"create-gmail-filter","ai_risk":{"level":"medium","score":5,"reasoning":"Creating a filter persistently changes how future incoming mail is handled (labeling, archiving, forwarding), which is a write operation that modifies account behavior and poses medium risk.","calculated_at":"2026-08-26T00:00:00.000Z"},"inputSchema":{"type":"object","properties":{"criteria":{"type":"object","description":"The conditions a message must match for the filter to apply. Provide at least one field.","properties":{"from":{"type":"string","description":"The sender's email address to match. Supports the same format as the Gmail search box, e.g. 'notifications@github.com' or 'from:(a@x.com OR b@x.com)'."},"to":{"type":"string","description":"The recipient's email address to match."},"subject":{"type":"string","description":"Text that must appear in the subject line."},"query":{"type":"string","description":"A Gmail search query that matches the message, using the same format as the Gmail search box (e.g. 'from:(notifications@github.com) list:(repo.org.github.com)')."},"negatedQuery":{"type":"string","description":"A Gmail search query whose matching messages are excluded from the filter."},"hasAttachment":{"type":"boolean","description":"Whether the message must have an attachment."},"excludeChats":{"type":"boolean","description":"Whether to exclude chat messages from matching."},"size":{"type":"number","description":"The size of the message in bytes, compared using 'sizeComparison'."},"sizeComparison":{"type":"string","enum":["larger","smaller"],"description":"How the message size is compared against 'size': 'larger' or 'smaller'."}},"additionalProperties":false},"action":{"type":"object","description":"The actions to apply to messages matching the criteria. Provide at least one field.","properties":{"addLabelIds":{"type":"array","items":{"type":"string"},"description":"Label IDs to add to matching messages. Can be a system label ID (e.g. 'STARRED', 'IMPORTANT') or a user-defined label ID from 'listGmailLabels'."},"removeLabelIds":{"type":"array","items":{"type":"string"},"description":"Label IDs to remove from matching messages. Remove 'INBOX' to auto-archive, or 'UNREAD' to mark as read."},"forward":{"type":"string","description":"An email address to forward matching messages to. The address must already be a verified forwarding address on the account."}},"additionalProperties":false}},"required":["criteria","action"]},"action":{"path":"/users/me/settings/filters","method":"POST","mapping":{"body":"{\n \"criteria\": arguments.criteria,\n \"action\": arguments.action\n }"}},"annotations":{"openWorldHint":true}},{"name":"listGmailFilters","enabled":true,"description":"Lists all filters (inbox rules) configured in the authenticated user's Gmail account, including each filter's ID, criteria, and actions. Use the returned filter ID with 'getGmailFilter' or 'deleteGmailFilter'.","slug":"list-gmail-filters","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists existing filters, which is a read-only operation and therefore low risk.","calculated_at":"2026-08-26T00:00:00.000Z"},"inputSchema":{"type":"object","properties":{}},"action":{"path":"/users/me/settings/filters","method":"GET","mapping":{"response":"{\n \"filters\": response.filter ? response.filter : []\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"getGmailFilter","enabled":true,"description":"Retrieves a single Gmail filter (inbox rule) by its ID, including its criteria and actions. Use 'listGmailFilters' to discover filter IDs.","slug":"get-gmail-filter","ai_risk":{"level":"low","score":1,"reasoning":"This tool fetches a single filter, which is a read-only operation and therefore low risk.","calculated_at":"2026-08-26T00:00:00.000Z"},"inputSchema":{"type":"object","properties":{"filterId":{"type":"string","description":"The ID of the filter to fetch."}},"required":["filterId"]},"action":{"path":"/users/me/settings/filters/{filterId}","method":"GET","mapping":{"params":"{\n \"filterId\": arguments.filterId\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"deleteGmailFilter","enabled":true,"description":"Immediately and permanently deletes a Gmail filter (inbox rule) by its ID. This does not affect messages already processed by the filter. Use 'listGmailFilters' to discover filter IDs.","slug":"delete-gmail-filter","ai_risk":{"level":"medium","score":5,"reasoning":"Deleting a filter permanently removes an inbox rule, which is a destructive change to account configuration and poses medium risk.","calculated_at":"2026-08-26T00:00:00.000Z"},"inputSchema":{"type":"object","properties":{"filterId":{"type":"string","description":"The ID of the filter to delete."}},"required":["filterId"]},"action":{"path":"/users/me/settings/filters/{filterId}","method":"DELETE","mapping":{"params":"{\n \"filterId\": arguments.filterId\n }","response":"{\n \"success\": true,\n \"filterId\": arguments.filterId\n }"}},"annotations":{"destructiveHint":true,"idempotentHint":true}}]}}
@@ -1 +1 @@
1
- {"id":"google-calendar","status":"active","internal_status":"tool-works","applications":["google-calendar"],"definition":{"display":{"name":"Google Calendar","description":"Google Calendar is a web-based calendar service developed by Google.","icon":"google-calendar.svg","website":"https://www.google.com/calendar","category":"scheduling-calendar","docs_url":"https://docs.withwillow.ai/docs/mcp-servers/built-in/google-calendar"},"api":{"base_url":"https://www.googleapis.com/calendar/v3"},"auth":{"methods":{"oauth":{"authUrl":"https://accounts.google.com/o/oauth2/v2/auth","tokenUrl":"https://oauth2.googleapis.com/token","authInitUrlParams":{"access_type":"offline","prompt":"consent"},"scopes":["https://www.googleapis.com/auth/calendar","https://www.googleapis.com/auth/calendar.readonly"],"defaultScopes":["https://www.googleapis.com/auth/calendar"],"codeExchangeConfig":{"modelCredentialsMapping":"{\n \"access_token\": access_token, \n \"expires_at\": $fromMillis($millis() + expires_in * 1000),\n \"refresh_token\": refresh_token,\n \"refresh_token_expires_at\": $fromMillis($millis() + refresh_token_expires_in * 1000),\n \"scope\": scope,\n \"token_type\": token_type\n }"}}}},"tools":[{"name":"List Calendars","description":"List all available calendars","slug":"list-calendars","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists all available calendars and is read-only, posing minimal risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"inputSchema":{"type":"object","properties":{},"required":[]},"enabled":true,"action":{"path":"/users/me/calendarList","method":"GET","mapping":{}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"List Events","description":"List events from a calendar","slug":"list-events","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists events from a calendar and is read-only, making it low risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"inputSchema":{"type":"object","properties":{"calendarId":{"type":"string","description":"ID of the calendar to list events from (use 'primary' for the main calendar)"},"timeMin":{"type":"string","format":"date-time","description":"Start time in ISO format with timezone required (e.g., 2024-01-01T00:00:00Z or 2024-01-01T00:00:00+00:00). Date-time must end with Z (UTC) or +/-HH:MM offset."},"timeMax":{"type":"string","format":"date-time","description":"End time in ISO format with timezone required (e.g., 2024-12-31T23:59:59Z or 2024-12-31T23:59:59+00:00). Date-time must end with Z (UTC) or +/-HH:MM offset."}},"required":["calendarId"]},"enabled":true,"action":{"path":"/calendars/{calendarId}/events","method":"GET","mapping":{"params":"{\n \"calendarId\": arguments.calendarId\n }","query":"{\n \"timeMin\": arguments.timeMin,\n \"timeMax\": arguments.timeMax\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"Search Events","description":"Search for events in a calendar by text query","slug":"search-events","ai_risk":{"level":"low","score":1,"reasoning":"This tool searches for events in a calendar by text query and is read-only, thus low risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"inputSchema":{"type":"object","properties":{"calendarId":{"type":"string","description":"ID of the calendar to search events in (use 'primary' for the main calendar)"},"query":{"type":"string","description":"Free text search query (searches summary, description, location, attendees, etc.)"},"timeMin":{"type":"string","format":"date-time","description":"Start time boundary in ISO format with timezone required (e.g., 2024-01-01T00:00:00Z or 2024-01-01T00:00:00+00:00). Date-time must end with Z (UTC) or +/-HH:MM offset."},"timeMax":{"type":"string","format":"date-time","description":"End time boundary in ISO format with timezone required (e.g., 2024-12-31T23:59:59Z or 2024-12-31T23:59:59+00:00). Date-time must end with Z (UTC) or +/-HH:MM offset."}},"required":["calendarId","query"]},"enabled":true,"action":{"path":"/calendars/{calendarId}/events","method":"GET","mapping":{"params":"{\n \"calendarId\": arguments.calendarId\n }","query":"{\n \"q\": arguments.query,\n \"timeMin\": arguments.timeMin,\n \"timeMax\": arguments.timeMax\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"List Colors","description":"List available color IDs and meanings","slug":"list-colors","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists available color IDs and meanings and is read-only, indicating low risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"inputSchema":{"type":"object","properties":{},"required":[]},"enabled":true,"action":{"path":"/colors","method":"GET","mapping":{}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"Create Event","description":"Create a new calendar event","slug":"create-event","ai_risk":{"level":"medium","score":5,"reasoning":"This tool creates a new calendar event, which is a standard write operation and carries medium risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"inputSchema":{"type":"object","properties":{"calendarId":{"type":"string","description":"ID of the calendar to create the event in (use 'primary' for the main calendar)"},"summary":{"type":"string","description":"Title of the event"},"description":{"type":"string","description":"Description/notes for the event (optional)"},"start":{"type":"string","format":"date-time","description":"Start time in ISO format with timezone required (e.g., 2024-08-15T10:00:00Z or 2024-08-15T10:00:00-07:00). Date-time must end with Z (UTC) or +/-HH:MM offset."},"end":{"type":"string","format":"date-time","description":"End time in ISO format with timezone required (e.g., 2024-08-15T11:00:00Z or 2024-08-15T11:00:00-07:00). Date-time must end with Z (UTC) or +/-HH:MM offset."},"timeZone":{"type":"string","description":"Timezone of the event start/end times, formatted as an IANA Time Zone Database name (e.g., America/Los_Angeles). Required if start/end times are specified, especially for recurring events."},"location":{"type":"string","description":"Location of the event (optional)"},"attendees":{"type":"array","description":"List of attendees (optional). Each attendee can include responseStatus to set RSVP state.","items":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Email address of the attendee"},"responseStatus":{"type":"string","enum":["needsAction","declined","tentative","accepted"],"description":"The attendee's response status. Use 'accepted' to auto-accept an invite for this attendee."},"optional":{"type":"boolean","description":"Whether this is an optional attendee"},"resource":{"type":"boolean","description":"Whether the attendee is a resource (e.g. a meeting room)"}},"required":["email"]}},"colorId":{"type":"string","description":"Color ID for the event (optional, use list-colors to see available IDs)"},"reminders":{"type":"object","description":"Reminder settings for the event","properties":{"useDefault":{"type":"boolean","description":"Whether to use the default reminders"},"overrides":{"type":"array","description":"Custom reminders (uses popup notifications by default unless email is specified)","items":{"type":"object","properties":{"method":{"type":"string","enum":["email","popup"],"description":"Reminder method (defaults to popup unless email is specified)","default":"popup"},"minutes":{"type":"number","description":"Minutes before the event to trigger the reminder"}},"required":["minutes"]}}},"required":["useDefault"]},"recurrence":{"type":"array","description":"List of recurrence rules (RRULE, EXRULE, RDATE, EXDATE) in RFC5545 format (optional). Example: [\"RRULE:FREQ=WEEKLY;COUNT=5\"]","items":{"type":"string"}}},"required":["calendarId","summary","start","end","timeZone"]},"enabled":true,"action":{"path":"/calendars/{calendarId}/events","method":"POST","mapping":{"params":"{\n \"calendarId\": arguments.calendarId\n }","body":"{\n \"summary\": arguments.summary,\n \"description\": arguments.description,\n \"start\": { \"dateTime\": arguments.start, \"timeZone\": arguments.timeZone },\n \"end\": { \"dateTime\": arguments.end, \"timeZone\": arguments.timeZone },\n \"location\": arguments.location,\n \"attendees\": arguments.attendees,\n \"colorId\": arguments.colorId,\n \"reminders\": arguments.reminders,\n \"recurrence\": arguments.recurrence\n }"}},"annotations":{"destructiveHint":true,"openWorldHint":true}},{"name":"Update Event","description":"Update an existing calendar event","slug":"update-event","ai_risk":{"level":"medium","score":5,"reasoning":"This tool updates an existing calendar event, representing a standard write operation with medium risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"inputSchema":{"type":"object","properties":{"calendarId":{"type":"string","description":"ID of the calendar containing the event"},"eventId":{"type":"string","description":"ID of the event to update"},"summary":{"type":"string","description":"New title for the event (optional)"},"description":{"type":"string","description":"New description for the event (optional)"},"start":{"type":"string","format":"date-time","description":"New start time in ISO format with timezone required (e.g., 2024-08-15T10:00:00Z or 2024-08-15T10:00:00-07:00). Date-time must end with Z (UTC) or +/-HH:MM offset."},"end":{"type":"string","format":"date-time","description":"New end time in ISO format with timezone required (e.g., 2024-08-15T11:00:00Z or 2024-08-15T11:00:00-07:00). Date-time must end with Z (UTC) or +/-HH:MM offset."},"timeZone":{"type":"string","description":"Timezone for the start/end times (IANA format, e.g., America/Los_Angeles). Required if modifying start/end, or for recurring events."},"location":{"type":"string","description":"New location for the event (optional)"},"colorId":{"type":"string","description":"New color ID for the event (optional)"},"attendees":{"type":"array","description":"New list of attendees (optional, replaces existing attendees). Each attendee can include responseStatus to preserve or set RSVP state.","items":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Email address of the attendee"},"responseStatus":{"type":"string","enum":["needsAction","declined","tentative","accepted"],"description":"The attendee's response status. Use 'accepted' to auto-accept an invite for this attendee."},"optional":{"type":"boolean","description":"Whether this is an optional attendee"},"resource":{"type":"boolean","description":"Whether the attendee is a resource (e.g. a meeting room)"}},"required":["email"]}},"reminders":{"type":"object","description":"New reminder settings for the event (optional)","properties":{"useDefault":{"type":"boolean","description":"Whether to use the default reminders"},"overrides":{"type":"array","description":"Custom reminders (uses popup notifications by default unless email is specified)","items":{"type":"object","properties":{"method":{"type":"string","enum":["email","popup"],"description":"Reminder method (defaults to popup unless email is specified)","default":"popup"},"minutes":{"type":"number","description":"Minutes before the event to trigger the reminder"}},"required":["minutes"]}}},"required":["useDefault"]},"recurrence":{"type":"array","description":"New list of recurrence rules (RFC5545 format, optional, replaces existing rules). Example: [\"RRULE:FREQ=DAILY;COUNT=10\"]","items":{"type":"string"}}},"required":["calendarId","eventId","timeZone"]},"enabled":true,"action":{"path":"/calendars/{calendarId}/events/{eventId}","method":"PATCH","mapping":{"params":"{\n \"calendarId\": arguments.calendarId,\n \"eventId\": arguments.eventId\n }","body":"{\n \"summary\": arguments.summary,\n \"description\": arguments.description,\n \"start\": { \"dateTime\": arguments.start, \"timeZone\": arguments.timeZone },\n \"end\": { \"dateTime\": arguments.end, \"timeZone\": arguments.timeZone },\n \"location\": arguments.location,\n \"attendees\": arguments.attendees,\n \"colorId\": arguments.colorId,\n \"reminders\": arguments.reminders,\n \"recurrence\": arguments.recurrence\n }"}},"annotations":{"destructiveHint":true,"idempotentHint":true,"openWorldHint":true}},{"name":"Delete Event","description":"Delete a calendar event","slug":"delete-event","ai_risk":{"level":"high","score":8,"reasoning":"This tool deletes a calendar event, which is a destructive action that can lead to irreversible data loss, thus high risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"inputSchema":{"type":"object","properties":{"calendarId":{"type":"string","description":"ID of the calendar containing the event"},"eventId":{"type":"string","description":"ID of the event to delete"}},"required":["calendarId","eventId"]},"enabled":false,"action":{"path":"/calendars/{calendarId}/events/{eventId}","method":"DELETE","mapping":{"params":"{\n \"calendarId\": arguments.calendarId,\n \"eventId\": arguments.eventId\n }"}},"annotations":{"destructiveHint":true,"idempotentHint":true}},{"name":"Check Availability","slug":"check-availability","ai_risk":{"level":"low","score":1,"reasoning":"This tool checks availability for specified calendars and is read-only, resulting in low risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"action":{"path":"/freeBusy","method":"POST","mapping":{"body":"{ \"timeMin\": arguments.timeMin, \"timeMax\": arguments.timeMax, \"items\": arguments.items }","response":""}},"enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"description":"Check availability for specified calendars using the Google Calendar Free/Busy API to determine availability.","inputSchema":{"type":"object","required":["timeMin","timeMax","items"],"properties":{"items":{"type":"array","items":{"type":"object","required":["id"],"properties":{"id":{"type":"string","description":"The email address of the calendar to check for availability."}}},"description":"A list of calendars to check for availability."},"timeMax":{"type":"string","format":"date-time","description":"The end of the time period to check for availability (exclusive)."},"timeMin":{"type":"string","format":"date-time","description":"The start of the time period to check for availability (inclusive)."}}}}]}}
1
+ {"id":"google-calendar","status":"active","internal_status":"tool-works","applications":["google-calendar"],"definition":{"display":{"name":"Google Calendar","description":"Google Calendar is a web-based calendar service developed by Google.","icon":"google-calendar.svg","website":"https://www.google.com/calendar","category":"scheduling-calendar","docs_url":"https://docs.withwillow.ai/docs/mcp-servers/built-in/google-calendar"},"api":{"base_url":"https://www.googleapis.com/calendar/v3"},"auth":{"methods":{"oauth":{"authUrl":"https://accounts.google.com/o/oauth2/v2/auth","tokenUrl":"https://oauth2.googleapis.com/token","authInitUrlParams":{"access_type":"offline","prompt":"consent"},"scopes":["https://www.googleapis.com/auth/calendar","https://www.googleapis.com/auth/calendar.readonly"],"defaultScopes":["https://www.googleapis.com/auth/calendar"],"scopeTemplates":[{"id":"read-only","name":"Read-only","description":"List calendars and events and check free/busy. Can't create or change events.","scopes":["https://www.googleapis.com/auth/calendar.readonly"]},{"id":"full-access","name":"Full access","description":"Read, create, update and delete events on every calendar the user can access.","scopes":["https://www.googleapis.com/auth/calendar"]}],"codeExchangeConfig":{"modelCredentialsMapping":"{\n \"access_token\": access_token, \n \"expires_at\": $fromMillis($millis() + expires_in * 1000),\n \"refresh_token\": refresh_token,\n \"refresh_token_expires_at\": $fromMillis($millis() + refresh_token_expires_in * 1000),\n \"scope\": scope,\n \"token_type\": token_type\n }"}}}},"tools":[{"name":"List Calendars","description":"List all available calendars","slug":"list-calendars","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists all available calendars and is read-only, posing minimal risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"inputSchema":{"type":"object","properties":{},"required":[]},"enabled":true,"action":{"path":"/users/me/calendarList","method":"GET","mapping":{}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"List Events","description":"List events from a calendar","slug":"list-events","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists events from a calendar and is read-only, making it low risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"inputSchema":{"type":"object","properties":{"calendarId":{"type":"string","description":"ID of the calendar to list events from (use 'primary' for the main calendar)"},"timeMin":{"type":"string","format":"date-time","description":"Start time in ISO format with timezone required (e.g., 2024-01-01T00:00:00Z or 2024-01-01T00:00:00+00:00). Date-time must end with Z (UTC) or +/-HH:MM offset."},"timeMax":{"type":"string","format":"date-time","description":"End time in ISO format with timezone required (e.g., 2024-12-31T23:59:59Z or 2024-12-31T23:59:59+00:00). Date-time must end with Z (UTC) or +/-HH:MM offset."}},"required":["calendarId"]},"enabled":true,"action":{"path":"/calendars/{calendarId}/events","method":"GET","mapping":{"params":"{\n \"calendarId\": arguments.calendarId\n }","query":"{\n \"timeMin\": arguments.timeMin,\n \"timeMax\": arguments.timeMax\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"Search Events","description":"Search for events in a calendar by text query","slug":"search-events","ai_risk":{"level":"low","score":1,"reasoning":"This tool searches for events in a calendar by text query and is read-only, thus low risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"inputSchema":{"type":"object","properties":{"calendarId":{"type":"string","description":"ID of the calendar to search events in (use 'primary' for the main calendar)"},"query":{"type":"string","description":"Free text search query (searches summary, description, location, attendees, etc.)"},"timeMin":{"type":"string","format":"date-time","description":"Start time boundary in ISO format with timezone required (e.g., 2024-01-01T00:00:00Z or 2024-01-01T00:00:00+00:00). Date-time must end with Z (UTC) or +/-HH:MM offset."},"timeMax":{"type":"string","format":"date-time","description":"End time boundary in ISO format with timezone required (e.g., 2024-12-31T23:59:59Z or 2024-12-31T23:59:59+00:00). Date-time must end with Z (UTC) or +/-HH:MM offset."}},"required":["calendarId","query"]},"enabled":true,"action":{"path":"/calendars/{calendarId}/events","method":"GET","mapping":{"params":"{\n \"calendarId\": arguments.calendarId\n }","query":"{\n \"q\": arguments.query,\n \"timeMin\": arguments.timeMin,\n \"timeMax\": arguments.timeMax\n }"}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"List Colors","description":"List available color IDs and meanings","slug":"list-colors","ai_risk":{"level":"low","score":1,"reasoning":"This tool lists available color IDs and meanings and is read-only, indicating low risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"inputSchema":{"type":"object","properties":{},"required":[]},"enabled":true,"action":{"path":"/colors","method":"GET","mapping":{}},"annotations":{"readOnlyHint":true,"idempotentHint":true}},{"name":"Create Event","description":"Create a new calendar event","slug":"create-event","ai_risk":{"level":"medium","score":5,"reasoning":"This tool creates a new calendar event, which is a standard write operation and carries medium risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"inputSchema":{"type":"object","properties":{"calendarId":{"type":"string","description":"ID of the calendar to create the event in (use 'primary' for the main calendar)"},"summary":{"type":"string","description":"Title of the event"},"description":{"type":"string","description":"Description/notes for the event (optional)"},"start":{"type":"string","format":"date-time","description":"Start time in ISO format with timezone required (e.g., 2024-08-15T10:00:00Z or 2024-08-15T10:00:00-07:00). Date-time must end with Z (UTC) or +/-HH:MM offset."},"end":{"type":"string","format":"date-time","description":"End time in ISO format with timezone required (e.g., 2024-08-15T11:00:00Z or 2024-08-15T11:00:00-07:00). Date-time must end with Z (UTC) or +/-HH:MM offset."},"timeZone":{"type":"string","description":"Timezone of the event start/end times, formatted as an IANA Time Zone Database name (e.g., America/Los_Angeles). Required if start/end times are specified, especially for recurring events."},"location":{"type":"string","description":"Location of the event (optional)"},"attendees":{"type":"array","description":"List of attendees (optional). Each attendee can include responseStatus to set RSVP state.","items":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Email address of the attendee"},"responseStatus":{"type":"string","enum":["needsAction","declined","tentative","accepted"],"description":"The attendee's response status. Use 'accepted' to auto-accept an invite for this attendee."},"optional":{"type":"boolean","description":"Whether this is an optional attendee"},"resource":{"type":"boolean","description":"Whether the attendee is a resource (e.g. a meeting room)"}},"required":["email"]}},"colorId":{"type":"string","description":"Color ID for the event (optional, use list-colors to see available IDs)"},"reminders":{"type":"object","description":"Reminder settings for the event","properties":{"useDefault":{"type":"boolean","description":"Whether to use the default reminders"},"overrides":{"type":"array","description":"Custom reminders (uses popup notifications by default unless email is specified)","items":{"type":"object","properties":{"method":{"type":"string","enum":["email","popup"],"description":"Reminder method (defaults to popup unless email is specified)","default":"popup"},"minutes":{"type":"number","description":"Minutes before the event to trigger the reminder"}},"required":["minutes"]}}},"required":["useDefault"]},"recurrence":{"type":"array","description":"List of recurrence rules (RRULE, EXRULE, RDATE, EXDATE) in RFC5545 format (optional). Example: [\"RRULE:FREQ=WEEKLY;COUNT=5\"]","items":{"type":"string"}}},"required":["calendarId","summary","start","end","timeZone"]},"enabled":true,"action":{"path":"/calendars/{calendarId}/events","method":"POST","mapping":{"params":"{\n \"calendarId\": arguments.calendarId\n }","body":"{\n \"summary\": arguments.summary,\n \"description\": arguments.description,\n \"start\": { \"dateTime\": arguments.start, \"timeZone\": arguments.timeZone },\n \"end\": { \"dateTime\": arguments.end, \"timeZone\": arguments.timeZone },\n \"location\": arguments.location,\n \"attendees\": arguments.attendees,\n \"colorId\": arguments.colorId,\n \"reminders\": arguments.reminders,\n \"recurrence\": arguments.recurrence\n }"}},"annotations":{"destructiveHint":true,"openWorldHint":true}},{"name":"Update Event","description":"Update an existing calendar event","slug":"update-event","ai_risk":{"level":"medium","score":5,"reasoning":"This tool updates an existing calendar event, representing a standard write operation with medium risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"inputSchema":{"type":"object","properties":{"calendarId":{"type":"string","description":"ID of the calendar containing the event"},"eventId":{"type":"string","description":"ID of the event to update"},"summary":{"type":"string","description":"New title for the event (optional)"},"description":{"type":"string","description":"New description for the event (optional)"},"start":{"type":"string","format":"date-time","description":"New start time in ISO format with timezone required (e.g., 2024-08-15T10:00:00Z or 2024-08-15T10:00:00-07:00). Date-time must end with Z (UTC) or +/-HH:MM offset."},"end":{"type":"string","format":"date-time","description":"New end time in ISO format with timezone required (e.g., 2024-08-15T11:00:00Z or 2024-08-15T11:00:00-07:00). Date-time must end with Z (UTC) or +/-HH:MM offset."},"timeZone":{"type":"string","description":"Timezone for the start/end times (IANA format, e.g., America/Los_Angeles). Required if modifying start/end, or for recurring events."},"location":{"type":"string","description":"New location for the event (optional)"},"colorId":{"type":"string","description":"New color ID for the event (optional)"},"attendees":{"type":"array","description":"New list of attendees (optional, replaces existing attendees). Each attendee can include responseStatus to preserve or set RSVP state.","items":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Email address of the attendee"},"responseStatus":{"type":"string","enum":["needsAction","declined","tentative","accepted"],"description":"The attendee's response status. Use 'accepted' to auto-accept an invite for this attendee."},"optional":{"type":"boolean","description":"Whether this is an optional attendee"},"resource":{"type":"boolean","description":"Whether the attendee is a resource (e.g. a meeting room)"}},"required":["email"]}},"reminders":{"type":"object","description":"New reminder settings for the event (optional)","properties":{"useDefault":{"type":"boolean","description":"Whether to use the default reminders"},"overrides":{"type":"array","description":"Custom reminders (uses popup notifications by default unless email is specified)","items":{"type":"object","properties":{"method":{"type":"string","enum":["email","popup"],"description":"Reminder method (defaults to popup unless email is specified)","default":"popup"},"minutes":{"type":"number","description":"Minutes before the event to trigger the reminder"}},"required":["minutes"]}}},"required":["useDefault"]},"recurrence":{"type":"array","description":"New list of recurrence rules (RFC5545 format, optional, replaces existing rules). Example: [\"RRULE:FREQ=DAILY;COUNT=10\"]","items":{"type":"string"}}},"required":["calendarId","eventId","timeZone"]},"enabled":true,"action":{"path":"/calendars/{calendarId}/events/{eventId}","method":"PATCH","mapping":{"params":"{\n \"calendarId\": arguments.calendarId,\n \"eventId\": arguments.eventId\n }","body":"{\n \"summary\": arguments.summary,\n \"description\": arguments.description,\n \"start\": { \"dateTime\": arguments.start, \"timeZone\": arguments.timeZone },\n \"end\": { \"dateTime\": arguments.end, \"timeZone\": arguments.timeZone },\n \"location\": arguments.location,\n \"attendees\": arguments.attendees,\n \"colorId\": arguments.colorId,\n \"reminders\": arguments.reminders,\n \"recurrence\": arguments.recurrence\n }"}},"annotations":{"destructiveHint":true,"idempotentHint":true,"openWorldHint":true}},{"name":"Delete Event","description":"Delete a calendar event","slug":"delete-event","ai_risk":{"level":"high","score":8,"reasoning":"This tool deletes a calendar event, which is a destructive action that can lead to irreversible data loss, thus high risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"inputSchema":{"type":"object","properties":{"calendarId":{"type":"string","description":"ID of the calendar containing the event"},"eventId":{"type":"string","description":"ID of the event to delete"}},"required":["calendarId","eventId"]},"enabled":false,"action":{"path":"/calendars/{calendarId}/events/{eventId}","method":"DELETE","mapping":{"params":"{\n \"calendarId\": arguments.calendarId,\n \"eventId\": arguments.eventId\n }"}},"annotations":{"destructiveHint":true,"idempotentHint":true}},{"name":"Check Availability","slug":"check-availability","ai_risk":{"level":"low","score":1,"reasoning":"This tool checks availability for specified calendars and is read-only, resulting in low risk.","calculated_at":"2026-05-22T10:04:01.672Z"},"action":{"path":"/freeBusy","method":"POST","mapping":{"body":"{ \"timeMin\": arguments.timeMin, \"timeMax\": arguments.timeMax, \"items\": arguments.items }","response":""}},"enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"description":"Check availability for specified calendars using the Google Calendar Free/Busy API to determine availability.","inputSchema":{"type":"object","required":["timeMin","timeMax","items"],"properties":{"items":{"type":"array","items":{"type":"object","required":["id"],"properties":{"id":{"type":"string","description":"The email address of the calendar to check for availability."}}},"description":"A list of calendars to check for availability."},"timeMax":{"type":"string","format":"date-time","description":"The end of the time period to check for availability (exclusive)."},"timeMin":{"type":"string","format":"date-time","description":"The start of the time period to check for availability (inclusive)."}}}}]}}
@@ -1 +1 @@
1
- {"id":"google-workspace-admin","status":"active","internal_status":"tool-works","applications":["google-workspace"],"definition":{"display":{"name":"Google Workspace Admin","description":"Administer your Google Workspace tenant through the Admin SDK: manage users, groups and members, organizational units, ChromeOS and mobile devices, and read audit and usage reports.","icon":"google-workspace.svg","website":"https://admin.google.com/","category":"identity-security","docs_url":"https://docs.withwillow.ai/docs/mcp-servers/built-in/google-workspace-admin"},"api":{"base_url":"https://admin.googleapis.com"},"auth":{"methods":{"oauth":{"authUrl":"https://accounts.google.com/o/oauth2/v2/auth","tokenUrl":"https://oauth2.googleapis.com/token","authInitUrlParams":{"access_type":"offline","prompt":"consent"},"scopes":["https://www.googleapis.com/auth/admin.directory.user","https://www.googleapis.com/auth/admin.directory.group","https://www.googleapis.com/auth/admin.directory.group.member","https://www.googleapis.com/auth/admin.directory.orgunit","https://www.googleapis.com/auth/admin.directory.device.chromeos","https://www.googleapis.com/auth/admin.directory.device.mobile","https://www.googleapis.com/auth/admin.reports.audit.readonly","https://www.googleapis.com/auth/admin.reports.usage.readonly","https://www.googleapis.com/auth/apps.licensing"],"defaultScopes":["https://www.googleapis.com/auth/admin.directory.user","https://www.googleapis.com/auth/admin.directory.group","https://www.googleapis.com/auth/admin.directory.orgunit","https://www.googleapis.com/auth/admin.directory.device.chromeos","https://www.googleapis.com/auth/admin.directory.device.mobile","https://www.googleapis.com/auth/admin.reports.audit.readonly","https://www.googleapis.com/auth/admin.reports.usage.readonly","https://www.googleapis.com/auth/apps.licensing"],"codeExchangeConfig":{"modelCredentialsMapping":"{\n \"access_token\": access_token, \n \"expires_at\": $fromMillis($millis() + expires_in * 1000),\n \"refresh_token\": refresh_token,\n \"refresh_token_expires_at\": $fromMillis($millis() + refresh_token_expires_in * 1000),\n \"scope\": scope,\n \"token_type\": token_type\n }"}}}},"tools":[{"name":"List Users","description":"List users in the Google Workspace account. Supports search queries, paging, and ordering. By default lists users for the authenticated admin's own customer (my_customer).","slug":"list-users","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","properties":{"customer":{"type":"string","description":"The unique ID of the customer's Google Workspace account. Use 'my_customer' (default) for the authenticated admin's account.","default":"my_customer"},"domain":{"type":"string","description":"Restrict results to a specific domain. If omitted, all domains for the customer are returned."},"query":{"type":"string","description":"Search query using the Admin SDK query syntax, e.g. \"email:jane*\", \"orgUnitPath='/Sales'\", or \"isSuspended=true\"."},"maxResults":{"type":"number","description":"Maximum number of results per page (1-500). Default 100.","default":100},"pageToken":{"type":"string","description":"Token to retrieve the next page of results."},"orderBy":{"type":"string","enum":["email","familyName","givenName"],"description":"Property to order results by."},"showDeleted":{"type":"boolean","description":"If true, list only recently deleted users."},"projection":{"type":"string","enum":["basic","custom","full"],"description":"Subset of fields to fetch. Default 'basic'."}}},"action":{"path":"/admin/directory/v1/users","method":"GET","mapping":{"query":"{\n \"customer\": arguments.domain ? undefined : (arguments.customer ? arguments.customer : \"my_customer\"),\n \"domain\": arguments.domain,\n \"query\": arguments.query,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 100,\n \"pageToken\": arguments.pageToken,\n \"orderBy\": arguments.orderBy,\n \"showDeleted\": $exists(arguments.showDeleted) ? $string(arguments.showDeleted) : undefined,\n \"projection\": arguments.projection\n }"}}},{"name":"Get User","description":"Retrieve a single user by their primary email address or unique user ID.","slug":"get-user","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["userKey"],"properties":{"userKey":{"type":"string","description":"The user's primary email address, alias email, or unique user ID."},"projection":{"type":"string","enum":["basic","custom","full"],"description":"Subset of fields to fetch. Default 'basic'."}}},"action":{"path":"/admin/directory/v1/users/{userKey}","method":"GET","mapping":{"params":"{ \"userKey\": arguments.userKey }","query":"{ \"projection\": arguments.projection }"}}},{"name":"Create User","description":"Create a new user in the Google Workspace account. Requires a primary email, first/last name, and an initial password.","slug":"create-user","enabled":true,"annotations":{"destructiveHint":false},"inputSchema":{"type":"object","required":["primaryEmail","givenName","familyName","password"],"properties":{"primaryEmail":{"type":"string","description":"The user's primary email address, e.g. jane@example.com."},"givenName":{"type":"string","description":"The user's first name."},"familyName":{"type":"string","description":"The user's last name."},"password":{"type":"string","description":"Initial password for the user (minimum 8 characters). Consider requiring a change on next login."},"changePasswordAtNextLogin":{"type":"boolean","description":"If true, the user must change their password at next sign-in.","default":true},"orgUnitPath":{"type":"string","description":"The full path of the org unit to place the user in, e.g. '/Sales'. Defaults to the root org unit '/'."}}},"action":{"path":"/admin/directory/v1/users","method":"POST","mapping":{"body":"{\n \"primaryEmail\": arguments.primaryEmail,\n \"name\": {\n \"givenName\": arguments.givenName,\n \"familyName\": arguments.familyName\n },\n \"password\": arguments.password,\n \"changePasswordAtNextLogin\": $exists(arguments.changePasswordAtNextLogin) ? arguments.changePasswordAtNextLogin : true,\n \"orgUnitPath\": arguments.orgUnitPath\n }"}}},{"name":"Update User","description":"Update fields on an existing user using a partial patch. Only the fields you provide are changed.","slug":"update-user","enabled":true,"annotations":{"destructiveHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["userKey"],"properties":{"userKey":{"type":"string","description":"The user's primary email or unique user ID."},"givenName":{"type":"string","description":"New first name."},"familyName":{"type":"string","description":"New last name."},"orgUnitPath":{"type":"string","description":"Move the user to this org unit path, e.g. '/Sales'."},"suspended":{"type":"boolean","description":"Set the user's suspended state."}}},"action":{"path":"/admin/directory/v1/users/{userKey}","method":"PATCH","mapping":{"params":"{ \"userKey\": arguments.userKey }","body":"{\n \"name\": ($exists(arguments.givenName) or $exists(arguments.familyName)) ? {\n \"givenName\": arguments.givenName,\n \"familyName\": arguments.familyName\n } : undefined,\n \"orgUnitPath\": arguments.orgUnitPath,\n \"suspended\": arguments.suspended\n }"}}},{"name":"Suspend User","description":"Suspend or un-suspend a user. Suspending immediately blocks the user from signing in without deleting the account.","slug":"suspend-user","enabled":true,"annotations":{"destructiveHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["userKey"],"properties":{"userKey":{"type":"string","description":"The user's primary email or unique user ID."},"suspended":{"type":"boolean","description":"True to suspend the user, false to restore access. Defaults to true.","default":true}}},"action":{"path":"/admin/directory/v1/users/{userKey}","method":"PATCH","mapping":{"params":"{ \"userKey\": arguments.userKey }","body":"{ \"suspended\": $exists(arguments.suspended) ? arguments.suspended : true }"}}},{"name":"Assign License","description":"Assign a Google Workspace product license to a user by product and SKU ID. Common productId is Google-Apps; SKU IDs vary by edition (e.g. Google-Apps-For-Business).","slug":"assign-license","enabled":true,"annotations":{"destructiveHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["productId","skuId","userId"],"properties":{"productId":{"type":"string","description":"Product ID, e.g. Google-Apps or Google-Vault."},"skuId":{"type":"string","description":"SKU ID for the license edition, e.g. Google-Apps-For-Business."},"userId":{"type":"string","description":"The user's primary email address."}},"additionalProperties":false},"action":{"path":"https://licensing.googleapis.com/apps/licensing/v1/product/{productId}/sku/{skuId}/user","method":"POST","mapping":{"params":"{\n \"productId\": arguments.productId,\n \"skuId\": arguments.skuId\n }","body":"{ \"userId\": arguments.userId }","response":"{\n \"userId\": response.userId,\n \"productId\": response.productId,\n \"skuId\": response.skuId,\n \"skuName\": response.skuName,\n \"productName\": response.productName\n }"}}},{"name":"Revoke License","description":"Revoke a Google Workspace product license from a user, freeing the seat for reassignment.","slug":"revoke-license","enabled":true,"annotations":{"destructiveHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["productId","skuId","userId"],"properties":{"productId":{"type":"string","description":"Product ID, e.g. Google-Apps or Google-Vault."},"skuId":{"type":"string","description":"SKU ID for the license edition to revoke."},"userId":{"type":"string","description":"The user's primary email address."}},"additionalProperties":false},"action":{"path":"https://licensing.googleapis.com/apps/licensing/v1/product/{productId}/sku/{skuId}/user/{userId}","method":"DELETE","mapping":{"params":"{\n \"productId\": arguments.productId,\n \"skuId\": arguments.skuId,\n \"userId\": arguments.userId\n }"}}},{"name":"List Groups","description":"List groups in the Google Workspace account. Optionally filter by domain, by a member's email, or by a search query.","slug":"list-groups","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","properties":{"customer":{"type":"string","description":"Customer ID. Use 'my_customer' (default) for the authenticated admin's account. Ignored when 'domain' or 'userKey' is provided.","default":"my_customer"},"domain":{"type":"string","description":"Restrict results to groups in this domain."},"userKey":{"type":"string","description":"If provided, list only groups that this user (email or ID) is a member of."},"query":{"type":"string","description":"Search query, e.g. \"email:sales*\" or \"name:Engineering\"."},"maxResults":{"type":"number","description":"Maximum number of results per page (1-200). Default 100.","default":100},"pageToken":{"type":"string","description":"Token to retrieve the next page of results."}}},"action":{"path":"/admin/directory/v1/groups","method":"GET","mapping":{"query":"{\n \"customer\": (arguments.domain or arguments.userKey) ? undefined : (arguments.customer ? arguments.customer : \"my_customer\"),\n \"domain\": arguments.domain,\n \"userKey\": arguments.userKey,\n \"query\": arguments.query,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 100,\n \"pageToken\": arguments.pageToken\n }"}}},{"name":"Get Group","description":"Retrieve a single group by its email address or unique ID.","slug":"get-group","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["groupKey"],"properties":{"groupKey":{"type":"string","description":"The group's email address or unique group ID."}}},"action":{"path":"/admin/directory/v1/groups/{groupKey}","method":"GET","mapping":{"params":"{ \"groupKey\": arguments.groupKey }"}}},{"name":"Create Group","description":"Create a new group with the given email address and name.","slug":"create-group","enabled":true,"annotations":{"destructiveHint":false},"inputSchema":{"type":"object","required":["email","name"],"properties":{"email":{"type":"string","description":"The group's email address, e.g. team@example.com."},"name":{"type":"string","description":"Display name of the group."},"description":{"type":"string","description":"Optional description of the group's purpose."}}},"action":{"path":"/admin/directory/v1/groups","method":"POST","mapping":{"body":"{\n \"email\": arguments.email,\n \"name\": arguments.name,\n \"description\": arguments.description\n }"}}},{"name":"List Group Members","description":"List the members of a group.","slug":"list-group-members","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["groupKey"],"properties":{"groupKey":{"type":"string","description":"The group's email address or unique group ID."},"roles":{"type":"string","description":"Comma-separated roles to filter by, e.g. 'OWNER,MANAGER,MEMBER'."},"maxResults":{"type":"number","description":"Maximum number of results per page (1-200). Default 100.","default":100},"pageToken":{"type":"string","description":"Token to retrieve the next page of results."}}},"action":{"path":"/admin/directory/v1/groups/{groupKey}/members","method":"GET","mapping":{"params":"{ \"groupKey\": arguments.groupKey }","query":"{\n \"roles\": arguments.roles,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 100,\n \"pageToken\": arguments.pageToken\n }"}}},{"name":"Add Group Member","description":"Add a user (or another group) as a member of a group.","slug":"add-group-member","enabled":true,"annotations":{"destructiveHint":false},"inputSchema":{"type":"object","required":["groupKey","email"],"properties":{"groupKey":{"type":"string","description":"The group's email address or unique group ID."},"email":{"type":"string","description":"Email address of the member to add."},"role":{"type":"string","enum":["MEMBER","MANAGER","OWNER"],"description":"Role for the new member. Defaults to MEMBER.","default":"MEMBER"}}},"action":{"path":"/admin/directory/v1/groups/{groupKey}/members","method":"POST","mapping":{"params":"{ \"groupKey\": arguments.groupKey }","body":"{\n \"email\": arguments.email,\n \"role\": arguments.role ? arguments.role : \"MEMBER\"\n }"}}},{"name":"Remove Group Member","description":"Remove a member from a group.","slug":"remove-group-member","enabled":true,"annotations":{"destructiveHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["groupKey","memberKey"],"properties":{"groupKey":{"type":"string","description":"The group's email address or unique group ID."},"memberKey":{"type":"string","description":"The member's email address or unique ID to remove from the group."}}},"action":{"path":"/admin/directory/v1/groups/{groupKey}/members/{memberKey}","method":"DELETE","mapping":{"params":"{ \"groupKey\": arguments.groupKey, \"memberKey\": arguments.memberKey }"}}},{"name":"List Org Units","description":"List the organizational units in the Google Workspace account.","slug":"list-org-units","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","properties":{"customerId":{"type":"string","description":"Customer ID. Use 'my_customer' (default) for the authenticated admin's account.","default":"my_customer"},"orgUnitPath":{"type":"string","description":"If provided, list org units under this path, e.g. '/Sales'."},"type":{"type":"string","enum":["all","children"],"description":"Whether to return all sub-org units or only immediate children. Default 'children'."}}},"action":{"path":"/admin/directory/v1/customer/{customerId}/orgunits","method":"GET","mapping":{"params":"{ \"customerId\": arguments.customerId ? arguments.customerId : \"my_customer\" }","query":"{\n \"orgUnitPath\": arguments.orgUnitPath,\n \"type\": arguments.type\n }"}}},{"name":"Get Org Unit","description":"Retrieve a single organizational unit by its path.","slug":"get-org-unit","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["orgUnitPath"],"properties":{"customerId":{"type":"string","description":"Customer ID. Use 'my_customer' (default) for the authenticated admin's account.","default":"my_customer"},"orgUnitPath":{"type":"string","description":"The full path of the org unit, without the leading slash, e.g. 'Sales/West'."}}},"action":{"path":"/admin/directory/v1/customer/{customerId}/orgunits/{orgUnitPath}","method":"GET","mapping":{"params":"{\n \"customerId\": arguments.customerId ? arguments.customerId : \"my_customer\",\n \"orgUnitPath\": arguments.orgUnitPath\n }"}}},{"name":"List ChromeOS Devices","description":"List ChromeOS devices enrolled in the Google Workspace account.","slug":"list-chromeos-devices","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","properties":{"customerId":{"type":"string","description":"Customer ID. Use 'my_customer' (default) for the authenticated admin's account.","default":"my_customer"},"query":{"type":"string","description":"Search query, e.g. \"status:ACTIVE\" or \"user:jane@example.com\"."},"orgUnitPath":{"type":"string","description":"Restrict results to devices in this org unit path."},"maxResults":{"type":"number","description":"Maximum number of results per page (1-300). Default 100.","default":100},"pageToken":{"type":"string","description":"Token to retrieve the next page of results."}}},"action":{"path":"/admin/directory/v1/customer/{customerId}/devices/chromeos","method":"GET","mapping":{"params":"{ \"customerId\": arguments.customerId ? arguments.customerId : \"my_customer\" }","query":"{\n \"query\": arguments.query,\n \"orgUnitPath\": arguments.orgUnitPath,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 100,\n \"pageToken\": arguments.pageToken\n }"}}},{"name":"List Mobile Devices","description":"List mobile devices (Android, iOS) enrolled in the Google Workspace account.","slug":"list-mobile-devices","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","properties":{"customerId":{"type":"string","description":"Customer ID. Use 'my_customer' (default) for the authenticated admin's account.","default":"my_customer"},"query":{"type":"string","description":"Search query, e.g. \"email:jane@example.com\" or \"type:ANDROID\"."},"maxResults":{"type":"number","description":"Maximum number of results per page (1-100). Default 100.","default":100},"pageToken":{"type":"string","description":"Token to retrieve the next page of results."}}},"action":{"path":"/admin/directory/v1/customer/{customerId}/devices/mobile","method":"GET","mapping":{"params":"{ \"customerId\": arguments.customerId ? arguments.customerId : \"my_customer\" }","query":"{\n \"query\": arguments.query,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 100,\n \"pageToken\": arguments.pageToken\n }"}}},{"name":"Action Mobile Device","description":"Take an administrative action on a mobile device, such as blocking it or wiping corporate data. Destructive actions cannot be undone.","slug":"action-mobile-device","enabled":true,"annotations":{"destructiveHint":true},"inputSchema":{"type":"object","required":["resourceId","action"],"properties":{"customerId":{"type":"string","description":"Customer ID. Use 'my_customer' (default) for the authenticated admin's account.","default":"my_customer"},"resourceId":{"type":"string","description":"The unique device resource ID (from List Mobile Devices)."},"action":{"type":"string","enum":["admin_account_wipe","admin_remote_wipe","approve","block","cancel_remote_wipe_then_activate","cancel_remote_wipe_then_block"],"description":"The action to perform. 'admin_account_wipe' removes only corporate data; 'admin_remote_wipe' factory-resets the device."}}},"action":{"path":"/admin/directory/v1/customer/{customerId}/devices/mobile/{resourceId}/action","method":"POST","mapping":{"params":"{\n \"customerId\": arguments.customerId ? arguments.customerId : \"my_customer\",\n \"resourceId\": arguments.resourceId\n }","body":"{ \"action\": arguments.action }"}}},{"name":"List Audit Activities","description":"Read audit activity events from the Reports API for a given application (e.g. login, admin, drive, token). Use to investigate admin changes, sign-ins, and other security-relevant events.","slug":"list-audit-activities","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["applicationName"],"properties":{"applicationName":{"type":"string","description":"The application to read events for, e.g. 'login', 'admin', 'drive', 'token', 'user_accounts', 'groups'."},"userKey":{"type":"string","description":"Filter by a specific user's email or ID, or 'all' for all users. Default 'all'.","default":"all"},"startTime":{"type":"string","description":"Only return events at or after this RFC 3339 timestamp, e.g. '2024-01-01T00:00:00Z'."},"endTime":{"type":"string","description":"Only return events at or before this RFC 3339 timestamp."},"eventName":{"type":"string","description":"Filter by a specific event name."},"filters":{"type":"string","description":"Event-parameter filters, e.g. \"doc_id==12345\" (see Reports API docs)."},"maxResults":{"type":"number","description":"Maximum number of events per page (1-1000). Default 100.","default":100},"pageToken":{"type":"string","description":"Token to retrieve the next page of results."}}},"action":{"path":"/admin/reports/v1/activity/users/{userKey}/applications/{applicationName}","method":"GET","mapping":{"params":"{\n \"userKey\": arguments.userKey ? arguments.userKey : \"all\",\n \"applicationName\": arguments.applicationName\n }","query":"{\n \"startTime\": arguments.startTime,\n \"endTime\": arguments.endTime,\n \"eventName\": arguments.eventName,\n \"filters\": arguments.filters,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 100,\n \"pageToken\": arguments.pageToken\n }"}}},{"name":"Get User Usage Report","description":"Retrieve usage parameters for a specific user (or all users) on a given date from the Reports API, e.g. last login time, storage used, and 2SV enrollment.","slug":"get-user-usage-report","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["date"],"properties":{"userKey":{"type":"string","description":"The user's email or ID, or 'all' for all users. Default 'all'.","default":"all"},"date":{"type":"string","description":"The date to report on in YYYY-MM-DD form. Usage data is typically available a few days in arrears."},"parameters":{"type":"string","description":"Comma-separated usage parameters to fetch, e.g. 'accounts:last_login_time,accounts:is_2sv_enrolled'."},"filters":{"type":"string","description":"Comma-separated parameter filters to narrow results (see Reports API docs)."},"maxResults":{"type":"number","description":"Maximum number of results per page. Default 100.","default":100},"pageToken":{"type":"string","description":"Token to retrieve the next page of results."}}},"action":{"path":"/admin/reports/v1/usage/users/{userKey}/dates/{date}","method":"GET","mapping":{"params":"{\n \"userKey\": arguments.userKey ? arguments.userKey : \"all\",\n \"date\": arguments.date\n }","query":"{\n \"parameters\": arguments.parameters,\n \"filters\": arguments.filters,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 100,\n \"pageToken\": arguments.pageToken\n }"}}}]}}
1
+ {"id":"google-workspace-admin","status":"active","internal_status":"tool-works","applications":["google-workspace"],"definition":{"display":{"name":"Google Workspace Admin","description":"Administer your Google Workspace tenant through the Admin SDK: manage users, groups and members, organizational units, ChromeOS and mobile devices, and read audit and usage reports.","icon":"google-workspace.svg","website":"https://admin.google.com/","category":"identity-security","docs_url":"https://docs.withwillow.ai/docs/mcp-servers/built-in/google-workspace-admin"},"api":{"base_url":"https://admin.googleapis.com"},"auth":{"methods":{"oauth":{"authUrl":"https://accounts.google.com/o/oauth2/v2/auth","tokenUrl":"https://oauth2.googleapis.com/token","authInitUrlParams":{"access_type":"offline","prompt":"consent"},"scopes":["https://www.googleapis.com/auth/admin.directory.user","https://www.googleapis.com/auth/admin.directory.group","https://www.googleapis.com/auth/admin.directory.group.member","https://www.googleapis.com/auth/admin.directory.orgunit","https://www.googleapis.com/auth/admin.directory.device.chromeos","https://www.googleapis.com/auth/admin.directory.device.mobile","https://www.googleapis.com/auth/admin.reports.audit.readonly","https://www.googleapis.com/auth/admin.reports.usage.readonly","https://www.googleapis.com/auth/apps.licensing","https://www.googleapis.com/auth/admin.directory.user.readonly","https://www.googleapis.com/auth/admin.directory.group.readonly","https://www.googleapis.com/auth/admin.directory.group.member.readonly","https://www.googleapis.com/auth/admin.directory.orgunit.readonly","https://www.googleapis.com/auth/admin.directory.device.chromeos.readonly","https://www.googleapis.com/auth/admin.directory.device.mobile.readonly"],"defaultScopes":["https://www.googleapis.com/auth/admin.directory.user","https://www.googleapis.com/auth/admin.directory.group","https://www.googleapis.com/auth/admin.directory.orgunit","https://www.googleapis.com/auth/admin.directory.device.chromeos","https://www.googleapis.com/auth/admin.directory.device.mobile","https://www.googleapis.com/auth/admin.reports.audit.readonly","https://www.googleapis.com/auth/admin.reports.usage.readonly","https://www.googleapis.com/auth/apps.licensing"],"scopeTemplates":[{"id":"read-only","name":"Read-only","description":"Read users, groups and members, organizational units and ChromeOS and mobile devices, plus audit and usage reports. Can't change the tenant.","scopes":["https://www.googleapis.com/auth/admin.directory.user.readonly","https://www.googleapis.com/auth/admin.directory.group.readonly","https://www.googleapis.com/auth/admin.directory.group.member.readonly","https://www.googleapis.com/auth/admin.directory.orgunit.readonly","https://www.googleapis.com/auth/admin.directory.device.chromeos.readonly","https://www.googleapis.com/auth/admin.directory.device.mobile.readonly","https://www.googleapis.com/auth/admin.reports.audit.readonly","https://www.googleapis.com/auth/admin.reports.usage.readonly"]},{"id":"user-lifecycle","name":"User onboarding and offboarding","description":"Create, update and suspend users, manage groups and their members, and assign licenses. Devices and reports stay off.","scopes":["https://www.googleapis.com/auth/admin.directory.user","https://www.googleapis.com/auth/admin.directory.group","https://www.googleapis.com/auth/admin.directory.group.member","https://www.googleapis.com/auth/admin.directory.orgunit.readonly","https://www.googleapis.com/auth/apps.licensing"]},{"id":"full-access","name":"Full access","description":"Manage users, groups, members, organizational units, ChromeOS and mobile devices and licenses, and read audit and usage reports.","scopes":["https://www.googleapis.com/auth/admin.directory.user","https://www.googleapis.com/auth/admin.directory.group","https://www.googleapis.com/auth/admin.directory.group.member","https://www.googleapis.com/auth/admin.directory.orgunit","https://www.googleapis.com/auth/admin.directory.device.chromeos","https://www.googleapis.com/auth/admin.directory.device.mobile","https://www.googleapis.com/auth/admin.reports.audit.readonly","https://www.googleapis.com/auth/admin.reports.usage.readonly","https://www.googleapis.com/auth/apps.licensing"]}],"codeExchangeConfig":{"modelCredentialsMapping":"{\n \"access_token\": access_token, \n \"expires_at\": $fromMillis($millis() + expires_in * 1000),\n \"refresh_token\": refresh_token,\n \"refresh_token_expires_at\": $fromMillis($millis() + refresh_token_expires_in * 1000),\n \"scope\": scope,\n \"token_type\": token_type\n }"}}}},"tools":[{"name":"List Users","description":"List users in the Google Workspace account. Supports search queries, paging, and ordering. By default lists users for the authenticated admin's own customer (my_customer).","slug":"list-users","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","properties":{"customer":{"type":"string","description":"The unique ID of the customer's Google Workspace account. Use 'my_customer' (default) for the authenticated admin's account.","default":"my_customer"},"domain":{"type":"string","description":"Restrict results to a specific domain. If omitted, all domains for the customer are returned."},"query":{"type":"string","description":"Search query using the Admin SDK query syntax, e.g. \"email:jane*\", \"orgUnitPath='/Sales'\", or \"isSuspended=true\"."},"maxResults":{"type":"number","description":"Maximum number of results per page (1-500). Default 100.","default":100},"pageToken":{"type":"string","description":"Token to retrieve the next page of results."},"orderBy":{"type":"string","enum":["email","familyName","givenName"],"description":"Property to order results by."},"showDeleted":{"type":"boolean","description":"If true, list only recently deleted users."},"projection":{"type":"string","enum":["basic","custom","full"],"description":"Subset of fields to fetch. Default 'basic'."}}},"action":{"path":"/admin/directory/v1/users","method":"GET","mapping":{"query":"{\n \"customer\": arguments.domain ? undefined : (arguments.customer ? arguments.customer : \"my_customer\"),\n \"domain\": arguments.domain,\n \"query\": arguments.query,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 100,\n \"pageToken\": arguments.pageToken,\n \"orderBy\": arguments.orderBy,\n \"showDeleted\": $exists(arguments.showDeleted) ? $string(arguments.showDeleted) : undefined,\n \"projection\": arguments.projection\n }"}}},{"name":"Get User","description":"Retrieve a single user by their primary email address or unique user ID.","slug":"get-user","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["userKey"],"properties":{"userKey":{"type":"string","description":"The user's primary email address, alias email, or unique user ID."},"projection":{"type":"string","enum":["basic","custom","full"],"description":"Subset of fields to fetch. Default 'basic'."}}},"action":{"path":"/admin/directory/v1/users/{userKey}","method":"GET","mapping":{"params":"{ \"userKey\": arguments.userKey }","query":"{ \"projection\": arguments.projection }"}}},{"name":"Create User","description":"Create a new user in the Google Workspace account. Requires a primary email, first/last name, and an initial password.","slug":"create-user","enabled":true,"annotations":{"destructiveHint":false},"inputSchema":{"type":"object","required":["primaryEmail","givenName","familyName","password"],"properties":{"primaryEmail":{"type":"string","description":"The user's primary email address, e.g. jane@example.com."},"givenName":{"type":"string","description":"The user's first name."},"familyName":{"type":"string","description":"The user's last name."},"password":{"type":"string","description":"Initial password for the user (minimum 8 characters). Consider requiring a change on next login."},"changePasswordAtNextLogin":{"type":"boolean","description":"If true, the user must change their password at next sign-in.","default":true},"orgUnitPath":{"type":"string","description":"The full path of the org unit to place the user in, e.g. '/Sales'. Defaults to the root org unit '/'."}}},"action":{"path":"/admin/directory/v1/users","method":"POST","mapping":{"body":"{\n \"primaryEmail\": arguments.primaryEmail,\n \"name\": {\n \"givenName\": arguments.givenName,\n \"familyName\": arguments.familyName\n },\n \"password\": arguments.password,\n \"changePasswordAtNextLogin\": $exists(arguments.changePasswordAtNextLogin) ? arguments.changePasswordAtNextLogin : true,\n \"orgUnitPath\": arguments.orgUnitPath\n }"}}},{"name":"Update User","description":"Update fields on an existing user using a partial patch. Only the fields you provide are changed.","slug":"update-user","enabled":true,"annotations":{"destructiveHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["userKey"],"properties":{"userKey":{"type":"string","description":"The user's primary email or unique user ID."},"givenName":{"type":"string","description":"New first name."},"familyName":{"type":"string","description":"New last name."},"orgUnitPath":{"type":"string","description":"Move the user to this org unit path, e.g. '/Sales'."},"suspended":{"type":"boolean","description":"Set the user's suspended state."}}},"action":{"path":"/admin/directory/v1/users/{userKey}","method":"PATCH","mapping":{"params":"{ \"userKey\": arguments.userKey }","body":"{\n \"name\": ($exists(arguments.givenName) or $exists(arguments.familyName)) ? {\n \"givenName\": arguments.givenName,\n \"familyName\": arguments.familyName\n } : undefined,\n \"orgUnitPath\": arguments.orgUnitPath,\n \"suspended\": arguments.suspended\n }"}}},{"name":"Suspend User","description":"Suspend or un-suspend a user. Suspending immediately blocks the user from signing in without deleting the account.","slug":"suspend-user","enabled":true,"annotations":{"destructiveHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["userKey"],"properties":{"userKey":{"type":"string","description":"The user's primary email or unique user ID."},"suspended":{"type":"boolean","description":"True to suspend the user, false to restore access. Defaults to true.","default":true}}},"action":{"path":"/admin/directory/v1/users/{userKey}","method":"PATCH","mapping":{"params":"{ \"userKey\": arguments.userKey }","body":"{ \"suspended\": $exists(arguments.suspended) ? arguments.suspended : true }"}}},{"name":"Assign License","description":"Assign a Google Workspace product license to a user by product and SKU ID. Common productId is Google-Apps; SKU IDs vary by edition (e.g. Google-Apps-For-Business).","slug":"assign-license","enabled":true,"annotations":{"destructiveHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["productId","skuId","userId"],"properties":{"productId":{"type":"string","description":"Product ID, e.g. Google-Apps or Google-Vault."},"skuId":{"type":"string","description":"SKU ID for the license edition, e.g. Google-Apps-For-Business."},"userId":{"type":"string","description":"The user's primary email address."}},"additionalProperties":false},"action":{"path":"https://licensing.googleapis.com/apps/licensing/v1/product/{productId}/sku/{skuId}/user","method":"POST","mapping":{"params":"{\n \"productId\": arguments.productId,\n \"skuId\": arguments.skuId\n }","body":"{ \"userId\": arguments.userId }","response":"{\n \"userId\": response.userId,\n \"productId\": response.productId,\n \"skuId\": response.skuId,\n \"skuName\": response.skuName,\n \"productName\": response.productName\n }"}}},{"name":"Revoke License","description":"Revoke a Google Workspace product license from a user, freeing the seat for reassignment.","slug":"revoke-license","enabled":true,"annotations":{"destructiveHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["productId","skuId","userId"],"properties":{"productId":{"type":"string","description":"Product ID, e.g. Google-Apps or Google-Vault."},"skuId":{"type":"string","description":"SKU ID for the license edition to revoke."},"userId":{"type":"string","description":"The user's primary email address."}},"additionalProperties":false},"action":{"path":"https://licensing.googleapis.com/apps/licensing/v1/product/{productId}/sku/{skuId}/user/{userId}","method":"DELETE","mapping":{"params":"{\n \"productId\": arguments.productId,\n \"skuId\": arguments.skuId,\n \"userId\": arguments.userId\n }"}}},{"name":"List Groups","description":"List groups in the Google Workspace account. Optionally filter by domain, by a member's email, or by a search query.","slug":"list-groups","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","properties":{"customer":{"type":"string","description":"Customer ID. Use 'my_customer' (default) for the authenticated admin's account. Ignored when 'domain' or 'userKey' is provided.","default":"my_customer"},"domain":{"type":"string","description":"Restrict results to groups in this domain."},"userKey":{"type":"string","description":"If provided, list only groups that this user (email or ID) is a member of."},"query":{"type":"string","description":"Search query, e.g. \"email:sales*\" or \"name:Engineering\"."},"maxResults":{"type":"number","description":"Maximum number of results per page (1-200). Default 100.","default":100},"pageToken":{"type":"string","description":"Token to retrieve the next page of results."}}},"action":{"path":"/admin/directory/v1/groups","method":"GET","mapping":{"query":"{\n \"customer\": (arguments.domain or arguments.userKey) ? undefined : (arguments.customer ? arguments.customer : \"my_customer\"),\n \"domain\": arguments.domain,\n \"userKey\": arguments.userKey,\n \"query\": arguments.query,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 100,\n \"pageToken\": arguments.pageToken\n }"}}},{"name":"Get Group","description":"Retrieve a single group by its email address or unique ID.","slug":"get-group","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["groupKey"],"properties":{"groupKey":{"type":"string","description":"The group's email address or unique group ID."}}},"action":{"path":"/admin/directory/v1/groups/{groupKey}","method":"GET","mapping":{"params":"{ \"groupKey\": arguments.groupKey }"}}},{"name":"Create Group","description":"Create a new group with the given email address and name.","slug":"create-group","enabled":true,"annotations":{"destructiveHint":false},"inputSchema":{"type":"object","required":["email","name"],"properties":{"email":{"type":"string","description":"The group's email address, e.g. team@example.com."},"name":{"type":"string","description":"Display name of the group."},"description":{"type":"string","description":"Optional description of the group's purpose."}}},"action":{"path":"/admin/directory/v1/groups","method":"POST","mapping":{"body":"{\n \"email\": arguments.email,\n \"name\": arguments.name,\n \"description\": arguments.description\n }"}}},{"name":"List Group Members","description":"List the members of a group.","slug":"list-group-members","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["groupKey"],"properties":{"groupKey":{"type":"string","description":"The group's email address or unique group ID."},"roles":{"type":"string","description":"Comma-separated roles to filter by, e.g. 'OWNER,MANAGER,MEMBER'."},"maxResults":{"type":"number","description":"Maximum number of results per page (1-200). Default 100.","default":100},"pageToken":{"type":"string","description":"Token to retrieve the next page of results."}}},"action":{"path":"/admin/directory/v1/groups/{groupKey}/members","method":"GET","mapping":{"params":"{ \"groupKey\": arguments.groupKey }","query":"{\n \"roles\": arguments.roles,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 100,\n \"pageToken\": arguments.pageToken\n }"}}},{"name":"Add Group Member","description":"Add a user (or another group) as a member of a group.","slug":"add-group-member","enabled":true,"annotations":{"destructiveHint":false},"inputSchema":{"type":"object","required":["groupKey","email"],"properties":{"groupKey":{"type":"string","description":"The group's email address or unique group ID."},"email":{"type":"string","description":"Email address of the member to add."},"role":{"type":"string","enum":["MEMBER","MANAGER","OWNER"],"description":"Role for the new member. Defaults to MEMBER.","default":"MEMBER"}}},"action":{"path":"/admin/directory/v1/groups/{groupKey}/members","method":"POST","mapping":{"params":"{ \"groupKey\": arguments.groupKey }","body":"{\n \"email\": arguments.email,\n \"role\": arguments.role ? arguments.role : \"MEMBER\"\n }"}}},{"name":"Remove Group Member","description":"Remove a member from a group.","slug":"remove-group-member","enabled":true,"annotations":{"destructiveHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["groupKey","memberKey"],"properties":{"groupKey":{"type":"string","description":"The group's email address or unique group ID."},"memberKey":{"type":"string","description":"The member's email address or unique ID to remove from the group."}}},"action":{"path":"/admin/directory/v1/groups/{groupKey}/members/{memberKey}","method":"DELETE","mapping":{"params":"{ \"groupKey\": arguments.groupKey, \"memberKey\": arguments.memberKey }"}}},{"name":"List Org Units","description":"List the organizational units in the Google Workspace account.","slug":"list-org-units","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","properties":{"customerId":{"type":"string","description":"Customer ID. Use 'my_customer' (default) for the authenticated admin's account.","default":"my_customer"},"orgUnitPath":{"type":"string","description":"If provided, list org units under this path, e.g. '/Sales'."},"type":{"type":"string","enum":["all","children"],"description":"Whether to return all sub-org units or only immediate children. Default 'children'."}}},"action":{"path":"/admin/directory/v1/customer/{customerId}/orgunits","method":"GET","mapping":{"params":"{ \"customerId\": arguments.customerId ? arguments.customerId : \"my_customer\" }","query":"{\n \"orgUnitPath\": arguments.orgUnitPath,\n \"type\": arguments.type\n }"}}},{"name":"Get Org Unit","description":"Retrieve a single organizational unit by its path.","slug":"get-org-unit","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["orgUnitPath"],"properties":{"customerId":{"type":"string","description":"Customer ID. Use 'my_customer' (default) for the authenticated admin's account.","default":"my_customer"},"orgUnitPath":{"type":"string","description":"The full path of the org unit, without the leading slash, e.g. 'Sales/West'."}}},"action":{"path":"/admin/directory/v1/customer/{customerId}/orgunits/{orgUnitPath}","method":"GET","mapping":{"params":"{\n \"customerId\": arguments.customerId ? arguments.customerId : \"my_customer\",\n \"orgUnitPath\": arguments.orgUnitPath\n }"}}},{"name":"List ChromeOS Devices","description":"List ChromeOS devices enrolled in the Google Workspace account.","slug":"list-chromeos-devices","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","properties":{"customerId":{"type":"string","description":"Customer ID. Use 'my_customer' (default) for the authenticated admin's account.","default":"my_customer"},"query":{"type":"string","description":"Search query, e.g. \"status:ACTIVE\" or \"user:jane@example.com\"."},"orgUnitPath":{"type":"string","description":"Restrict results to devices in this org unit path."},"maxResults":{"type":"number","description":"Maximum number of results per page (1-300). Default 100.","default":100},"pageToken":{"type":"string","description":"Token to retrieve the next page of results."}}},"action":{"path":"/admin/directory/v1/customer/{customerId}/devices/chromeos","method":"GET","mapping":{"params":"{ \"customerId\": arguments.customerId ? arguments.customerId : \"my_customer\" }","query":"{\n \"query\": arguments.query,\n \"orgUnitPath\": arguments.orgUnitPath,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 100,\n \"pageToken\": arguments.pageToken\n }"}}},{"name":"List Mobile Devices","description":"List mobile devices (Android, iOS) enrolled in the Google Workspace account.","slug":"list-mobile-devices","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","properties":{"customerId":{"type":"string","description":"Customer ID. Use 'my_customer' (default) for the authenticated admin's account.","default":"my_customer"},"query":{"type":"string","description":"Search query, e.g. \"email:jane@example.com\" or \"type:ANDROID\"."},"maxResults":{"type":"number","description":"Maximum number of results per page (1-100). Default 100.","default":100},"pageToken":{"type":"string","description":"Token to retrieve the next page of results."}}},"action":{"path":"/admin/directory/v1/customer/{customerId}/devices/mobile","method":"GET","mapping":{"params":"{ \"customerId\": arguments.customerId ? arguments.customerId : \"my_customer\" }","query":"{\n \"query\": arguments.query,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 100,\n \"pageToken\": arguments.pageToken\n }"}}},{"name":"Action Mobile Device","description":"Take an administrative action on a mobile device, such as blocking it or wiping corporate data. Destructive actions cannot be undone.","slug":"action-mobile-device","enabled":true,"annotations":{"destructiveHint":true},"inputSchema":{"type":"object","required":["resourceId","action"],"properties":{"customerId":{"type":"string","description":"Customer ID. Use 'my_customer' (default) for the authenticated admin's account.","default":"my_customer"},"resourceId":{"type":"string","description":"The unique device resource ID (from List Mobile Devices)."},"action":{"type":"string","enum":["admin_account_wipe","admin_remote_wipe","approve","block","cancel_remote_wipe_then_activate","cancel_remote_wipe_then_block"],"description":"The action to perform. 'admin_account_wipe' removes only corporate data; 'admin_remote_wipe' factory-resets the device."}}},"action":{"path":"/admin/directory/v1/customer/{customerId}/devices/mobile/{resourceId}/action","method":"POST","mapping":{"params":"{\n \"customerId\": arguments.customerId ? arguments.customerId : \"my_customer\",\n \"resourceId\": arguments.resourceId\n }","body":"{ \"action\": arguments.action }"}}},{"name":"List Audit Activities","description":"Read audit activity events from the Reports API for a given application (e.g. login, admin, drive, token). Use to investigate admin changes, sign-ins, and other security-relevant events.","slug":"list-audit-activities","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["applicationName"],"properties":{"applicationName":{"type":"string","description":"The application to read events for, e.g. 'login', 'admin', 'drive', 'token', 'user_accounts', 'groups'."},"userKey":{"type":"string","description":"Filter by a specific user's email or ID, or 'all' for all users. Default 'all'.","default":"all"},"startTime":{"type":"string","description":"Only return events at or after this RFC 3339 timestamp, e.g. '2024-01-01T00:00:00Z'."},"endTime":{"type":"string","description":"Only return events at or before this RFC 3339 timestamp."},"eventName":{"type":"string","description":"Filter by a specific event name."},"filters":{"type":"string","description":"Event-parameter filters, e.g. \"doc_id==12345\" (see Reports API docs)."},"maxResults":{"type":"number","description":"Maximum number of events per page (1-1000). Default 100.","default":100},"pageToken":{"type":"string","description":"Token to retrieve the next page of results."}}},"action":{"path":"/admin/reports/v1/activity/users/{userKey}/applications/{applicationName}","method":"GET","mapping":{"params":"{\n \"userKey\": arguments.userKey ? arguments.userKey : \"all\",\n \"applicationName\": arguments.applicationName\n }","query":"{\n \"startTime\": arguments.startTime,\n \"endTime\": arguments.endTime,\n \"eventName\": arguments.eventName,\n \"filters\": arguments.filters,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 100,\n \"pageToken\": arguments.pageToken\n }"}}},{"name":"Get User Usage Report","description":"Retrieve usage parameters for a specific user (or all users) on a given date from the Reports API, e.g. last login time, storage used, and 2SV enrollment.","slug":"get-user-usage-report","enabled":true,"annotations":{"readOnlyHint":true,"idempotentHint":true},"inputSchema":{"type":"object","required":["date"],"properties":{"userKey":{"type":"string","description":"The user's email or ID, or 'all' for all users. Default 'all'.","default":"all"},"date":{"type":"string","description":"The date to report on in YYYY-MM-DD form. Usage data is typically available a few days in arrears."},"parameters":{"type":"string","description":"Comma-separated usage parameters to fetch, e.g. 'accounts:last_login_time,accounts:is_2sv_enrolled'."},"filters":{"type":"string","description":"Comma-separated parameter filters to narrow results (see Reports API docs)."},"maxResults":{"type":"number","description":"Maximum number of results per page. Default 100.","default":100},"pageToken":{"type":"string","description":"Token to retrieve the next page of results."}}},"action":{"path":"/admin/reports/v1/usage/users/{userKey}/dates/{date}","method":"GET","mapping":{"params":"{\n \"userKey\": arguments.userKey ? arguments.userKey : \"all\",\n \"date\": arguments.date\n }","query":"{\n \"parameters\": arguments.parameters,\n \"filters\": arguments.filters,\n \"maxResults\": arguments.maxResults ? arguments.maxResults : 100,\n \"pageToken\": arguments.pageToken\n }"}}}]}}