DaySurface

Tools

The 34 Gmail, PDF, and webhook tools your assistant gets once connected

Once connected, your assistant has 34 tools, all backed by the official Gmail API. Tools marked UI render an interactive MCP App in clients that support it (an inbox dashboard, a draft composer, a signing surface) and fall back to plain structured output everywhere else.

Every tool takes a user_id that the server injects from the authenticated principal - clients never pass it.

Connection

ToolDescription
gmail_connectBegin the Google OAuth flow. Returns a sign-in URL and a state token.
gmail_statusWhether an account is linked, plus its address, scopes, and grant time.
gmail_disconnectRevoke and erase the linked account's stored tokens.

Inbox & threads

ToolDescription
gmail_curate_inbox UIRank recent inbox threads by a deterministic score and render the inbox dashboard.
gmail_list_inboxList recent inbox messages, optionally filtered by a Gmail search query.
gmail_get_thread UIFetch a thread with full message bodies.
gmail_get_attachmentFetch the raw base64 bytes of one attachment or inline image.
gmail_mark_thread_readRemove the UNREAD label from a thread.
gmail_archive_threadRemove INBOX from a thread and mark it dismissed in the curation ledger.
gmail_mark_thread_doneApply the MCP/Done label so the thread drops out of the curated inbox.
gmail_unmark_thread_doneUndo mark-done by removing the MCP/Done label.

Triage ledger

Banked triage judgments, so the same thread is not re-reasoned every morning.

ToolDescription
inbox_get_curation UIRead banked triage verdicts plus coverage. Cheap - fetches no bodies, runs no reasoning.
inbox_searchSearch recent threads headlessly (no UI) for a thorough triage pass.
inbox_save_curationBank triage judgments for one or more threads into the ledger.

Drafts & sending

ToolDescription
gmail_compose UICreate a new draft and open the interactive composer.
gmail_reply_to_thread UICreate a reply draft on an existing thread.
gmail_update_draft UIPatch fields on a draft. Omitted fields are preserved; null clears them.
gmail_get_draftFetch a single draft by id.
gmail_list_draftsList the account's drafts.
gmail_discard_draftDelete a draft by id.
gmail_sendSend a previously composed draft.
gmail_add_attachmentAttach one file to an existing draft, leaving body and recipients untouched.
gmail_remove_attachmentRemove one file from a draft by its attachment_id.

Drafts are written, not sent. gmail_send only ever sends a draft that already exists, so the user reviews the text in the composer before anything leaves the account.

PDF forms & signing

See PDF Forms for the full workflow.

ToolDescription
pdf_openOpen a PDF into a server-side editing session and return its fields, a doc_id, and page images.
pdf_editApply a batch of edits to an open session (fill fields, place text, and so on).
pdf_request_signature UILock the document and hand it to the user to sign.
pdf_exportDeliver the finished document - v1 attaches it to an existing Gmail draft.

The signature itself is a step only the user can complete by typing their own name in the signing UI. The assistant fills fields; it cannot sign on the user's behalf.

Push notifications & settings

See Gmail Webhooks for the event payloads and signature scheme.

ToolDescription
webhook_settings UIOpen settings: Gmail connection status and webhook subscriptions.
webhook_subscribeRegister an HTTPS endpoint to receive signed webhook events.
webhook_listList the caller's subscriptions. Secrets are never returned.
webhook_rotate_secretIssue a new signing secret, invalidating the old one.
webhook_unsubscribeDeactivate a subscription so it stops receiving events.
gmail_watch_startSubscribe the account's inbox to Gmail push notifications.
gmail_watch_stopCancel the account's push-notification watch.

Parameters for the common tools

The rest of the surface is discoverable from each tool's schema - your client reads it over MCP. These are the ones worth knowing by hand.

gmail_curate_inbox

ParameterTypeDefaultDescription
querystring(none)Gmail search query to narrow the set
limitinteger10Threads to rank (1-100)

Ranking is a deterministic heuristic score, not a model - no LLM inference runs over your mail. For a considered triage, prefer inbox_get_curation (banked verdicts) and go deeper with inbox_search + inbox_save_curation when coverage shows uncurated or stale threads.

gmail_list_inbox

ParameterTypeDefaultDescription
querystring(none)Gmail search query, e.g. from:[email protected] is:unread
limitinteger25Messages to return (1-500)

gmail_get_thread

ParameterTypeDefaultDescription
thread_idstring(required)Thread to fetch
include_attachment_databooleanfalseInline raw attachment bytes. Off by default to keep payloads small
strip_quoted_repliesbooleanfalseDrop quoted history from each reply, keeping only new text

gmail_compose

ParameterTypeDefaultDescription
tostring(required)Comma-separated recipients
subjectstring(required)Subject line
bodystring(required)Message body
cc / bccstring(none)Comma-separated address lists
in_reply_to_thread_idstring(none)Thread to attach the draft to
attachmentsarray[]Files as { filename, mime_type, data_base64 }

Returns the draft's saved state - draft_id, thread_id, recipients, subject, a body preview, and the attachment list - so there is no follow-up gmail_get_draft needed to confirm what was written.

gmail_reply_to_thread

ParameterTypeDefaultDescription
thread_idstring(required)Thread to reply on
bodystring(placeholder)Reply text; the composer can fill it on the next turn
subjectstringRe: <original>Derived from the thread's last message
tostring(derived)Defaults to the other party in the thread, never the account owner
cc / bccstring(none)Used verbatim when supplied; no de-duplication against thread participants
attachmentsarray[]Same shape as gmail_compose

gmail_send

ParameterTypeDescription
draft_idstringThe draft to send

Error handling

A failed tool call returns an error the assistant can act on rather than a crash:

{ "error": "Gmail account not connected. Call gmail_connect first." }

Keeping this list honest

The tool surface has one source of truth: the @service registry in the Python package. make gen_tool_surface snapshots it to landing-page/src/config/tool-surface.generated.json, which is what the landing page and the pre-connect server card advertise. When you add or rename a service, regenerate that snapshot and update the tables above in the same change.

On this page