# Your AI Agent Can Send Emails as You

> The Gmail MCP server gives AI agents access to send emails, delete messages in bulk, and manage your inbox. Here's how to rate limit sends and block batch operations.

Published: Mon Mar 16

Canonical: https://policylayer.com/blog/secure-gmail-mcp-server

Your AI assistant just emailed your entire contact list. It was supposed to reply to one customer — but it hallucinated an email address, drafted a rambling apology for an issue that never happened, and hit send. Five times. To five different people, including your CEO's wife. By the time you noticed, the replies were already coming in.

Or maybe it's worse. Maybe you asked it to "clean up old promotions" and it called `batchDelete`, wiping 4,000 messages in a single request. No trash folder. No undo. Permanently gone.

This is what happens when you give an AI agent unrestricted access to your Gmail. And that's exactly what the Gmail MCP server does.

<!--truncate-->

## What the Gmail MCP server exposes

Google's [Workspace CLI](https://github.com/googleworkspace/cli) includes a Gmail MCP server (`gws mcp -s gmail`) that exposes **79 tools** to any connected agent. The dangerous ones:

- **`gmail_users_messages_send`** and **`gmail_users_drafts_send`** — send emails as you, to anyone
- **`gmail_users_messages_batchDelete`** — permanently delete messages in bulk. No trash, no recovery
- **`gmail_users_messages_batchModify`** — relabel or archive hundreds of messages at once
- **`gmail_users_messages_delete`** — permanently delete individual messages
- **`gmail_users_settings_forwardingAddresses_create`** — silently set up email forwarding to an external address
- **`gmail_users_settings_delegates_create`** — grant another account access to your mailbox

Read operations like `gmail_users_messages_list` and `gmail_users_threads_get` are harmless. But the send, delete, and settings tools can cause damage that ranges from embarrassing to irreversible — and MCP provides zero built-in controls.

Prompt instructions won't save you here. "Only send 5 emails per hour" works right up until the agent decides the situation warrants an exception. As we covered in [What Happens When Your AI Agent Goes Rogue](/blog/ai-agent-goes-rogue), the only reliable constraint is one that operates outside the model's reasoning — at the transport layer, deterministically.

## Rate limit sends, block bulk operations

[PolicyLayer](/mcp-gateway) sits between your agent and the Gmail MCP server. Every `tools/call` is evaluated against a YAML policy before it reaches Google. Violating calls are blocked and the agent receives a denial message.

Here's the core of the Gmail policy — sends capped at 5 per hour, bulk operations blocked outright:

```yaml
version: "1"
description: "Policy for gws mcp -s gmail"
default: "allow"
tools:
    gmail_users_messages_send:
        rules:
          - name: "rate-limit-sending"
            rate_limit: "5/hour"
            on_deny: "Rate limit: max 5 sent emails per hour"

    gmail_users_drafts_send:
        rules:
          - name: "rate-limit-sending"
            rate_limit: "5/hour"
            on_deny: "Rate limit: max 5 sent emails per hour"

    gmail_users_drafts_create:
        rules:
          - name: "rate-limit-draft-creation"
            rate_limit: "10/hour"
            on_deny: "Rate limit: max 10 drafts per hour"

    gmail_users_messages_batchDelete:
        rules:
          - name: "block-bulk-operations"
            action: deny
            on_deny: "Bulk message deletion blocked by policy — delete messages individually"

    gmail_users_messages_batchModify:
        rules:
          - name: "block-bulk-operations"
            action: deny
            on_deny: "Bulk message modification blocked by policy"

    gmail_users_labels_create:
        rules:
          - name: "rate-limit-label-changes"
            rate_limit: "10/hour"
            on_deny: "Rate limit: max 10 label operations per hour"

    "*":
        rules:
          - name: "global-rate-limit"
            rate_limit: "60/minute"
            on_deny: "Global rate limit: max 60 calls per minute"
```

The two batch tools — `batchDelete` and `batchModify` — are blocked unconditionally with `action: deny`. There is no legitimate reason for an AI agent to permanently delete hundreds of emails in one call. If the agent needs to delete messages, it can use `gmail_users_messages_trash` (which is rate-limited to 10/hour and moves to trash rather than destroying permanently).

Sends are limited to 5 per hour. Drafts get 10/hour. Label operations — creating, modifying, deleting — are capped at 10/hour. And a global rate limit of 60 calls per minute catches any tool not explicitly listed, preventing runaway loops regardless of what the agent decides to do.

The `default: "allow"` posture means read tools pass through freely. Your agent can still search, list, and read messages without restriction.

## Getting started

Route your Gmail MCP server through PolicyLayer — point your MCP client at the gateway URL with a per-person grant token, and the policy above runs on every call before it reaches Gmail:

```json
{
  "mcpServers": {
    "gmail": {
      "url": "https://proxy.policylayer.com/mcp/<server-uuid>/",
      "headers": { "Authorization": "Bearer <grant-token>" }
    }
  }
}
```

You define and adjust the policy in the [PolicyLayer dashboard](https://app.policylayer.com) — no local proxy to install or run.

Email number 6 in an hour gets blocked. Batch delete attempts get blocked every time. Your inbox stays intact, and your contacts stay un-spammed.

[Full Gmail policy →](/policies/google-workspace-gmail)
