$ lanes link connect gmail --profile personal --workspace localThat is the whole of it. A browser opens, you approve the scopes, the connection is made. There is no Cloud project to create and no client to register: by default Lanes Link authorises against a client Lanes operates, whose secret stays in the Lanes API and never reaches your machine.
Two things that costs you, both worth knowing before you start:
- Until Google's verification completes you see a "Google hasn't verified this app" screen. Choose Advanced → Go to Lanes to continue.
- The hosted client is limited to 100 Google accounts, a cap Google counts for the lifetime of
the project.
connectwarns as it fills.
If neither suits you, register a client of your own.
Each product is its own connection
Connecting Gmail does not imply Drive, Sheets, Docs, Calendar, Tasks, or Contacts. Each holds its own
token under its own scopes. One OAuth client covers all seven, so adding the second costs no new
credentials, but each needs its own API enabled and its own scopes registered. connect prints that
console work the first time you connect each product.
$ lanes link connect drive --profile personal --workspace local
$ lanes link connect calendar --profile personal --workspace localWhat your agent can do
Gmail. Search with Gmail's own q syntax, then retrieve by id. Read threads, labels, drafts, and
attachments. Send mail or write a draft; send or discard a draft that exists. Archive, mark read,
report spam, and move between folders, which in Gmail are all one operation on labels. Trash and
untrash, which are recoverable. Create and delete filters, which is how a sender is blocked.
There is no permanent delete. That needs the mail.google.com scope, which this refuses to ask
for.
Drive. Search files and read metadata, export a Google-native file to a portable format, and see
who a file is shared with. Create, copy, update, move, rename, delete, and share. Creating a
spreadsheet, document, or presentation is also drive.files.create, with the right mimeType.
Every write is bounded by the drive.file scope, so an agent can only touch files it created or
that you opened with it. Reading is drive.readonly.
Sheets and Docs. Read a spreadsheet's structure without its cells, read one range or several at
once, then write, append, or clear. Everything structural (tabs, formatting, frozen rows, charts)
goes through batchUpdate. Docs reads the document as a structure, which is how you find the index
to edit at, and every edit is documents.batchUpdate.
Calendar, Tasks, and Contacts. List calendars and events, expand a recurring event, and answer "when am I free" in one call across calendars whose contents the token may not read. Create, patch, delete, and move events. The same lifecycle for task lists and tasks, where completing a task is a patch with a status.
Contacts is read-only and cannot enumerate: there is no "list all my contacts". It searches, so "email Bob" resolves to an address, including over addresses Gmail saved automatically.
Nothing here destroys a container. Deleting a task list would take every task with it, so it is not offered.
The weekly re-authorisation
This is the one thing about Google worth understanding before you rely on it.
It is a property of the OAuth client's publishing status, and nothing else. A client in Testing has every refresh token it issues expired after seven days; a client in production does not. The hosted client is under review, and a client under review has whatever status it has, so connections made against it expire weekly too until that lands.
When one dies, a call fails with a message naming the cause and the fix:
The refresh token for gmail.work has expired or been revoked.
Re-authorise with: lanes link connect gmail.work
lanes link doctor reports stale connections before you hit them:
$ lanes link doctor --profile personal --workspace local
warn gmail.personal credential is 8 days old. Testing-status apps expire at 7.
Run: lanes link connect gmail.personalThe ways out, cheapest first:
| Escape | What it costs |
|---|---|
| Register your own client as Internal | About ten minutes, once. Needs a Google Workspace organisation, and every account on that domain. Nothing to maintain afterwards |
| Register your own as External, and publish it | About twenty minutes. An unverified-app screen for everyone you connect, and a lifetime cap of 100 new users on that project. This is the one most people want |
| An app password over IMAP | Personal accounts only, mail only. Nothing expires and there is no console project at all |
| A service account key | Nothing expires, because nothing consented. It reaches less, and how much less depends on the product |
| Complete Google's verification | Weeks to months, and for restricted scopes a paid third-party security assessment |
Anything else claiming to avoid this is either using non-restricted scopes or is about to stop working.
Gmail over IMAP
If this is a personal @gmail.com and mail is what you need, there is a route with nothing to
expire and no console project at all:
$ lanes link connect gmail_imap --profile personal --workspace localThat is a different provider from gmail rather than another route into it, because a manifest has
one connector and IMAP is not HTTPS.
gmail | gmail_imap | |
|---|---|---|
| Credential | OAuth token, or a service account key | An app password |
| Expires | with the client's publishing status | never |
| Works on Workspace | yes | no. Google ended basic auth there in March 2025 |
| Reaches | Gmail's API: labels, threads, drafts, the lot | a mailbox: search, read, flag, move, send |
| Policy rule | gmail.* | gmail_imap.* |
They are separate connections and can both exist. Nothing shares a credential between them.
Getting the password. Two-Step Verification has to be on first, or the app-passwords page reports that the setting is unavailable rather than saying why. Then myaccount.google.com/apppasswords, create one, and name it "Lanes Link", which is the only way to revoke this one later without cutting off your other devices. Google shows the sixteen characters once, in four groups of four. The spaces are cosmetic.
If a login is refused, it is almost always the account password pasted where the app password
belongs, because IMAP reports both the same way. lanes link connect gmail_imap --replace is the
fix; a bare re-run finds the refused credential already stored and reuses it.
When something goes wrong
| Symptom | Cause |
|---|---|
invalid_grant, roughly weekly | Testing publishing status. See the weekly re-authorisation |
invalid_grant once, after months of working | Not an expiry. The consent was revoked: a Workspace admin withdrawing third-party access, a password change, or a removal at myaccount.google.com/permissions |
invalid_grant immediately | The account is not in Test users, or the grant was revoked |
| 403 "Insufficient Permission" | The API is not enabled, or the consent did not include the scope |
| 403 on the Gmail organising tools only | The consent predates gmail.modify. Add it under Data access, then re-run connect. A refresh keeps the old grant and will not pick it up |
| 403 on the Gmail filter tools only | The consent predates gmail.settings.basic. filters_list still working is the tell, because it accepts gmail.readonly |
| 403 on every Calendar call, but consent worked | The enabled service is calendar.googleapis.com. Calendar's is calendar-json.googleapis.com |
| Tools list fine, every call says "The caller does not have permission" | You are on gmail_mcp or drive_mcp without Workspace Developer Preview enrolment. Switch to gmail or drive |
| No refresh token returned | The account already authorised this app. Revoke at myaccount.google.com/permissions and retry |
| The tool list did not change after a version bump | The served list comes from the discovery cache. Re-run connect to refresh it |
| Mailboxes missing after an IMAP login succeeds | Gmail → Settings → See all settings → Forwarding and POP/IMAP → IMAP access |
lanes link audit tail shows what was actually attempted, with arguments redacted.
Next: Add it to your agent. If you need your own OAuth client, a service account, or the Workspace MCP servers, that is Registering your own Google client.