gwagent
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| GWAGENT_TZ | No | Time zone for calendar output and for times given without an offset | Europe/Rome |
| GWAGENT_ADB | No | adb binary; defaults to adb on PATH, then ~/android-ufficio-sdk/platform-tools/adb, then ~/Library/Android/sdk/platform-tools/adb | |
| GWAGENT_PIN | No | Screen-lock PIN (prefer the PIN file); never print or commit it | |
| GWAGENT_TRACE | No | Set to 1 to print every adb call and server command with its duration on stderr | |
| GWAGENT_SERIAL | No | adb serial of the phone to drive | emulator-5554 |
| GWAGENT_NO_LOCK | No | Set to 1 to disable the UI lock: unit tests only, never with a real phone | |
| GWAGENT_OUT_DIR | No | Where downloads, attachments and screenshots go on the host | ~/gwagent-downloads |
| GWAGENT_PIN_FILE | No | File holding the PIN (mode 600); never print or commit it | ~/.android-ufficio-pin |
| GWAGENT_BUILD_SDK | No | Android SDK used by dumpserver/build.sh | ~/.cache/gwagent-sdk |
| GWAGENT_FAST_DUMP | No | Set to 0 to disable the on-phone server (falls back to uiautomator dump / input) | 1 |
| GWAGENT_FAST_IDLE | No | Seconds after which an idle on-phone server exits | 45 |
| GWAGENT_KEEPALIVE | No | Keep the screen awake during long ops; set to 0 to disable | 1 |
| GWAGENT_LOCK_FILE | No | UI lock file | /tmp/gwagent-ui.lock |
| GWAGENT_STATE_DIR | No | Host state: last Gmail list, last Drive location, last Gmail action (for undo) | ~/.cache/gwagent |
| GWAGENT_CALENDAR_ID | No | Default calendar id for calendar.create; defaults to the primary calendar | |
| GWAGENT_RECOVER_CMD | No | Operator hook (shell command) run once when the phone stays unreachable for 90 s after adb reconnect attempts, e.g. a command that restarts the emulator; gets GWAGENT_SERIAL and a fresh GWAGENT_BOOT_TIMEOUT | |
| GWAGENT_SLEEP_AFTER | No | Set to 1 to turn the screen off after every UI op | |
| GWAGENT_AUTO_RECOVER | No | Wait for an offline phone and repeat retry-safe ops once; set to 0 to disable | 1 |
| GWAGENT_BOOT_TIMEOUT | No | Max seconds to wait for the phone to come back | 300 |
| GWAGENT_LOCK_TIMEOUT | No | Seconds to wait for the UI lock before failing with busy | 300 |
| GWAGENT_FAST_BUSY_TIMEOUT | No | Seconds of silence before the server is considered stuck and restarted | 25 |
| GWAGENT_FAST_START_TIMEOUT | No | Seconds to wait for the on-phone server to start | 30 |
| GWAGENT_RECOVER_CMD_TIMEOUT | No | Max seconds the GWAGENT_RECOVER_CMD hook may run | 120 |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| app_intentC | Start an activity with an arbitrary intent ( |
| app_launchB | Bring an app to the foreground. Returns the focused window (package, activity, window) plus |
| app_stopB | Force-stop an app. |
| calendar_add_meetA | Add a Google Meet video conference to one of your events (the provider cannot create one). Guests are not e-mailed about the change ("Don't send" is chosen if asked). Returns the Meet link once the provider has it. |
| calendar_attendee_addA | Invite people to an event (Google e-mails them). Returns the attendee list. Requires confirm=true (outward-facing or destructive). |
| calendar_attendee_removeA | Remove guests from an event (Google may e-mail them a cancellation). Returns what is left. Requires confirm=true (outward-facing or destructive). |
| calendar_calendarsA | List the calendars on the phone (id, name, account, colour, access level, visible, sync). Use the |
| calendar_createB | Create an event (synced to Google Calendar). Returns the new event (see calendar.get). |
| calendar_deleteA | Delete an event (the whole series for recurring events, or one occurrence). Synced to Google.
Requires confirm=true (outward-facing or destructive). |
| calendar_delete_specialA | Delete a working location, Out of office or Focus time entry of one day in the Calendar app. These entries are not in the calendar provider (calendar.delete cannot see them). For a working location only that day is removed (your weekly setting stays for other days; the day then has no working location). A multi-day Out of office is deleted as a whole. Requires confirm=true (outward-facing or destructive). |
| calendar_eventsA | List event occurrences in a time range (recurring events are expanded into instances). Range: |
| calendar_focus_timeA | Create a Focus time block in the Calendar app (colleagues see it; meetings can be auto-declined). Not in the calendar provider: read back from the app, removed with calendar.delete_special. Requires confirm=true (outward-facing or destructive). |
| calendar_free_busyA | Busy blocks (merged) and the free gaps between them in a time range. Counts events marked busy (and tentative, unless disabled), skipping canceled events and
events you declined. All-day events are ignored unless include_all_day. Every calendar
synced to the phone counts (hidden ones too, unless include_hidden=false); calendars with
sync off are listed in |
| calendar_getA | Get one event (whole series for recurring events) with attendees and reminders. |
| calendar_meet_linkB | The Google Meet link of an event, if it has one (provider only, no UI). |
| calendar_nextB | The next upcoming (or currently running) event occurrences, soonest first. |
| calendar_openA | Show a date in the Calendar app (optionally switching view) and read what is visible. Returns the view, the toolbar title and the visible items (or, in month view, the number of items of each day). Use calendar.view_screen to read whole days in detail. |
| calendar_open_eventA | Open an event in the Calendar app by provider id and read its screen. Returns what the app shows: when, recurrence, Google Meet link and dial-in, location, notifications, calendar, guests with their answers, notes and your RSVP state (rsvp.available, rsvp.response = yes/no/maybe/null). The event must be synced with Google. |
| calendar_out_of_officeA | Create an Out of office block in the Calendar app (colleagues see it; meetings can be auto-declined). Google shows it to people who look at your calendar and, with auto_decline, declines new
meeting invitations in that time, sending Requires confirm=true (outward-facing or destructive). |
| calendar_reminder_addB | Add a reminder to an event. Returns the event's reminders. |
| calendar_reminder_removeA | Remove reminders from an event (by minutes, by reminder_id, or all). Returns what is left. |
| calendar_remove_meetA | Remove the Google Meet conference from one of your events (the link stops working). Requires confirm=true (outward-facing or destructive). |
| calendar_respondA | Answer an invitation: set your own attendee status (the organizer is notified by Google). Requires confirm=true (outward-facing or destructive). |
| calendar_rsvpA | Answer an invitation with the Calendar app's Yes / No / Maybe buttons (organizer is notified). Unlike calendar.respond (provider), this goes through Google's servers at once and can answer a single occurrence of a recurring event (scope 'this'). The result is checked on the provider after the app syncs. Read the current answer first with calendar.open_event. Requires confirm=true (outward-facing or destructive). |
| calendar_searchA | Search events (series, not occurrences) by text in title, description or location. Searches all calendars, including hidden ones, newest first. For recurring events the
start/end are those of the first occurrence; use calendar.events with |
| calendar_set_calendarA | Show/hide a calendar in the Calendar app, or turn its sync to the phone on/off. Hidden calendars are still synced (calendar.events includes them). A calendar with sync off has no events on the phone; turning sync on downloads them (run calendar.sync_background). These are phone settings of your calendar list, not changes to the events. |
| calendar_set_working_locationA | Set your working location (Home, Office or any place) for one day or a range of days. Colleagues see it in Calendar/Gmail/Chat. It applies to these days only (your weekly working-location settings stay); to undo, set the previous place again or use calendar.delete_special (the day then has no working location). Read with calendar.working_location. Requires confirm=true (outward-facing or destructive). |
| calendar_syncA | Force a Calendar sync with Google and wait for it to finish. New server events then show in the provider (calendar.events) and local changes are uploaded. method auto (default): Android's sync manager first (fast, no screen), the app's Refresh if no sync started; background: sync manager only (same as calendar.sync_background); ui: the app's Refresh (drawer). The sync start is verified on Android's sync manager. |
| calendar_sync_backgroundA | Sync the calendar with Google without the screen (Android sync manager, Pushes local changes (create/update/delete/respond) and pulls server changes; works with the phone locked and the screen off. calendar.sync does the same and falls back to the app. |
| calendar_task_completeA | Mark a Google Task as completed (or not completed again with undo=true). |
| calendar_task_createC | Create a Google Task (shown in Calendar on its date). |
| calendar_task_deleteA | Delete a Google Task. Requires confirm=true (outward-facing or destructive). |
| calendar_task_list_createB | Create a new Google Tasks list (it becomes the list shown). |
| calendar_task_list_deleteA | Delete a Google Tasks list and all its tasks (the default list cannot be deleted). Requires confirm=true (outward-facing or destructive). |
| calendar_task_listsC | The Google Tasks lists (names usable as Args: |
| calendar_task_updateA | Edit a Google Task: rename, change/remove its date and time, notes, subtasks, star, list. Returns the task as it is now (title, list, notes, due, subtasks, starred) plus
|
| calendar_tasksA | List Google Tasks of one list as shown in the Calendar app (tasks are not in the provider). Each task: title, due (as shown, e.g. 'Tomorrow, 9:15 AM'), completed, starred, notes, subtask (true for a subtask, listed right after its parent). Tasks are addressed by title (+ occurrence when several share it) in the other task ops. |
| calendar_updateA | Change fields of an event (whole series for recurring events, or one occurrence). Omitted fields are kept. Changing only Guests: changing title, time, location, description or recurrence of an event you organise that has guests makes Google e-mail them the update, so it needs confirm=true. Invitations from someone else cannot be changed (only your availability/colour, and reminders with calendar.reminder_*): answer them with calendar.respond / calendar.rsvp. Avoid rapid successive edits of the same event: an edit made while the sync adapter is
uploading the previous one can be overwritten by the server copy (check |
| calendar_view_screenA | Read what the Calendar app shows for one or more days, as structured rows (schedule view). Shows things the provider lacks: working locations, tasks, the RSVP shown for each event. Rows: kind (event / working_location / task / out_of_office / focus_time), title, all_day, time, start, end (HH:MM), response (Not responded / No / Maybe..., absent when you accepted or organise it), location, calendar (absent for your own calendar), color, and event_id/instance_id matched from the provider (use them with calendar.open_event / calendar.rsvp). If the provider has events the app does not show yet, the app is refreshed and read again; those still missing are listed in not_shown_event_ids. |
| calendar_working_locationB | Your working location (Office, Home, ...) for each day, as shown by the Calendar app. Working locations are not in the provider. Days without one are reported with place null. |
| device_accountsB | Accounts registered on the phone (name and type). |
| device_install_adb_keyboardA | Install ADBKeyboard (not needed: the on-phone server types any Unicode; the office phone forbids APK installs). Requires confirm=true (outward-facing or destructive). |
| device_lsB | List files in a phone directory. |
| device_pullA | Copy a file from the phone to this computer (default: the gwagent downloads dir). |
| device_pushB | Copy a file from this computer to the phone (default: the phone's Download folder). |
| device_rmA | Delete a file from the phone's shared storage (/sdcard only). Requires confirm=true (outward-facing or destructive). |
| device_shellA | Run a raw |
| device_sleepA | Turn the screen off (re-locks the phone). Use when done, to save CPU on the host. |
| device_statusB | Phone status: adb state, Android version, screen on/locked, foreground app, app versions. |
| device_unlockA | Wake the screen and unlock it with the configured PIN (every UI op does this automatically). |
| drive_cdA | Enter a folder: by path relative to the current location ("A/B/C", ".." = parent, leading "/" = from My Drive) or by index from the last list. Returns the folder's items. |
| drive_copyC | Make a copy of a file ("Make a copy"); the copy is named "Copy of ". Drive is left in the destination folder, where the copy is checked. |
| drive_create_docA | Create a new Google Docs/Sheets/Slides file (Create new > Google Docs...). Drive hands the creation to the Docs/Sheets/Slides app: when that app is not installed
(as on this phone) Drive opens the Play Store instead and this op fails with
|
| drive_delete_foreverA | Permanently delete an item that is in the Trash (cannot be undone). Requires confirm=true (outward-facing or destructive). |
| drive_downloadA | Download a file with Drive's "Download" (Google Docs/Sheets/Slides are exported by the app, e.g. a Google Doc as PDF) into the phone's Download folder, then copy it to this computer. |
| drive_empty_trashA | Permanently delete everything in the Trash ("Empty trash"; cannot be undone). Give only_if_all_match or all=true (invalid_argument otherwise, nothing touched): the Trash can hold items the user trashed by hand, so emptying it unconditionally must be explicit. Requires confirm=true (outward-facing or destructive). |
| drive_infoA | Details and activity of an item ('View information'): type, size, location, created, modified (by whom), sharing summary, recent activity. |
| drive_listA | List the items of the current Drive location (folder, section or search results). Scrolls and de-duplicates; switches grid view to list view (richer info). Indexes are usable by drive.cd / drive.info / drive.download / drive.read_text. |
| drive_locationB | Where Drive is now: screen kind, title, sort order, view mode and remembered folder path. |
| drive_menuA | List the actions Drive offers for an item (its 'More actions' menu), without running any. |
| drive_mkdirB | Create a new folder in the current location (or in |
| drive_moveB | Move a file or folder to another folder of My Drive. |
| drive_offlineB | Make a file available offline on the phone (enable=true) or remove offline access. |
| drive_openC | Open a Drive section and list its first items. |
| drive_read_textA | Read the text of a file (PDF pages, document, slides, sheets, plain text). 'download' downloads/exports the file and extracts its text on this computer (nothing is left on the phone); 'viewer' opens it in Drive's viewer and reads the text it exposes; 'auto' tries download, then the viewer. |
| drive_refreshA | Pull-to-refresh the current Drive list (re-sync from the server) and list it again. |
| drive_renameC | Rename a file or folder. |
| drive_restoreA | Restore an item from the Trash to its original folder. |
| drive_searchB | Search Drive (file names and content) and return the matching items, optionally filtered by type, owner and modification date. |
| drive_set_roleA | Change the role of a person who already has access to a file or folder (Manage access). Requires confirm=true (outward-facing or destructive). |
| drive_shareB | Share a file or folder with people (Share > add people, role, notify, Send). Requires confirm=true (outward-facing or destructive). |
| drive_share_linkA | Get an item's link and optionally change its General access (who can open the link). The General access choices are set by the organisation (on this account: "Restricted" and
an organisation-defined scope); an unknown Requires confirm=true (outward-facing or destructive). |
| drive_sharingA | Read an item's sharing (changes nothing): people with access (name, email, role), general access ('Restricted'...) and the item's link and file id. |
| drive_sortA | Change the sort order of the current list (Drive remembers it per view). |
| drive_starC | Add a file or folder to Starred. |
| drive_storageB | Drive storage used, and optionally the files using the most storage. |
| drive_trashA | Move a file or folder to the Trash (restorable with drive.restore for 30 days). Requires confirm=true (outward-facing or destructive). |
| drive_unshareA | Remove people's access to a file or folder (Manage access > person > Remove). Every address must currently have access (else not_found and nothing is changed); the owner cannot be removed. Requires confirm=true (outward-facing or destructive). |
| drive_unstarB | Remove a file or folder from Starred. |
| drive_upB | Go to the parent folder (or leave a section/search back to the main screen). |
| drive_uploadA | Upload a file from this computer into a Drive folder (Create new > Upload). The file is copied to the phone, picked in the system file picker, uploaded under
|
| drive_upload_filesB | Upload several files from this computer into one Drive folder (one after the other). |
| drive_upload_folderA | Upload a folder from this computer: creates a Drive folder and uploads its files and sub-folders into it (recursively; hidden files are skipped). |
| drive_viewA | Switch the current Drive list between list and grid view. |
| gmail_archiveB | Archive conversations (remove them from the Inbox; they stay in All mail). |
| gmail_attachmentsC | List the attachments of a conversation (name, type, size, message index). |
| gmail_backA | Close the open conversation (or dialog/full view) and return to the mail list. |
| gmail_block_senderA | Block the sender of a message: their future mail goes to Spam (message menu > Block "sender"). Gmail blocks at once (no dialog); gmail.unblock_sender reverts it. Not offered for your own messages. Requires confirm=true (outward-facing or destructive). |
| gmail_cancel_scheduledA | Cancel a scheduled send: the message is not sent and becomes a draft again (see gmail.drafts). |
| gmail_compose_stateA | Describe the compose window currently open (mode, recipients, subject, body, attachments). |
| gmail_create_labelB | Create a new Gmail label (drawer -> Create label). |
| gmail_delete_draftA | Delete (discard) a draft: index from gmail.drafts, optionally with the same query. Requires confirm=true (outward-facing or destructive). |
| gmail_delete_foreverA | Permanently delete conversations that are in the Trash or Spam (cannot be undone). Only conversations listed in the Trash or Spam folder (default: Trash), or in a search restricted to them ('in:trash ...' / 'in:spam ...'), can be targeted. Some Gmail builds (e.g. Workspace accounts) offer no per-conversation 'Delete forever'; the op then fails with not_found and gmail.empty is the only way to purge. Requires confirm=true (outward-facing or destructive). |
| gmail_delete_labelA | Delete a user label (Gmail settings -> Manage labels). Conversations keep existing without it. Requires confirm=true (outward-facing or destructive). |
| gmail_discardA | Close the compose window currently open WITHOUT sending it (its text is thrown away). Requires confirm=true (outward-facing or destructive). |
| gmail_download_attachmentA | Download attachment(s) of a conversation to the phone's Download folder and copy them to this computer. Choose the attachment with |
| gmail_draftA | Create a new draft (not sent): recipients, subject, Unicode body, attachments. |
| gmail_draftsB | List drafts (Drafts folder, or drafts matching a Gmail query). Indexes feed gmail.send_draft. |
| gmail_edit_draftA | Change an existing draft (recipients, subject, body, attachments) and save it again. The draft keeps its thread (reply drafts stay replies). Fields left out are unchanged. With append=false (default) given recipients REPLACE the field and body replaces the whole editable body; with append=true recipients are added and body is added at the end. |
| gmail_emptyA | Empty the Trash or the Spam folder: EVERY conversation in it is permanently deleted. Returns how many conversations Gmail said it would delete ('count'). Requires confirm=true (outward-facing or destructive). |
| gmail_foldersA | List Gmail folders (inbox categories, system folders) and user labels with unread counts. Counts are what the drawer shows: unread conversations for most folders, the total for Drafts/Outbox/Scheduled, and 'N new' for inbox categories. |
| gmail_forwardA | Forward the last message of a conversation, or message_index (with its attachments), to new recipients. Send is never repeated blind: when Gmail's reaction to Send is unclear the mail is looked up in Outbox / Sent; if that cannot tell, the op fails with error 'send_state_unknown' and nothing is re-sent (check gmail.list folder='sent' before any retry). A result may carry verified_in='outbox' | 'sent' when the send was confirmed that way. Requires confirm=true (outward-facing or destructive). |
| gmail_geminiA | Ask Gemini in Gmail and return its answer text. Without index/query/folder Gemini is asked from the mail list (questions about the mailbox, e.g. 'unread mail from Alice this week'); with them the conversation is opened first and the question is about that conversation. Raises gemini_unavailable when the account has no Gemini in Gmail. |
| gmail_importantC | Mark conversations as important. |
| gmail_labelB | Apply and/or remove labels on conversations ('Label as' dialog; 'Inbox' is a label too). The result lists the labels offered by the dialog ('labels'). |
| gmail_labelsA | List the user labels (and system folders) available to gmail.label / gmail.move. |
| gmail_listA | List conversations of the current list (folder, label or search results) or of a given folder. Rows have an 'index' (0 = top of the list) usable with gmail.read / gmail.reply / gmail.archive ... The list and its rows are remembered: a follow-up op given only an index re-opens this list if the phone shows another one, and refuses (not_found) when the row at that index is no longer the same conversation (it is looked up nearby if it just moved). |
| gmail_mark_readB | Mark conversations as read (changed=false if they already were). |
| gmail_mark_unreadB | Mark conversations as unread (an open conversation is closed, as in the app). |
| gmail_message_actionsA | List the actions a message's own menu offers (Reply all, Forward, Block "x", Report spam ...). Read-only: tells whether gmail.block_sender / gmail.unblock_sender / gmail.unsubscribe / gmail.report_phishing apply to this message. |
| gmail_moveA | Move conversations to another folder: an inbox category (Primary, Promotions...), a label, or the Inbox. 'Move to' is offered on folder lists (and, as 'Move to Inbox', for trashed/archived search results); it is not available on ordinary search results - use gmail.label there. |
| gmail_muteA | Mute conversations: they are archived and later replies skip the Inbox (find them with 'is:muted'). |
| gmail_not_importantC | Mark conversations as not important. |
| gmail_not_spamB | Report conversations as not spam: they go back to the Inbox (default list: the Spam folder). |
| gmail_openB | Open Gmail on a folder or label (Inbox, Starred, Sent, Drafts, All mail, Spam, Trash, a user label...). |
| gmail_readA | Read a whole conversation: subject, labels, and every message (from, to, cc, date, full body, attachments). Opens row |
| gmail_refreshA | Sync mail now: pull-to-refresh on the current list (goes to the list first). |
| gmail_rename_labelA | Rename a user label (Gmail settings -> Manage labels -> label -> Name). Conversations keep it. |
| gmail_replyA | Reply to the sender of the last message of a conversation (or of message_index). Send is never repeated blind: when Gmail's reaction to Send is unclear the mail is looked up in Outbox / Sent; if that cannot tell, the op fails with error 'send_state_unknown' and nothing is re-sent (check gmail.list folder='sent' before any retry). A result may carry verified_in='outbox' | 'sent' when the send was confirmed that way. Requires confirm=true (outward-facing or destructive). |
| gmail_reply_allA | Reply to everyone on the last message of a conversation (or of message_index). Send is never repeated blind: when Gmail's reaction to Send is unclear the mail is looked up in Outbox / Sent; if that cannot tell, the op fails with error 'send_state_unknown' and nothing is re-sent (check gmail.list folder='sent' before any retry). A result may carry verified_in='outbox' | 'sent' when the send was confirmed that way. Requires confirm=true (outward-facing or destructive). |
| gmail_report_phishingA | Report a message as phishing to Google (irreversible), when Gmail offers it for that message. Not every message has the entry: the op then fails with not_found and lists the actions the message menu offers (see gmail.message_actions); use gmail.spam to report spam instead. Requires confirm=true (outward-facing or destructive). |
| gmail_restoreA | Bring conversations back to the Inbox from the Trash, Spam or the archive (All mail / search). Uses 'Move to Inbox' / 'Move to' -> Inbox when offered, else adds the Inbox label. |
| gmail_save_attachment_to_driveA | Save an attachment of a conversation into Google Drive (the tile's 'Save to Drive'). Choose the attachment with |
| gmail_scheduledA | List mail scheduled to be sent later (the 'Scheduled' folder). Indexes feed gmail.cancel_scheduled. |
| gmail_scrollA | Scroll the current Gmail list or open conversation; 'top' returns to the top of the list. On a list, the rows now visible are returned with their absolute 'index' (usable by gmail.read / gmail.reply / gmail.archive...) when the list is the one last returned by gmail.list / gmail.search / gmail.scroll; 'indexed' tells whether they could be numbered (direction=top always can). On an open conversation the visible messages are returned. |
| gmail_searchA | Search mail with Gmail query syntax and return the result rows. Examples: 'from:alice has:attachment', 'is:unread label:work', 'subject:report after:2026/01/01'. The results stay on screen: gmail.read / gmail.list without arguments work on them. |
| gmail_sendA | Send a new e-mail (any Unicode text) with optional Cc, Bcc, attachments, From alias, or schedule it. The account's signature is added after the body by Gmail (signature=false removes it). Recipients are verified on the compose screen before sending; on any mismatch nothing is sent. Scheduled mail waits in the 'Scheduled' folder (gmail.scheduled, gmail.cancel_scheduled). Send is never repeated blind: when Gmail's reaction to Send is unclear the mail is looked up in Outbox / Sent; if that cannot tell, the op fails with error 'send_state_unknown' and nothing is re-sent (check gmail.list folder='sent' before any retry). A result may carry verified_in='outbox' | 'sent' when the send was confirmed that way; a scheduled send counts only once Gmail confirms it or it is found in 'Scheduled' (verified_in='scheduled'). Gmail offers 'Undo' for about 7 s after 'Sent' (undo_available tells whether it was still on screen when the op returned; gmail.undo uses it). undo=true taps that Undo within this op, the moment Gmail shows it: the result then has undone='send' and saved_as_draft=true only when the mail came back as a draft and is not in Outbox / Sent; undone=false (with undo_error) means it was sent anyway. Requires confirm=true (outward-facing or destructive). |
| gmail_send_draftA | Send an existing draft (index from gmail.drafts, optionally with the same query). Send is never repeated blind: when Gmail's reaction to Send is unclear the mail is looked up in Outbox / Sent; if that cannot tell, the op fails with error 'send_state_unknown' and nothing is re-sent (check gmail.list folder='sent' before any retry). A result may carry verified_in='outbox' | 'sent' when the send was confirmed that way; a scheduled send counts only once Gmail confirms it or it is found in 'Scheduled' (verified_in='scheduled'). Requires confirm=true (outward-facing or destructive). |
| gmail_set_signatureA | Set the mobile signature added to mail sent from the phone ('' removes it). |
| gmail_set_vacationA | Turn the vacation responder (out-of-office auto-reply) on or off and set its dates and text. While on, Gmail answers incoming mail automatically (outward-facing: needs confirm). Fields left out keep their current value. The result is the state read back from the screen. Requires confirm=true (outward-facing or destructive). |
| gmail_signatureB | Read the mobile signature Gmail adds to mail sent from the phone ('' = none: the web signature is used). |
| gmail_snoozeA | Snooze conversations until a preset moment or a chosen date and time (gmail.unsnooze reverts). Gmail offers only the presets that make sense now (e.g. no 'later_today' in the evening); an unavailable preset fails with not_found listing the available ones. |
| gmail_spamA | Report conversations as spam (moved to Spam; the report is sent to Google). Requires confirm=true (outward-facing or destructive). |
| gmail_starC | Star conversations. |
| gmail_summarizeB | Summarize a conversation with Gemini in Gmail ('Summarize this email'). Raises gemini_unavailable when the account has no Gemini in Gmail. |
| gmail_trashA | Delete conversations (move them to the Trash; gmail.restore or gmail.undo bring them back). Requires confirm=true (outward-facing or destructive). |
| gmail_unblock_senderB | Unblock the sender of a message (banner 'Unblock sender' or message menu > Unblock). A sender that is not blocked is left alone (was_blocked=false). |
| gmail_undoA | Undo the last Gmail action: tap 'Undo' on its snackbar if still shown, else revert it. After gmail.send / reply / forward / send_draft it recalls the mail while Gmail still shows 'Undo' (about 7 s after 'Sent'; the send result's undo_available says whether it still did): undone='send' only when the message is back in Drafts and not in Outbox / Sent. Later it fails (not_found, the mail was sent). To be sure to recall a send, use gmail.send undo=true. Reverting runs the opposite action on the same conversations (found again by subject): archive/trash/spam -> back to the Inbox, star <-> unstar, read <-> unread, label add <-> remove, mute -> unmute, snooze -> unsnooze, move -> move back (when it was done from a folder list). |
| gmail_unmuteA | Unmute conversations (e.g. query='is:muted'); they stay archived (use gmail.restore for the Inbox). |
| gmail_unread_countB | Number of unread conversations in a folder or label, as shown in the Gmail drawer. |
| gmail_unsnoozeA | Unsnooze conversations: they return to the Inbox now (default list: the Snoozed folder). |
| gmail_unstarC | Remove the star from conversations. |
| gmail_unsubscribeA | Unsubscribe from a mailing list / newsletter with Gmail's own Unsubscribe (outward, irreversible). Gmail offers it only for messages with a recognised unsubscribe header; otherwise the op fails with not_found and lists the available actions. Requires confirm=true (outward-facing or destructive). |
| gmail_vacationA | Read the vacation responder (out-of-office auto-reply): on/off, first/last day, subject, message. |
| meta_list_opsA | List every available operation with its parameters (JSON schema). |
| ui_double_tapA | Double-tap by coordinates or on the first element matching a selector (e.g. zoom in an image or PDF preview). Without the on-phone server a slow phone may see two single taps. |
| ui_dumpB | Describe the current screen: foreground app and visible elements (text, desc, id, bounds, flags). |
| ui_findC | Find elements on screen matching a selector (optionally wait up to timeout seconds). |
| ui_global_actionA | Perform a system action like the navigation buttons or the status bar do. lock_screen turns the screen off and locks the phone (the next UI op unlocks it); take_screenshot saves an image in the phone's gallery (prefer ui.screenshot); power_dialog needs the on-phone server. |
| ui_keyA | Press a key: BACK, HOME, ENTER, APP_SWITCH, DEL, TAB, DPAD_DOWN, MENU, SEARCH, or any KEYCODE_*. |
| ui_screenshotB | Save a PNG screenshot of the phone screen on this computer (look at it to see the UI). |
| ui_scrollA | Scroll the main content ('down' shows what is below, 'up' goes back toward the top). |
| ui_swipeC | Raw swipe gesture between two points. |
| ui_tapB | Tap by coordinates, or tap the first element matching a selector (waits for it). |
| ui_typeB | Type text into the focused field. |
| ui_waitB | Wait until an element appears (or disappears with gone=true). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 156 tools
Tools are grouped by domain and mostly distinct, but many near-neighbors require close reading, such as calendar_respond vs calendar_rsvp, calendar_sync vs calendar_sync_background, gmail_move vs gmail_label, and gmail_delete_forever vs gmail_empty. Descriptions clarify most boundaries, but the large surface creates real misselection risk.
All names use snake_case with a clear domain prefix (calendar_, drive_, gmail_, ui_, device_, app_), giving predictable grouping. The pattern is not strictly verb_noun throughout—several names are noun/state-oriented such as drive_location, gmail_compose_state, and calendar_calendars—but consistency is mostly maintained.
At 156 tools, this is far beyond the well-scoped 3-15 range and exceeds the 50-tool threshold for extreme mismatch. Even though the server spans multiple app domains, the surface is too large to navigate efficiently as a coherent tool set.
Coverage across Gmail, Calendar, Drive, UI automation, and device control is extensive, including CRUD, sharing, labels, drafts, sync, tasks, and escape hatches. No obvious dead ends are apparent; unsupported edge cases can generally be reached through device_shell.