Building MCP Together: Arcade's Contribution to Secure Agent Auth

Building MCP Together: Arcade's Contribution to Secure Agent Auth

Nate Barbettini's avatar
Wils Dawson's avatar
Nate Barbettini & Wils Dawson
JULY 11, 2025
4 MIN READ
MCP
Rays decoration image
Ghost Icon

See URL Mode Elicitation in Action →
Watch our engineer Will Dawson walk through the new MCP proposal that's solving one of the biggest security gaps in AI tool-calling. In 15 minutes, you'll see how agents can finally handle OAuth flows, payment confirmations, and API keys without exposing sensitive data to the LLM.

Watch the technical walkthrough →

Your AI agent needs to search Gmail for that weekly report. You've built an MCP server, the tool definition, everything's wired up perfectly. One problem: there's no secure path in the protocol to get the OAuth 2.0 bearer token your agent needs to call the Gmail API.

This is the gap between MCP's design and production reality. While the protocol handles client-server authentication beautifully, it completely lacks a mechanism for servers to securely obtain third-party credentials. At Arcade.dev, we've been working to fix this fundamental limitation.

The Technical Problem: Credential Flow in Distributed Systems

Let's break down what's actually happening. Your MCP server needs to make authenticated requests to external APIs. But MCP has no secure credential gathering mechanism.

Current workarounds are all security anti-patterns for multi-user production systems:

  • Service account tokens with excessive scopes
  • Credentials hardcoded in server configs
  • Passing tokens through the MCP client (violating the principle of least privilege)
  • Client-side credential storage (hello, token exfiltration risks)

This isn't just bad UX—it's a fundamental security architecture flaw. MCP clients are often untrusted code running on user devices. They're OAuth 2.0 "public clients" that can't securely store secrets. Yet today, that's exactly what developers are forced to do.

Our Engineering Journey: Two Approaches to Secure Auth

PR #475: Adding User Interaction as a Client Capability

Our initial proposal introduced a new client capability for user interactions. The core insight: leverage the browser as a trusted security context, just like OAuth 2.0 has done successfully for 15+ years.

The implementation added a userInteraction capability:

interface UserInteractionRequest {
  method: "userInteraction";
  params: {
    prompt: string;
    url?: string;
    timeout?: number;
  };
}

This allowed servers to redirect users to secure endpoints for credential gathering, keeping sensitive data out of the client execution context entirely. The proposal sparked extensive discussion and security review with 50+ contributors examining attack vectors, CSRF protections, and state management.

But MCP 2025-06-18 shipped with  elicitation, a client capability for dynamically rendering forms and gathering data from the user. Elicitation via forms doesn't work for credentials or sensitive data, but could it be extended to enable secure user interactions?

PR #887: Extending Elicitation with URL Mode

Rather than having two similar-but-different client capabilities, we evolved our approach. PR #887 extends the elicitation framework with a new mode:

interface UrlElicitation {
  id: string;
  mode: "url";
  url: string;
  message: string;
  metadata?: {
    oauth_provider?: string;
    required_scopes?: string[];
    state?: string;
  };
}

This creates clear separation of concerns:

  • Form mode: Client-rendered UI for non-sensitive data (preferences, parameters)
  • URL mode: Direct browser navigation for sensitive flows (OAuth 2.0, payments, WebAuthn, SAML)

The security model is explicit: form elicitation flows data through the client, URL elicitation bypasses the client  entirely. But why does that matter?

Deep Dive: Why URL Elicitation Matters

Proper OAuth 2.0 Implementation

Consider implementing GitHub integration. With URL elicitation, you get proper OAuth 2.0:

# Server initiates OAuth flow
def handle_github_tool_call(params):
    if not has_valid_token(user_id):
        state = generate_secure_state()
        code_verifier = generate_code_verifier()
        
        auth_url = build_oauth_url(
            client_id=GITHUB_CLIENT_ID,
            redirect_uri=CALLBACK_URL,
            state=state,
            code_challenge=hash_verifier(code_verifier),
            scope="repo:read"
        )
        
        raise ElicitationRequired([{
            "id": f"github-auth-{state}",
            "mode": "url",
            "url": auth_url,
            "message": "Authorize GitHub access",
            "metadata": {
                "oauth_provider": "github",
                "required_scopes": ["repo:read"]
            }
        }])

Or, something other than OAuth entirely: a redirect to a payment portal, enterprise IDP login page, etc. The client just opens the URL. For the client, that means no token handling, no state management, no security responsibilities.

Respecting Security Boundaries

URL elicitation enforces proper security boundaries:

  1. Client (untrusted): Facilitates navigation, handles retry logic
  2. Server (trusted): Manages tokens, validates state, enforces scopes
  3. Auth provider (trusted): Handles user authentication, consent

