[BUG] [PRIVACY] GMail MCP Rewrites URL with google tracking URLS as of 5th of June
Status Open
Maintainer reply None cached
Workaround ✓ Mentioned in thread ↓
Activity 20 comments · opened Jun 7, 2026
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
As of few days GMail MCP is rewriting - silently URL in the emails created as drafts with google tracking URLs - this is privacy nightmare and it's been done silently without telling anyone.
This should be fixed immediately and this "feature" should be opt-in.
What Should Happen?
URLs should be passed verbatim and not modified on the flight.
Error Messages/Logs
No error logs, no information about this happening
Steps to Reproduce
- Send draft email with embedded URL
- Observe the URL in draft is silently rewritten to
https://www.google.com/url?q=…&source=gmail&ust=…&sa=E)
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
v2.1.168
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
Please - don't do it.
20 Comments
The rewritten form you're seeing —
https://www.google.com/url?q=…&source=gmail&ust=…&sa=E— is Gmail's own link redirector, not something Claude Code or the MCP generates. Thesource=gmail/ust/sa=Eparameters are Gmail's server-side signature; that wrapper is applied by Google's mail infrastructure to links inside email bodies, which lines up with theexternallabel here.That said, "it worked in a previous version" is a real signal, so the useful question is what changed on the MCP side that now makes Gmail wrap the links. The usual trigger is the MIME content type of the body:
text/plain, Gmail generally leaves URLs verbatim.text/html(or multipart with an HTML part), Gmail tends to rewrap<a href>/auto-linked URLs through thegoogle.com/url?q=…redirector.So a likely explanation is that the MCP started sending drafts as HTML where it previously sent plain text.
How to pin down where the rewrite happens (and who owns the fix), without guessing:
users.drafts.getwithformat=RAW(orusers.messages.get?format=raw), and base64url-decode the payload.google.com/url?q=…form → Gmail rewrote it at accept-time (or the MCP sent it pre-wrapped). Check theContent-Typeheader in that same MIME — if it'stext/html, that's almost certainly the cause.If the raw MIME is
text/htmland contains the wrapped URLs, the fix belongs in the Gmail MCP server (sendtext/plain, or expose a content-type option), not in Claude Code core — and it'd be worth filing against that MCP server repo with the raw MIME attached. If the stored body is verbatim, then nothing was actually modified in your data and it's purely Gmail's render-time redirect.Either way, the raw-draft dump is the one artifact that settles it conclusively.
Just to verify if google is doing something global I tested with Grok to send an email with https link and there was no URL google.com wrapping then.
Reproducing this via Claude Desktop + Gmail MCP (Gmail:create_draft)
Same issue here. When Claude creates a draft using htmlBody with clean <a href="https://example.com">anchor text</a> tags, the links in the resulting draft already contain the google.com/url?q=... wrapper before the email is ever sent. This means recipients are hitting a redirect warning interstitial and have to click "Continue to site" before the link loads.
The rewriting is happening inside the MCP at draft-creation time, not as a Gmail send-time behaviour. The href in the draft's HTML source is already wrapped when you inspect the draft in Gmail.
Reddit thread also tracking this: https://www.reddit.com/r/ClaudeCowork/comments/1uci5fz/links_in_coworkdrafted_gmail_started_arriving_as/
Still reproducing on v2.1.197 (macOS), ~6 weeks after this report — not fixed.
**Minimal repro (confirms it's not reply-specific): a brand-new draft via
create_draftwith two plain-text URLs comes back with both** rewritten tohttps://www.google.com/url?q=…&source=gmail&ust=<ts>&sa=Ein the stored body — as visible text, not just thehref. Both share oneust=timestamp → a single wrapping pass at creation. NoreplyToMessageId, no quoted original involved.Contrast on the same account: creating the identical draft via the community
workspace-mcpdraft_gmail_messagetool stores the URLs verbatim. So the raw URL reaches the pipeline intact — the built-in connector is what mangles it.Impact: hits client-facing links — e.g. a payment link renders as
google.com/url?q=…next to "Pay $X," which reads as phishing on a payment email and forces manual fixes or switching tools.+1 that URLs should be passed verbatim.
This is causing problems on my end as well - trying to embed a img reference in an htmlBody messge. The google url wrapper is breaking the image embeding.
Still present on v2.1.193. Adding a datapoint that may narrow this, because the rewrite
does not appear to survive sending, at least for
<a href>inhtmlBody.Created a draft via
create_draftwith a plain href. Reading it back withlist_draftsreturns it wrapped:
A different draft on the same thread, created the same way and then sent by hand, reads
back from
get_messagewith the href intact:Plain, no wrapper, no tracking params. Same for every other sent message on that thread.
So in our case the wrapping is in the draft representation only, and the recipient gets
the URL verbatim.
Worth separating two claims in this thread, since they have different severities:
message we checked carried the author's original URL.
If others are seeing (2) with actual received mail, that is a much bigger problem than
(1) and probably deserves splitting out, because right now the report reads as if both
are established.
The practical cost of (1) on its own is still real, just different from a privacy leak:
anything that diffs a draft against the message that was eventually sent now sees a
spurious change on every link. We do exactly that to track which parts of generated
drafts humans edit by hand, and it produces false positives on nearly every draft, since
most of ours carry at least one link. Workaround is to normalize
google.com/url?q=back to its
qparam on both sides before comparing.No data to add on the
<img>case from the comment above, we do not embed images.Environment: Claude Code v2.1.193, macOS, Gmail connector,
create_draft/list_drafts/get_message.Confirming this is still reproducing as of September 2, 2026, and that it affects sent messages, not only drafts.
My setup is a scheduled task that composes a daily news digest and sends it via
mcp__Gmail__send_message. Every source URL in the delivered mail arrives wrapped as https://www.google.com/url?q=…&ust=….Three tests that narrow the cause:
bodyonly, nohtmlBodyat all. Bare URLs in the plain-text body were wrapped too, despite there being no anchor tags anywhere in the message.That points to the rewriting happening in the connector at send time, applied to URLs in the message content regardless of MIME part.
On impact: the digest cites sources for a research brief. A wrapped URL is not the citation it claims to be. The destination is not visible before clicking, copying a link yields the redirect rather than the article, and every click is routed through Google. For a daily digest that becomes a standing record of what the recipient reads.
Agreed with the original request. Verbatim URLs seem like the right default for a send API, with wrapping opt-in at most.
This is occurring for me too, and very frustrating as adding the https://www.google.com/url?q=... wrapper makes it mandatory that I edit the URL in the email before sending it, despite Claude CoWork supposedly making crafting an email faster. I tried asking Claude to create plain text URLs, but it still was required to add brackets such as [.] and make it still time consuming to edit when I'm wanting to focus on other aspects of the email to ensure they are accurate rather than things like this.
This is from Google's own API, which is consumed by GMail MCP. The only way around it is not using the MCP, but an "App Password" to send it directly via SMTP.
App passwords basically open up your account for anyone with access to it, so be careful :)
One thing i found that works, have Claude write as an HTML email and then at least the url wrapper is in the background and not visible in the email -- this works for me and allows me to send without editing. Hope this helps some others here!
This is still a bug which makes it so that Claude is unusable for creating drafts in Gmail. Seems like a P1 issue if Claude wants to be a work partner!
Yes, this is a highly annoying bug. I read this comment, but took it a step further. The only way around is to NOT use the MCP but there are many other ways besides an app password.
What other connectors do you have, that use Gmail?
For me, I have Zapier so I use the Zapier Connector for creating drafts now. Problem solved.
Facing the same issue here.
I've reported this to Google, since the rewrite happens on their side and Anthropic can't fix it:
https://issuetracker.google.com/issues/569219200 (Gmail API component)
What I found (raw MIME via
get_draftwithRAW):create_draftwith onlybody, nohtmlBody, still comes back with a wrapped URL in thetext/plainpart. The server also adds an HTML part we never sent, with the same wrapper. So switching to text/plain doesn't avoid it.Received: … by gmailapi.google.com with HTTPREST, so the rewrite happens server-side when the draft is created.ustis creation time + 24h, so the wrapped links appear to go stale after a day.I've also opened a Workspace support case and asked for it to be linked to the issue.
If you're affected, please ★ the Google issue (top left of the issue page). Stars are how Google gauges impact, and if you're on Workspace, opening a support case that references the issue adds more weight.
Can I ask, how are you sure that it's the Google side? Other platforms, MCP etc do not have this issue.
This is really bad. It makes the gmail tool unusable, accidentally sending anything that reads like a link results in an embarrassing mess. It will also split hostnames, so
foo.bar.example.combecomesfoo.https://www.google.com/url?q=http://bar.example.com&source=gmail&ust=...&sa=E, and it will keep adding "Re:"s to the subject line, even if there'a already one there, so an email with "Re: example" becomes "Re: Re: example"Good question. There's a timestamp fingerprint that shows the rewrite happens inside Google's server, not before the request reaches it.
The client doesn't build the MIME:
create_drafttakes plain fields (body,subject), and Google's server assembles the message. Fetch a wrapped draft raw and compare:----=_Part_41210_236293551.1791017778859. The last part is a millisecond timestamp:1791017778859.…&ust=1791104178859000&sa=E. Theustis in microseconds.ustis a 24h expiry, so:1791017778859ms + 86,400,000 ms (24h) =1791104178859ms =1791104178859000µs, exactly theustvalue, to the millisecond. I checked three separate drafts and all three match the same way. So the wrapper is generated by the same process and clock that builds the message on Google's side. If the client, or anything between it and Google, had rewritten the body before sending, its timestamp couldn't line up with Google's MIME-build time like that.You can check your own: fetch a wrapped draft with
get_draft(format RAW), take the boundary's trailing number, add 86400000, and compare withust/1000.As for other platforms not having the problem: as far as I can tell, they don't use Google's MCP server.
Got a reply from Google Workspace Support:
Reproduced on 2026-10-07 with the claude.ai Gmail connector (claude.ai chat, desktop app), not Claude Code CLI. A few findings that might help narrow this down:
send_message: I sent a mail with a plain-text body only (to,subject,body). Reading the sent message back viaget_message(RAW), both thetext/plainpart and atext/htmlpart (which I never supplied) contain the URLs wrapped ashttps://www.google.com/url?q=<original>&source=gmail&ust=...&sa=E. Bare domains likeexample.orgwere also turned into wrappedhttp://links. So the rewrite is already present in the stored/sent message, not just in the draft view.create_draft: the same happens with (a)body+htmlBodywith explicit<a href="...">anchors and (b)htmlBodyonly. In both cases thehreftargets and the plain-text part come back wrapped viaget_draft(RAW). ThehtmlBodyworkaround suggested in #91287 therefore did not help in my case.mailto:links and plain email addresses were not rewritten, onlyhttp(s)URLs and bare domains.Impact: recipients receive redirect links that look like tracking links, the original URL is hard to read, and I had to verify and repair every outgoing mail manually. That defeats the purpose of using the connector in an agentic workflow.
Requested behavior: store and send the body verbatim (as a direct Gmail API call does), or at least make the rewriting opt-in / provide a parameter to disable it. If the wrapping is intentional, please document it in the tool descriptions.
Workaround: skip the connector and call the Gmail API directly
Because the rewrite seems to happen in the connector's draft/send path, calling the plain Gmail REST API avoids it. I tested this on 2026-10-07: a mail with
https://example.com/path?x=1&y=2and a bareexample.orgarrived with unmodified links, in both thetext/plainandtext/htmlparts.How to set it up:
https://www.googleapis.com/auth/gmail.compose, and keep the client ID/secret/refresh token in a password manager (I use 1Password and read them withop read).How to call it:
email.message.EmailMessage(plain text part plus an optionaltext/htmlpart with explicit<a href>links), base64url-encode it, and send it as{"raw": "..."}.POST https://gmail.googleapis.com/gmail/v1/users/me/draftscreates a draft,POST .../users/me/messages/sendsends it directly.Send asaddress works as theFromheader.Caveat: with only
gmail.compose,drafts.getworks butmessages.getreturns 403, so a sent message cannot be read back with that scope.I wrapped this in a small stdlib-only script (draft/send,
--cc/--bcc/--attach,--dry-run). ~Happy to share it if useful.~ -> https://gist.github.com/rudi3k/98f8debcc5e387b7365eb4908eece9c2This only works around the problem on the user's own machine. The connector itself should still store and send bodies verbatim, or make the rewriting opt-in.