Native JIT Authorization for Agents via OAuth Challenge/Response and MCP Elicitation

Open
#21 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Feature
Clarity
Needs clarification
Activity status
Quiet

Research direction

Start by reading the linked OAuth First-Party Apps draft, the author's agent-native authorization proposal, and the MCP Elicitation specification. The issue presents a broad design discussion with open questions rather than naming files, tests, or an implementation entry point. Done would require an agreed scope and concrete specification or implementation plan.

Written by the indexing model from the issue text.

Description

enhancement

Author: @embesozzi
Status: Draft
Classification: Discussion / Feature Proposal
Date: 2026-03-19


Abstract

This proposal explores a pattern for enabling Just-In-Time (JIT) authorization in MCP agents without browser redirects, by combining:

  1. OAuth 2.0 First-Party Apps (FiPA): an IETF draft defining a challenge/response authorization protocol for applications trusted by the authorization server operator.
  2. Structured Elicitation: an agent-readable metadata format (following the MCP elicitation/create structure) that binds FiPA challenge steps directly to MCP Elicitation JSON-RPC calls.

The core idea is a binding where OAuth authorization challenges are expressed as MCP elicitation/create calls. This allows MCP clients (agents) to collect user input inline and complete multi-step authentication flows entirely within the agent runtime.

In this model, the MCP Server acts as a trusted first-party client, mediating the authorization flow with the Authorization Server, while the agent serves only as a UI surface for Human-to-Agent (H2A) interaction.


Motivation

Current MCP OAuth 2.1 flows rely on browser redirects for token acquisition. This creates limitations in native agent environments (e.g., CLI, IDE):

  1. No native JIT authorization primitive: Step-up or JIT auth forces users out to a browser, breaking CLI/IDE continuity.
  2. No agent-readable challenge metadata: FiPA defines the wire protocol but not a structured format agent runtimes can map to user prompts.
  3. No binding to MCP Elicitation: There is no defined mapping between OAuth challenge responses and elicitation/create calls.

Core Concepts

First-Party MCP Server

A First-Party MCP Server is an MCP Server that is explicitly registered as a first-party client with the Authorization Server.

  • The Authorization Server trusts the MCP Server to mediate authentication challenges.
  • The agent is not trusted and only acts as a user interaction surface.
  • The trust boundary is therefore between the MCP Server and the Authorization Server, not the agent.

This constraint is required for safely enabling inline authentication flows.


Proposed Binding

Note: The following describes the author's draft proposal (draft-embesozzi-oauth-agent-native-authorization), not a standardized specification. It is presented here to illustrate the concept and invite feedback.

The binding is triggered when the MCP Server, based on its authorization policies, determines that a Just-In-Time (JIT) authorization step is required before executing a sensitive tool. At that point, the MCP Server — acting as the registered first-party FiPA client — initiates an Authorization Challenge Request to the AS on behalf of the current operation.

When an Authorization Server returns an insufficient_authorization error (per FiPA), the proposed extension adds an elicitations array to the response. Each entry maps directly to an MCP elicitation/create call:

AS Challenge Response:

{
  "error": "insufficient_authorization",
  "auth_session": "sess_abc123",
  "elicitations": [
    {
      "mode": "form",
      "message": "Enter the 6-digit code from your Authenticator App.",
      "requestedSchema": {
        "type": "object",
        "properties": {
          "otp": { "type": "string", "minLength": 6, "maxLength": 6 }
        },
        "required": ["otp"]
      }
    }
  ]
}

MCP Server issues elicitation/create to the MCP Client with the same params, collects user input, then responds to the AS:

{ "auth_session": "sess_abc123", "response": { "otp": "847291" } }

Two elicitation modes are supported: form (inline JSON Schema-driven input) and url (out-of-band browser/webview, used as fallback for third-party agents).

H2A Flow
sequenceDiagram
    participant Human
    participant Agent as MCP Client (Agent)
    participant MCP as MCP Server (First-Party FiPA Client)
    participant AS as Authorization Server

    Human->>Agent: Invokes tool request
    Agent->>MCP: tools/call
    MCP->>AS: Authorization Challenge Request
    AS-->>MCP: insufficient_authorization + auth_session + elicitations[]

    loop Each challenge step
        MCP->>Agent: elicitation/create
        Agent->>Human: Native prompt
        Human-->>Agent: Input
        Agent-->>MCP: elicitation result
        MCP->>AS: Challenge response (auth_session + response)
        AS-->>MCP: Next challenge OR authorization_code
    end

    MCP->>AS: Token Request
    AS-->>MCP: Access Token
    MCP->>MCP: Execute tool (Bearer token held by MCP Server)
    MCP-->>Agent: Tool response
    Agent-->>Human: Result

Security Considerations

  • First-party boundary: These flows MUST only be used by first-party MCP Servers. The AS MUST enforce this via client registration metadata, the first-party trust boundary is at the MCP Server, not the agent.
  • Phishing resistance: First-party MCP Servers may invoke native WebAuthn APIs.
  • H2A scope only: This pattern requires a human present to respond. It does not apply to A2A or autonomous agent scenarios.

Working Implementation

A proof-of-concept has been validated with Claude Code and GitHub Copilot CLI.

In the demo:

  • An agent attempts a protected operation
  • The MCP Server triggers a JIT authorization challenge
  • The user completes authentication inline in the CLI
  • The Authorization Server issues an updated token
  • The operation proceeds

https://github.com/user-attachments/assets/c8d1f356-f54b-4187-8cd4-cddd7e53c0b9

Open Questions

  1. Is native JIT authorization for first-party MCP servers in scope for ext-auth, or should it live in the modelcontextprotocol repo? Please let me know where this is best discussed.

  2. Extending MCP Elicitation beyond input collection:
    The current elicitation/create method is designed for collecting user-provided input, either via JSON Schema-driven forms or URL-based flows.
    This proposal raises the question of whether elicitation should also support invoking user authentication actions, not just collecting values.

Specifically, should the elicitation format be extended to include execution hints — read-only metadata that instructs the MCP client to trigger a native platform capability, instead of prompting for typed input?
Examples include:

  • Triggering a passkey / WebAuthn authentication flow
  • Invoking OS-level biometric authentication
  • Using hardware-backed credentials (e.g., security keys)

Here is an example of device-bound passkey (security key) authentication, where Claude Code triggers JIT authorization via client-side hooks.

https://github.com/user-attachments/assets/37dabc85-74ef-42be-a2e0-e2efe9517903


References

Dominant language
MDX
Stars
164
Forks
54
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from modelcontextprotocol/ext-auth

All issues in modelcontextprotocol/ext-auth

Similar issues

More Security issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.