This mirrors established web security patterns. The MCP client never touches credentials, preventing entire classes of attacks:

  • Token exfiltration via compromised clients
  • Scope escalation through client manipulation
  • The "confused deputy" problem

Real Implementation Benefits

From our research into production-ready MCP servers at Arcade:

// Before: Insecure token passing
const result = await mcp.callTool("search_gmail", {
  query: "weekly report",
  token: localStorage.getItem("gmail_token") // 🚨 Security nightmare
});

// After: Secure URL elicitation
try {
  const result = await mcp.callTool("search_gmail", {
    query: "weekly report"
  });
} catch (e) {
  if (e.code === "ELICITATION_REQUIRED") {
    // Client opens URL, user auths, server stores token
    window.open(e.elicitations[0].url);
      // Retry after auth completes
  }
}

This pattern mirrors what client apps already do to interact with services that require redirects for authorization.

Multi-Provider Authentication

Real agents need multiple auth providers. URL elicitation handles this elegantly:

// Server can request multiple authorizations
throw new ElicitationRequired([
  {
    id: "gmail-auth",
    mode: "url",
    url: getGoogleOAuthUrl(),
    message: "Authorize Gmail access"
  },
  {
    id: "slack-auth", 
    mode: "url",
    url: getSlackOAuthUrl(),
    message: "Connect Slack workspace"
  }
]);

What This Enables

With proper authorization, MCP servers are one step closer to being production-ready:

  • Scoped access: Request minimum necessary permissions
  • Token refresh: Handle expiry without user intervention
  • Audit trails: Track what actions were taken with which authorizations
  • Revocation: Users can revoke access anytime through the provider

The technical foundations matter. This is the difference between a demo and production infrastructure.

Implementation Timeline

PR #887 is under active review. For early adopters:

  1. Today: Arcade.dev tools already implement these patterns 
  2. Near term: URL elicitation standardizes the approach
  3. Future: The MCP ecosystem adopts these patterns in both clients and servers

Want to accelerate this?

  • Review PR #887 and stress-test the security model
  • Implement URL elicitation in your MCP server

Without a way to securely interact with the user, MCP is limited to servers that only connect to first-party APIs. By adding a mechanism that respects the security boundaries of the client (inspired by the battle-tested patterns used by OAuth), more powerful and interesting MCP servers are possible. We're excited about the future of MCP, what about you?


The Arcade.dev team has spent years hardening auth at Okta, Stormpath, and Redis. We're applying those lessons to make AI infrastructure production-ready.

Want to build AI agents that actually work in production? While we wait for authorization to land in MCP, Arcade already implements secure auth for 100+ integrations. No bot tokens, no security nightmares—just real OAuth flows that work.

Start building with Arcade → Sign Up.

SHARE THIS POST

RECENT ARTICLES

Rays decoration image
THOUGHT LEADERSHIP

38 Proxy Server AI Revenue Metrics: Market Growth, Data Collection ROI, and Infrastructure Performance

Comprehensive analysis of proxy server market valuations, AI-driven revenue acceleration, and performance benchmarks shaping the future of scoped, user-delegated access The convergence of proxy infrastructure and artificial intelligence represents one of the fastest-growing segments in enterprise technology, with the proxy server market valued at $1 billion in 2024. This growth reflects the need for secure, scoped access pathways as AI systems move from prototypes to real operations. Arcade.de

Rays decoration image
THOUGHT LEADERSHIP

26 Global AI Developer Community Statistics: Adoption Rates, Security Challenges, and Market Momentum

A data-driven analysis of the worldwide AI developer ecosystem, covering adoption patterns, security concerns, productivity gains, and enterprise deployment trends The global AI developer community has reached an inflection point, with 17.4 million developers using or building with AI/ML—a significant jump from 15.5 million in 2023. This massive shift toward AI-powered development creates both unprecedented opportunity and urgent challenges around security, multi-user authorization, and tool r

Rays decoration image
THOUGHT LEADERSHIP

45 API Tool User Growth Trends in AI: Market Expansion, Developer Adoption, and Enterprise Integration

Data-driven analysis of AI API tool adoption patterns, agentic AI growth trajectories, and the infrastructure demands shaping how developers build action-oriented AI systems The shift from conversational AI to action-oriented agents represents a fundamental change in how businesses deploy artificial intelligence. With 7.53 million AI API calls recorded in the past 12 months—a 40% year-over-year increase—developers are building systems that don't just respond but execute tasks across email, cal

Blog CTA Icon

Get early access to Arcade, and start building now.