JUHE API Marketplace
christian-posta avatar
MCP Server

MCP Auth Server

A Model Context Protocol (MCP) server with HTTP transport that implements JWT authentication, allowing secure tool execution and prompt handling with role-based access control.

36
GitHub Stars
8/23/2025
Last Updated
No Configuration
Please check the documentation below.

README Documentation

MCP Auth Step by Step

This repository demonstrates building an MCP (Model Context Protocol) server with HTTP transport and JWT authentication, progressing through iterative steps.

This repo is a companion to the in-depth, step-by-step blog posts on "MCP Authorization". See the following:

Part 4 (late addition to the series): MCP Authorization With Dynamic Client Registration

MCP Authorization Specification Requirements

The table below shows support for OAuth RFCs required by the MCP authorization specification across major identity providers.

RFC Requirements Summary:

  • PKCE: Proof Key for Code Exchange (OAuth 2.1 requirement)
  • RFC 8414: OAuth 2.0 Authorization Server Metadata
  • RFC 7591: OAuth 2.0 Dynamic Client Registration Protocol
  • RFC 8707: Resource Indicators for OAuth 2.0
Identity ProviderPKCERFC 8414RFC 7591RFC 8707
OktaYesYesYesN0
Auth0YesYesKindaNo
KeycloakYesYesYesNo
Ping FederateYesYesYesYes
ForgeRockYesYesYesKinda
Google OAuthYesNoNoNo
Microsoft EntraYesYesNoNo

Overview

The project shows how to build a secure MCP server with:

  • FastAPI-based HTTP transport
  • JWT token authentication
  • OAuth 2.0 metadata endpoints
  • Scope-based authorization
  • Role-based access control

Step-by-Step Progression

Step 1: Basic FastAPI Skeleton

  • File: http-transport-steps/src/mcp_http/step1.py
  • What it adds: Basic FastAPI application with health endpoint
  • Key features:
    • FastAPI server setup
    • Basic health check endpoint (/health)
    • Foundation for MCP HTTP transport

Step 2: Basic MCP Request Handling

  • File: http-transport-steps/src/mcp_http/step2.py
  • What it adds: MCP protocol request/response handling
  • Key features:
    • MCP request parsing and validation
    • Basic MCP response structure
    • /mcp endpoint for MCP protocol communication
    • JSON-RPC style request handling

Step 3: MCP Tools and Prompts Definitions

  • File: http-transport-steps/src/mcp_http/step3.py
  • What it adds: MCP tools and prompts without dispatching
  • Key features:
    • Tool definitions (echo, get_time)
    • Prompt definitions (greeting, help)
    • MCP protocol compliance for tools and prompts
    • No actual tool execution yet

Step 4: MCP Tools Dispatching

  • File: http-transport-steps/src/mcp_http/step4.py
  • What it adds: Actual tool execution and prompt handling
  • Key features:
    • Tool dispatching and execution
    • Prompt retrieval and handling
    • Working MCP server with functional tools
    • Error handling for invalid requests

Step 5: Basic JWT Infrastructure

  • File: http-transport-steps/src/mcp_http/step5.py
  • What it adds: JWT public key loading and JWKS endpoint
  • Key features:
    • Public key loading from file
    • JWKS (JSON Web Key Set) endpoint (/.well-known/jwks.json)
    • External token generation script (generate_token.py)
    • JWT infrastructure foundation

Step 6: JWT Token Validation

  • File: http-transport-steps/src/mcp_http/step6.py
  • What it adds: JWT authentication middleware and enforcement
  • Key features:
    • JWT token validation middleware
    • Authentication enforcement on /mcp endpoint
    • User context extraction from tokens
    • Proper error responses for invalid/missing tokens

Step 7: OAuth 2.0 Metadata Endpoints

  • File: http-transport-steps/src/mcp_http/step7.py
  • What it adds: OAuth 2.0 metadata for protected resource and authorization server
  • Key features:
    • /.well-known/oauth-protected-resource endpoint
    • /.well-known/oauth-authorization-server endpoint
    • Enhanced health endpoint with OAuth metadata
    • OAuth metadata in MCP responses

Step 8: Scope-Based Authorization

  • File: http-transport-steps/src/mcp_http/step8.py
  • What it adds: Permission checking and role-based access control
  • Key features:
    • check_permission method for scope validation
    • Role-based access control (admin, user, guest)
    • 403 Forbidden responses for insufficient permissions
    • Scope enforcement for MCP operations

Step 9: Enhanced MCP Integration (Planned)

  • What it will add: User context in responses and authenticated tools
  • Planned features:
    • User context in MCP response headers/metadata
    • Authenticated tools with user-aware behavior
    • Enhanced MCP protocol integration
    • Personalized responses based on user identity

JWT Token Structure

The JWT tokens include:

  • User ID: Unique identifier for the user
  • Scopes: Permissions (e.g., mcp:read, mcp:tools, mcp:prompts)
  • Roles: User roles (e.g., admin, user, guest)
  • Expiration: Token validity period

Testing

Each step includes a corresponding test script (test_stepX.sh) that validates:

  • Basic functionality
  • JWT authentication (steps 5+)
  • Authorization (steps 6+)
  • OAuth metadata (steps 7+)
  • Access control (steps 8+)

Usage

Prerequisites

  1. Install uv: https://docs.astral.sh/uv/getting-started/installation/
  2. Navigate to the http-transport-steps directory

Running Steps with uv

# Run any step using uv run
uv run step1
uv run step2
uv run step3
# ... etc

Running Step 10 with Environment Configuration

Step 10 supports environment-based configuration for Keycloak and MCP server URLs. You can specify an env file (not .env) using the --env flag, or let it default to keycloak_direct.env.

Two example env files are provided:

  • keycloak_direct.env (for direct Keycloak access at localhost:8080)
  • keycloak_proxy.env (for proxy access at localhost:9090)

Example usage:

# Run step 10 with a specific env file (e.g., proxy)
uv run step10 --env keycloak_proxy.env

If the env file or environment variables are missing, the server will fall back to sensible defaults (localhost:8080, etc).

Notes for running step11

  • you will need to run step10 mcp server
  • you will have to allow anonymous client registration:
  • add trusted hosts (check keycloak logs for the right IP)
  • for trusted host policy, you don't need matching on URI
  • allowable scopes for mcp:read, etc and aud mapper
  • then run the step11 client
uv run step11

To run with mcp-inspector

mcp scopes issue: https://github.com/modelcontextprotocol/inspector/issues/587

Token Generation

For steps 5-8 that require JWT authentication, you can generate tokens using the generate_token.py script:

uv run python generate_token.py --username alice --scopes mcp:read,mcp:tools
uv run python generate_token.py --username bob --scopes mcp:read,mcp:prompts
uv run python generate_token.py --username admin --scopes mcp:read,mcp:tools,mcp:prompts
uv run python generate_token.py --username guest --scopes ""

Keycloak Token Generation

To quickly get a token for testing step9/keycloak:

curl -X POST "http://localhost:8080/realms/mcp-realm/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=password" \
  -d "client_id=mcp-test-client" \
  -d "username=mcp-admin" \
  -d "password=admin123" \
  -d "scope=openid profile email mcp:read mcp:tools mcp:prompts" | jq -r '.access_token'

The script will output a JWT token that can be used in the Authorization: Bearer <token> header for authenticated requests.

Dependencies

  • FastAPI
  • PyJWT
  • cryptography
  • uvicorn

The project uses uv for dependency management with pyproject.toml configuration.

Quick Actions

Key Features

Model Context Protocol
Secure Communication
Real-time Updates
Open Source