Skip to main content

Native MCP Elicitation Auth

When an LLM calls a tool that requires an OAuth2-protected API, HasMCP needs to obtain a valid access token on behalf of the user — without ever exposing credentials to the model. Native MCP Elicitation Auth handles this automatically. If a token is missing or has expired, HasMCP pauses execution, sends an OAuth2 authorization URL to the MCP client, waits for the user to authenticate, then resumes the tool call with the fresh token. This is built on the MCP protocol’s elicitation/create mechanism — a standard way for MCP servers to request additional input from a user mid-session.

The Problem

LLMs cannot log in to services. OAuth2 flows require a human to click a link, authenticate with a trusted provider, and grant permissions. At the same time, the LLM session must not be abandoned while waiting — it needs to resume from exactly where it left off once authentication completes.

How It Works

Step 1 — Tool call is intercepted

When the LLM issues a tools/call request, HasMCP checks for a valid OAuth2 access token in the current session. Elicitation is triggered in two cases:
ConditionTrigger
Token is missingNo access token found for this provider in the session
Token is expiredAccess token exists but its expiry time has passed
Token lacks required scopesToken exists but doesn’t cover the scopes the tool needs
API returns 401The upstream API rejected the token mid-call

Step 2 — Elicitation request is sent

HasMCP returns a JSON-RPC error with code -32042 to the MCP client. The error payload contains an elicitations array with a URL-mode entry:
{
  "code": -32042,
  "data": {
    "elicitations": [
      {
        "mode": "url",
        "elicitationId": "<unique-id>",
        "url": "https://hasmcp.com/oauth2/authorize?state=...",
        "message": "Authorization is required to call tool: get-emails"
      }
    ]
  }
}
The MCP client is expected to surface this URL to the user and pause further tool execution.

Step 3 — User authenticates

The authorization URL redirects the user to the external OAuth2 provider (e.g. Google, GitHub, Salesforce). The state parameter in the URL is a short-lived token (3-minute TTL) that encodes the session context — user ID, organization ID, provider ID, server ID, and required scopes. HasMCP uses this to match the callback to the correct in-progress tool call.

Step 4 — Callback and token storage

After the user grants permission, the OAuth2 provider redirects to HasMCP’s callback endpoint. HasMCP:
  1. Validates the state token and extracts session context
  2. Exchanges the authorization code for an access token and optional refresh token
  3. Encrypts and stores the tokens in the session (and optionally in organization-level variables for reuse)
  4. Displays a confirmation page that auto-closes after 3 seconds

Step 5 — Tool call resumes

Once the callback completes, the MCP client retries the original tool call. HasMCP finds the freshly stored token and proceeds with the API request — no manual retry needed from the LLM.

URL Elicitation and the MCP Protocol

The elicitation/create method is a standard part of the MCP specification. HasMCP uses the "mode": "url" variant, which instructs the client to present a URL for the user to visit rather than prompting for typed input. This keeps credentials fully out of the LLM context — the model only sees that a tool call was made; it never sees tokens, passwords, or auth codes. The client responds to the elicitation with one of three actions:
ActionMeaning
acceptUser completed authentication
declineUser chose not to authenticate
cancelAuth was abandoned

Token Lifetime and Re-authentication

After the initial auth, tokens are cached in the session with their expiry time. On each subsequent tool call, HasMCP checks:
  • Is a token present?
  • Has it expired?
  • Does it cover the required scopes?
If any check fails, elicitation is triggered again transparently. The user experience is identical to the first login.

Security Properties

  • Credentials never reach the LLM. The model only sees an opaque URL; all token exchange happens server-side.
  • State tokens are short-lived. The OAuth2 state parameter expires after 3 minutes to prevent replay attacks.
  • State is single-use. After a successful callback, the state is deleted from cache immediately.
  • Tokens are encrypted at rest. Access and refresh tokens are stored using AES encryption before being written to session or organization variables.
  • Scopes are enforced per tool. Each tool declares the OAuth2 scopes it needs. HasMCP will trigger re-authentication if the current token doesn’t cover those scopes.