Part of MCP Builders — The Producer Playbook. Chapter 2 of 6.

Your MCP server works in the demo. A developer connects GitHub — or your product — completes OAuth, and the agent happily calls tools. Everyone applauds.

Three weeks later, security asks a question nobody prepared for:

“What exactly did the user authorize — and what can the LLM do with it when nobody is watching?”

That is not a hypothetical. OAuth for SaaS was designed for humans clicking “Allow” and then making deliberate API calls. MCP adds a middle layer: an agent that may invoke tools repeatedly, in parallel, with imperfect judgment, while the user is in another tab.

This chapter is about building authorization that survives that reality — not OAuth syntax (the spec and SDKs cover that), but the permission model your server exposes to agents.

The delegation chain you are actually building

When OAuth succeeds in an MCP flow, authority flows through four hops:

  1. End user — owns the upstream account (GitHub, your SaaS, etc.)
  2. MCP client — Cursor, Claude Desktop, Slack with Claude Tag
  3. Your MCP server — holds or exchanges tokens, maps tools → upstream API calls
  4. Upstream API — enforces scopes on each request

The user’s mental model: “I connected my account.”

The actual model: “I delegated a capability bundle to an autonomous caller.”

If your tool surface is too broad, or your tokens too long-lived, you have not connected an account — you have installed a persistent agent with the user’s privileges.

Why copying your SaaS OAuth app is dangerous

Most teams reuse the OAuth application they built for the web dashboard. Same client ID, same scopes, same refresh token behavior. Fast to ship. Wrong abstraction.

Dashboard OAuth assumes:

  • A human reads UI before destructive actions
  • One action per session intent
  • Session length matches “using the product now”

MCP OAuth assumes none of that. The agent may:

  • Call create_issue because a prompt sounded like a suggestion
  • Retry failed writes with variations
  • Chain read tools into write tools faster than the user can review
  • Run overnight in a scheduled workflow

Fix: treat MCP as a separate OAuth client — or a separate scope bundle — with tighter defaults than your web app.

Scope minimization: map tools, not endpoints

Do not translate your OpenAPI file 1:1 into MCP tools. Map each tool to the smallest upstream scope that satisfies it.

ToolGood scope postureOver-permission trap
search_issuesRead-only issues in one orgFull repo admin
get_customerSingle-record readExport-all customers
create_draftWrite to drafts onlyPublish + delete

Document the mapping in your server README and submission to Influzer.ai. Enterprise buyers ask for it.

Read vs write: ship the split explicitly

The safest rollout pattern for a new MCP server:

  1. Phase 1 — read tools only. Search, get, list. No mutations.
  2. Phase 2 — narrow write tools. One verb per tool: create_comment, not manage_ticket.
  3. Phase 3 — optional admin tools behind separate OAuth consent or disabled by default.

Name tools so models infer risk:

  • list_invoices — clearly read
  • create_refund — clearly write; never bury inside handle_billing

Teams consuming your server run audits like our seven-question checklist. Write tools with vague names fail review.

Token lifetime and offboarding

Refresh tokens that live for months + agent access = ghost employees.

When Sarah leaves the company:

  • Her IdP account is deactivated — good
  • Her personal GitHub PAT in a shared mcp.json — still works — bad
  • Her OAuth refresh token in your MCP server’s store — still works until revoked — worse

Builder checklist:

  • Short access token TTL with refresh where appropriate
  • Revocation endpoint or admin “disconnect all sessions”
  • No long-lived PATs as the default auth path for team configs
  • Prefer enterprise-managed auth when the client supports it — users inherit IdP offboarding (see our enterprise auth breakdown)

Chapter 3 will go deeper on implementing enterprise-managed auth as a provider. For now: design as if tokens outlive the employee who created them — because they will.

The five over-permission patterns we see in the wild

1. One consent screen for all tools

User clicks Allow once; your server exposes twelve tools including delete and admin. Split consent by risk tier, or ship read tools under a separate client.

2. God-mode personal tokens in team repos

A developer commits their PAT so “the team can try it.” That token now powers any agent on any machine that loads the config. Ban this in your docs; offer service accounts or org OAuth instead.

3. Generic tools that wrap destructive APIs

run_query that accepts arbitrary SQL. execute_action that passes through to your internal admin API. Models will find the sharp edges.

4. Returning raw upstream payloads to the model

API responses often embed internal IDs, emails, API keys in metadata fields, or cross-customer data in mis-paginated results. Filter responses before they become tool output — agents remember context.

5. Silent scope expansion on token refresh

Your web app added new scopes; refresh tokens picked them up; MCP server inherited broader access without a new consent screen. Version your MCP OAuth client separately.

What the user should see before they authorize

Consent UX for MCP should answer four questions in plain language:

  1. Which tools will this enable? (List them, not “full access”)
  2. Read or write? per tool or per bundle
  3. Which data — one workspace, one org, one environment
  4. How to revoke — link to settings, not buried in ToS

If your upstream IdP supports enterprise-managed provisioning, admins may never see per-user OAuth — they provision once. Your docs should describe both paths: individual OAuth and org-provisioned access.

Storing tokens: your server is now a secrets vault

The moment you hold refresh tokens, you are in the secrets business.

  • Encrypt at rest — no plaintext tokens in SQLite on a laptop
  • Per-user isolation — token A never serves user B’s tool call
  • Audit log — which tool, which upstream call, which user — even minimal logging beats none
  • Never log token values — redact in error traces

For HTTP-hosted MCP, transport security (TLS) is table stakes. stdio-local servers often store tokens in OS keychains — document where yours lives.

Testing authorization like an attacker (and like an agent)

Before launch, run these tests:

  • Connect with minimum-scope test account — can any tool exceed that scope?
  • Prompt the agent to “delete everything” / “export all customers” — do write tools refuse or escalate?
  • Revoke token upstream — does your server fail gracefully on next tool call?
  • Expired refresh — clear error message to user, not silent failure

Agents are not malicious; they are over-eager. Test for eagerness.

Builder checklist — copy into your runbook

  • ☐ Separate OAuth client (or scope bundle) for MCP vs web dashboard
  • ☐ Per-tool scope mapping documented
  • ☐ Read tools shipped before write tools
  • ☐ No generic pass-through tools to admin APIs
  • ☐ Tool output filtered — no raw upstream leakage
  • ☐ Token encryption, revocation, and offboarding path defined
  • ☐ Enterprise-managed auth on roadmap if you sell to teams
  • ☐ Consent screen lists tools and data boundary explicitly

What’s next in MCP Builders

Quick answers

Should we use the same OAuth app as our web product?

Only if scopes are identical and tight. Usually: separate MCP client with narrower scopes.

Are personal API keys ever OK?

For solo local dev — yes, with loud warnings. For team or production MCP — no. Use OAuth or service accounts.

Does enterprise-managed auth replace OAuth for builders?

It changes who provisions access — admins via IdP, not each user clicking Allow. You still implement the auth extension on your server. Chapter 3 covers provider-side work.

We already shipped wide scopes. Now what?

Ship a v2 MCP client with reduced tools, migrate users, deprecate the overbroad client with a deadline. Do not wait for an incident.

Final thought

Users think they are connecting an integration. Agents experience it as delegated authority.

Your job as a builder is to make that delegation visible, minimal, revocable, and boring to audit. The teams that get adopted at scale — and listed in directories like Influzer.ai — will be the ones security can say yes to without a six-week review.

Narrow the scopes. Split read and write. Assume the agent runs at 2 a.m. If you have not built tools yet, start with Chapter 1.