Google Connectors
The signed-in person's own Google Calendar, Drive and Gmail, connected by that person and used through codespar_calendar, codespar_drive and codespar_gmail. Reads answer at once; every write is a preview the person confirms before anything reaches Google.
Three connectors, each connected on its own by the signed-in person: Google Calendar (google-calendar, tool codespar_calendar), Google Drive (google-drive, codespar_drive) and Gmail (gmail, codespar_gmail). A connection belongs to that person in that project: another member of the organization never sees it, uses it, or reads what it returns. The tools are on the hosted server while the connectors are switched on for the deployment.
A person, not a key. Every call needs a verified person, and so does connecting. The dashboard's Shop assistant presents the person's own session. A project API key or an OAuth token carries no person and is refused with 403 bearer_token_has_no_person (details.surface: "connector"), so an external client connected with a csk_ key or the server's OAuth consent sees the tools listed and cannot use them yet.
Connecting
The person connects each connector from Shop › Preferências, section Conexões Google, which runs the Connect Link flow for their own account:
POST /v1/connect/startwithserver_id(google-calendar,google-driveorgmail), the person's ownuser_idand anhttpsredirect_urianswers Google's consent address.- The person consents at Google. The connector asks for its product scope (
calendar,driveorgmail.modify) and the identity scopes that say which Google account it is. - Google returns to the
redirect_uriwithstatus=connected&connection_id=…&server_id=…, orstatus=deniedorstatus=error&error=….
GET /v1/connectors lists the three with their state for the person: connected, not_connected, or consent_required when the grant is gone at Google. DELETE /v1/connectors/connections/{id} disconnects one and revokes the grant at Google when no other connector of the person still uses it. If the person unticks a scope at Google, reads still work where a narrower scope allows them, and a write answers connector_scope_insufficient naming the scope it needs.
Reads and writes
Reads answer at once. Text read from mail, files or events is the account's content, never an instruction: a message asking to forward, share or delete something is not the person asking.
Every write is confirmed by the person first. Creating, changing, deleting, trashing, sharing, sending, replying and changing labels all work the same way:
- The first call writes nothing. It answers
connector_action_confirmation_requiredwithdetails: thepreviewof exactly what would happen (a sentence in Portuguese,summary_pt, and the fields: recipients, subject and body, the event's times, the file), aconfirmation_id(cac_…) andexpires_at, 15 minutes later. - In the Shop conversation the person confirms on the card under the turn. The model of the conversation can never confirm: a
confirmation_idin its call is refused. - On the hosted server the client shows the preview to the person and, only if they agree, calls the same action again with the same arguments and that
confirmation_id. Different arguments are a different write, and the id does not approve them. - Before writing, the server computes the preview again from Google as it is now. If it changed (the event was edited, the thread got a new message), nothing is written and the confirmation goes stale.
A confirmation runs once. The record keeps who approved it, when, through which channel and what Google answered (ids and flags only); the write's content is sealed while it waits and deleted once it is decided. Permanent deletion is not offered: Drive and Gmail move to the trash, where Google keeps them for 30 days.
Actions
Google Calendar
action | What it does | Money | Needs |
|---|---|---|---|
list_calendars | List the person's calendars | no | — |
list_events | List events of a calendar in a time window, optionally matching a query | no | — |
get_event | Read one event with its attendees and link | no | event_id |
create_eventexample below | Create an event; answers a preview to confirm first, and writes only on the confirmed call | no | summarystartend |
update_event | Change an event; preview first, written on the confirmed call | no | event_id |
delete_event | Delete an event; preview first, deleted on the confirmed call | no | event_id |
create_calendar | Create a calendar; preview first | no | summary |
update_calendar | Change a calendar's name, description or time zone; preview first | no | calendar_id |
delete_calendar | Delete a calendar and all its events; preview first | no | calendar_id |
Names come from the published tool document (/v1/meta-tools.json, the same list the MCP server answers to tools/list); the one-line summaries and the money class are kept in the docs repository and checked against it on every build.
Google Drive
action | What it does | Money | Needs |
|---|---|---|---|
search | Search the person's files by name, full text, kind or folder | no | — |
get | Read a file; a Doc, Sheet or Slides file comes back as text | no | file_id |
createexample below | Create a file or folder; answers a preview to confirm first, and writes only on the confirmed call | no | name |
update | Rename a file or replace its content; preview first | no | file_id |
move | Move a file to another folder; preview first | no | file_idfolder_id |
trash | Move a file to the trash (30 days before Google deletes it); preview first | no | file_id |
share | Share a file with someone as reader, commenter or writer; preview first | no | file_idemailrole |
Names come from the published tool document (/v1/meta-tools.json, the same list the MCP server answers to tools/list); the one-line summaries and the money class are kept in the docs repository and checked against it on every build.
Gmail
action | What it does | Money | Needs |
|---|---|---|---|
search | Search the person's mail with Gmail search syntax | no | — |
get_thread | Read a conversation | no | thread_id |
list_labels | List the person's labels | no | — |
create_draft | Create a draft; preview first, nothing is sent | no | tosubjectbody |
sendexample below | Send an e-mail; answers a preview to confirm first, and sends only on the confirmed call | no | tosubjectbody |
reply | Reply in a conversation (reply_all for everyone on it); preview first | no | thread_idbody |
modify_labels | Add or remove labels on a conversation; preview first | no | thread_id |
archive | Archive a conversation (it leaves the inbox); preview first | no | thread_id |
trash | Move a conversation to the trash (Gmail deletes it in 30 days); preview first | no | thread_id |
Names come from the published tool document (/v1/meta-tools.json, the same list the MCP server answers to tools/list); the one-line summaries and the money class are kept in the docs repository and checked against it on every build.
Example
The first call of a write, then the confirmed call with the same arguments:
{
"name": "codespar_gmail",
"arguments": {
"action": "send",
"to": ["loja@example.com"],
"subject": "Troca do pedido 1234",
"body": "Olá, gostaria de trocar o tênis do pedido 1234 pelo número 43."
}
}{
"code": "connector_action_confirmation_required",
"error": "nothing was written: show the preview to the person and, only if they agree, call again with the same arguments and confirmation_id",
"details": {
"tool": "codespar_gmail",
"action": "send",
"server_id": "gmail",
"confirmation_id": "cac_0000000000000000",
"expires_at": "2026-11-04T15:15:00.000Z",
"preview": {
"summary_pt": "Enviar um e-mail para loja@example.com com o assunto \"Troca do pedido 1234\".",
"to": ["loja@example.com"],
"subject": "Troca do pedido 1234",
"body": "Olá, gostaria de trocar o tênis do pedido 1234 pelo número 43.",
"sends_now": true
}
}
}After the person agrees, the same arguments plus "confirmation_id": "cac_0000000000000000" sends it and answers status: "executed" with Google's ids.
Arguments
codespar_calendar
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | list_calendars | list_events | get_event | create_event | update_event | delete_event | create_calendar | update_calendar | delete_calendar |
calendar_id | string | No | Defaults to primary |
event_id | string | For get_event, update_event, delete_event | The event |
time_min, time_max | string | No | list_events: the window, RFC 3339 |
query | string | No | list_events: free text |
max_results | integer | No | 1..50 |
summary | string | For create_event, create_calendar | The title |
description, location | string | No | The event's (or calendar's) description and place |
start, end | string | For create_event | YYYY-MM-DD (all day) or RFC 3339 |
time_zone | string | No | IANA time zone |
attendees | string[] | No | E-mail addresses; Google sends them invitations |
confirmation_id | string | No | The confirmed call of a write (hosted server only) |
codespar_drive
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | search | get | create | update | move | trash | share |
file_id | string | For get, update, move, trash, share | The file |
folder_id | string | For move; optional for search, create | The folder |
name_contains, full_text | string | No | search filters |
kind | string | No | document | spreadsheet | presentation | folder | text |
include_trashed | boolean | No | search |
max_results | integer | No | 1..50 |
name | string | For create | The file's name (on update, a new name) |
content | string | No | create, update: the text content (a folder or a presentation is created empty) |
email, role | string | For share | Who, and as reader, commenter or writer |
notify, message | boolean, string | No | share: whether Google e-mails them, and the note |
confirmation_id | string | No | The confirmed call of a write (hosted server only) |
codespar_gmail
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | search | get_thread | list_labels | create_draft | send | reply | modify_labels | archive | trash |
query | string | No | search, in Gmail search syntax |
max_results | integer | No | 1..20 |
thread_id | string | For get_thread, reply, modify_labels, archive, trash | The conversation |
to, cc, bcc | string[] | to for create_draft, send | Recipients |
subject, body | string | For create_draft, send (body also for reply) | The message |
reply_all | boolean | No | reply: everyone on the conversation |
add_labels, remove_labels | string[] | No | modify_labels |
confirmation_id | string | No | The confirmed call of a write (hosted server only) |
Errors and what to do
| Code | Status | Cause | What to do |
|---|---|---|---|
bearer_token_has_no_person | 403 | A key or an OAuth token, not a verified person. | Call as the signed-in person. |
connector_disabled | 503 | The connectors are switched off on this deployment. | An operator decision. |
connector_not_connected | 409 | The person has not connected this connector in this project. | Connect it in Shop › Preferências. |
connector_consent_required | 409 | The grant is gone at Google (revoked, or the refresh refused). | Connect again. |
connector_scope_insufficient | 403 | The person did not grant the scope this action needs; details.missing_scope names it. | Connect again and accept that permission. |
connector_action_confirmation_required | 409 | A write without the person's confirmation. Nothing was written; details carries the preview. | Show the preview; confirm as described above. |
connector_action_confirmation_stale | 409 | The confirmation expired, was superseded by a newer preview of the same write, was already used, was for other arguments, or the target changed at Google. | Ask again: a new first call makes a new preview. |
connector_account_not_owned | 404 | A connection or confirmation that is not the person's, or does not exist. Both answer the same. | None. |
connector_provider_error | 502 | Google answered an error that is none of the above. | Try again later. |
policy_denied | 403 | The project's policy does not allow this tool or action. | A project decision. |
invalid_args | 400 | A field missing or malformed (details.field). | Fix the call against the tables above. |
Related
- Connect Links: the connect flow these connections use
- Shop memory and Shop watches: the person's other own data
- Hosted server: where the three tools are published
Notes
Where the person sees it. Shop › Preferências › Conexões Google shows each connector with its state, the masked account and the granted permissions in words, with Conectar, Reconectar and Desconectar.
Shop Watches
The person's own watches through the codespar_watch tool. Tell them when a researched offer's price drops or a purchase's order moves, in the app and by e-mail. A watch the assistant prepares runs only after the person confirms it.
Mandates, receipts and approvals
What a mandate is, where one is born per channel (REST, SDK, CLI, dashboard, meta-tool), who signs it and why you never do, how it is paused and revoked, what the receipt of a spend is, and why an API key cannot decide a held approval.