· Experiences · 6 min read

Giving AI Its Own Keys with MCP

Connecting AI to email and Notion made it feel like a second brain. Giving it separate accounts and credentials made that useful without handing over the keys to everything else.

An ornate brass key resting on the Enter key of a black computer keyboard.

I wanted AI to do more than answer a question and forget about it. I already had issue updates arriving by email, and I had Notion waiting on the other side as the place where I organize what happened. Copying the progress over by hand worked, but it was exactly the kind of small, repetitive job that made my “second brain” feel suspiciously dependent on the first one.

MCP gave me a way to connect those pieces. The useful part was not just that the AI could call another service. It was that I could give it a small set of tools, let it read from one place and write to another, and keep that access separate from the accounts I use every day.

The workflow I wanted

My practical goal was to document the progress of issues without rebuilding the history from memory later. Updates were already showing up through email, so I connected an AI-accessible Gmail account and let the workflow read those messages. From there, it could collect the useful progress and organize the resolutions in Notion.

Email remained the stream of updates, while Notion became the durable record. The AI handled the translation between them instead of becoming one more inbox to check.

MCP made the boundary understandable. A server exposes a particular set of tools, and the AI can use those tools as part of the conversation. It does not magically gain access to every service on my computer. However, that distinction only helps when the accounts and tokens behind those tools are scoped with the same care.

Build a sandbox before a workflow

My first rule became: do not start with my primary account.

I created a dedicated Gmail account for the updates the workflow needed to read. That gave the AI its own inbox rather than permission to wander through my personal email. The same idea applies to API tokens. I would rather issue a separate token for an MCP integration than reuse one that already has broad access somewhere else.

This is less convenient at the beginning. There is another account to configure, another token to name, and another permissions screen to click through. But the inconvenience buys me a boundary I can understand:

  • The inbox contains only messages intended for the workflow.

  • The token belongs only to the MCP connection.

  • Permissions can be limited to the actions the workflow needs.

  • I can revoke that access without interrupting my normal account.

That last point matters. A sandbox is not only protection against a spectacular failure. It makes ordinary debugging less nerve-racking. If I configure a tool incorrectly or the workflow behaves differently than I expected, I know how far the mistake can reach.

Keep credentials out of the MCP configuration

The other boundary is in the project itself. I do not put credentials directly in .cursor/mcp.json. That file describes the Notion and Gmail connections, while the Gmail client credentials live in .env and are referenced by name.

This is the shape I use for the workflow:

{
  "mcpServers": {
    "notion": {
      "url": "https://mcp.notion.com/mcp"
    },
    "gmail": {
      "url": "https://gmailmcp.googleapis.com/mcp/v1",
      "auth": {
        "CLIENT_ID": "${env:GMAIL_MCP_CLIENT_ID}",
        "CLIENT_SECRET": "${env:GMAIL_MCP_CLIENT_SECRET}",
        "scopes": ["https://www.googleapis.com/auth/gmail.readonly"]
      }
    }
  }
}

The local environment file holds the two Gmail values:

GMAIL_MCP_CLIENT_ID=replace-with-the-client-id
GMAIL_MCP_CLIENT_SECRET=replace-with-the-client-secret

The .env file stays out of source control. The MCP configuration can be shared as part of the project because it contains the variable names, not their values. The Notion entry points at Notion's remote MCP endpoint without placing a Notion credential in this file.

The Gmail scope is just as important as where the secret is stored. gmail.readonly lets the workflow inspect the updates arriving in its dedicated inbox without granting permission to send, edit, or delete mail. The configuration says what the integration can do instead of relying only on the fact that it has its own account.

The JSON is not the whole Gmail setup. Google's Gmail MCP configuration guide walks through enabling the Gmail API and Gmail MCP API in a Google Cloud project, configuring the OAuth consent screen in Google Auth Platform, and creating an OAuth 2.0 client ID and secret. The account still has to complete that authorization flow before the MCP server can read the inbox with the requested scope.

Access should match the job

A dedicated credential is only useful if it is also limited. If an MCP server only needs to read email, I do not want to give it permission to send or delete messages. If the Notion side only needs to add and update a known set of pages, it does not need a map of the whole workspace.

I think about each connection in terms of the smallest job it has to perform:

  1. What does the workflow need to read?

  2. What does it need to create or update?

  3. Which account owns that data?

  4. How do I revoke the integration without affecting anything else?

MCP makes services easier to connect, but it does not make those permission decisions for me. The tool boundary and the credential boundary have to agree. Otherwise, I have built a tidy interface over access that is still much broader than the task.

Turn the workflow into a scheduled habit

Once the instructions are stable, this does not have to remain a prompt that I remember to type. I can package the process as a Cursor Skill: read the dedicated inbox, identify meaningful issue updates, organize the resolution in Notion, and report anything that needs my attention. The skill keeps the steps and expected result together in a reusable SKILL.md instead of depending on whichever wording I come up with that day.

I can then use a Cursor Automation to run that skill on a schedule. A daily run could process the latest updates before I start work, while a weekly run could produce a broader issue summary.

Scheduling does not remove the access boundary. A project-local .cursor/mcp.json does not, by itself, make these integrations available to a scheduled agent. Gmail and Notion must also be connected and authenticated where the automation runs. The skill defines the job, the schedule starts it, and the MCP connections limit its reach.

Final Thoughts

The email-to-Notion workflow was the first time the “second brain” idea felt practical to me. Updates could arrive where they already arrived, and the useful parts could become organized notes without another round of copying and pasting.

The part I am keeping, though, is not a particular Gmail or Notion tool. It is the sandbox around them. A separate inbox, a separate token, permissions that match the job, and credentials loaded from .env turned MCP from an interesting connection into something I was comfortable relying on. Wrapping those instructions in a skill and running it on a schedule can make the result dependable without widening that boundary. Giving AI a key can unlock a useful workflow. I just want it to be a key made for that door.

Back to Blog

Related Posts

View All Posts »
Reactivity in Astro

Reactivity in Astro

As I was learning to use the Astro framework, I wanted to learn about idiomatic implementations within Astro. Here is what I learned about implementing reactivity in Astro.

Implementing an AI RAG for Bylaw Retrieval

Implementing an AI RAG for Bylaw Retrieval

A bylaw search assistant should find the right clauses without making the rules up as it goes. Building one taught me that retrieval quality, citation quality, and consistency all need their own tests.

Building a Layered Scroll Background with CSS View Timelines

Building a Layered Scroll Background with CSS View Timelines

A layered landscape can make a long page feel alive, but tying several large images to scroll introduces its own design and debugging constraints. I built one with transparent image layers, CSS view timelines, and a few safeguards that keep the content in charge.

© 2026 Sea Otter Studios All rights reserved.