-
released this
2026-08-21 21:29:11 -05:00 | 21 commits to main since this releaseG1: a fourth tenant, and it reads Gmail. Seven read tools on their own hostname, their
own connector and their own credential, built against what nine live probes found rather
than against the RFCs. The code is not live-verified and G1 is not done until it is —
docs/gmail-plan.mdcarries the pass to run, and a green gate has cleared nothing on this
project since M2 shipped 799 passing tests around amove_messagethat had never worked.Added
-
TENANT=gmail, withmcp_gateway/gmail/:list_folders,list_unread_counts,
list_messages,search_messages,get_message,get_message_securityand
get_attachment. Read-only, and not by a switch — there is no write path in the
package at all, asserted against the built server withMAIL_WRITABLE_FOLDERSand
MAIL_SEND_ENABLEDboth set to values that would enable one next door. -
GOOGLE_MAIL_ADDRESSandGOOGLE_APP_PASSWORD, required only by this tenant, which
reads neither Apple value. Provider-prefixed rather than generic because these arrive as
per-service Portainer variables: two service blocks each holding aMAIL_ADDRESS, with
different mailboxes in them, is the paste hazard Credentials already names for
MCP_OAUTH_SIGNING_KEY. -
deploy/nginx/gmail.conf, andConfig.mail_address/Config.is_mail_tenantso
nothing downstream has to know which tenant it is in to ask for the mailbox.
Changed
-
list_unread_countsandsearch_messagesexclude All Mail from the all-labels
answer, because Gmail files every message there as well as under its label — probe 5
found every sampled INBOX message in both. Summing across labels without this reports
roughly double the real unread total, and reports it confidently. Excluded by role,
never by name: the[Gmail]/folders are localized, so matching the English string
would silently stop matching and put the double count straight back with no error. -
Both mail tenants now name their account in every colliding tool description. Seven
names exist on both connectors, andCLAUDE.mdmandates verb-first names with a test
pinning it — so the names cannot disambiguate and the descriptions have to. A rule
applied to one of two colliding tenants is not a rule, so iCloud's seven changed in this
commit too, and a test fails if either side ever drops it.
Notes
-
Gmail advertises
SPECIAL-USE,UIDPLUS,MOVEandX-GM-EXT-1. iCloud has
neitherSPECIAL-USEnorMOVE, so its role-guessing and itsCOPYUIDworkaround are
iCloud's problems and are deliberately not carried across. Copying them would have
added mystery rather than safety. -
get_message_securityneeded no new parsing.mail/authresults.pyreads Gmail's
header unmodified. The tool does add one thing probe 9 found by accident: a message the
user sent themselves carries noAuthentication-Results, because it never left
Google — so an absent block is reported as not applicable rather than rendered as a
failure. Everything in Sent looks like that, and it is exactly what a naive
implementation would flag as suspicious. -
Two of the new tests were rewritten after they passed. The first fake overrode
unread_countsand re-implemented the All Mail rule inside itself, which asserts only
that the test agrees with the test. It now intercepts the connection, so the real method
runs — and both it and the naming rule were confirmed by breaking the code and watching
them fail. -
1100 tests green (16 new).
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-