Name: Towards AI Legal Name: Towards AI, Inc. Description: Towards AI is the world's leading artificial intelligence (AI) and technology publication. Read by thought-leaders and decision-makers around the world. Phone Number: +1-650-246-9381 Email: pub@towardsai.net
228 Park Avenue South New York, NY 10003 United States
Website: Publisher: https://towardsai.net/#publisher Diversity Policy: https://towardsai.net/about Ethics Policy: https://towardsai.net/about Masthead: https://towardsai.net/about
Name: Towards AI Legal Name: Towards AI, Inc. Description: Towards AI is the world's leading artificial intelligence (AI) and technology publication. Founders: Roberto Iriondo, , Job Title: Co-founder and Advisor Works for: Towards AI, Inc. Follow Roberto: X, LinkedIn, GitHub, Google Scholar, Towards AI Profile, Medium, ML@CMU, FreeCodeCamp, Crunchbase, Bloomberg, Roberto Iriondo, Generative AI Lab, Generative AI Lab VeloxTrend Ultrarix Capital Partners Denis Piffaretti, Job Title: Co-founder Works for: Towards AI, Inc. Louie Peters, Job Title: Co-founder Works for: Towards AI, Inc. Louis-François Bouchard, Job Title: Co-founder Works for: Towards AI, Inc. Cover:
Towards AI Cover
Logo:
Towards AI Logo
Areas Served: Worldwide Alternate Name: Towards AI, Inc. Alternate Name: Towards AI Co. Alternate Name: towards ai Alternate Name: towardsai Alternate Name: towards.ai Alternate Name: tai Alternate Name: toward ai Alternate Name: toward.ai Alternate Name: Towards AI, Inc. Alternate Name: towardsai.net Alternate Name: pub.towardsai.net
5 stars – based on 497 reviews

Frequently Used, Contextual References

TODO: Remember to copy unique IDs whenever it needs used. i.e., URL: 304b2e42315e

Resources

Free: 6-day Agentic AI Engineering Email Guide.
Learnings from Towards AI's hands-on work with real clients.
Mastering Authentication in MCP: An AI Engineer’s Comprehensive Guide
Latest   Machine Learning

Mastering Authentication in MCP: An AI Engineer’s Comprehensive Guide

Last Updated on February 9, 2026 by Editorial Team

Author(s): Neel Shah

Originally published on Towards AI.

Mastering Authentication in MCP: An AI Engineer’s Comprehensive Guide

As an AI engineer working with the Message Control Protocol (MCP), I’ve implemented and evaluated three authentication methods to secure client-server communication: API Key-based, JWT-based with custom implementation, and JWT-based with FastMCP’s built-in authentication. Each method addresses different needs, from simplicity to enterprise-grade security with role-based access control (RBAC). In this blog, I’ll provide an in-depth exploration of these approaches, including technical details, code snippets, use cases, and best practices, drawing from my hands-on experience building and testing these systems.

Understanding Authentication in MCP

The Message Control Protocol (MCP) enables real-time, tool-based interactions between AI agents (MCP clients) and servers, often using Server-Sent Events (SSE) for communication. Authentication ensures that only authorized clients can access tools like TimeTool or weather_tool. The three methods discussed—API Key-based, custom JWT, and FastMCP’s JWT—offer varying levels of security and complexity, catering to different application requirements.

1. API Key-Based Authentication

Overview

API key-based authentication uses a static key in the request headers, offering simplicity but limited security. It’s ideal for quick prototypes or internal tools where ease of implementation is prioritized.

How It Works

  • Client Side: The client sends an x-api-key header (e.g., secretkey) with SSE requests to the server (e.g., http://localhost:8100/sse). The client lists and invokes tools like weather_tool for queries like “What’s the weather in Dubai?”
  • Server Side: The server validates the x-api-key header in a check_auth function, returning a 401 Unauthorized error if invalid. It also supports Basic Auth and Bearer Token for compatibility.
  • Implementation Details: Built with FastAPI and Starlette, the server routes requests to tools after validating the key. Tools like TimeTool and weather_tool fetch time or weather data from external APIs like OpenWeatherMap.

Code Snippet

# Client: Sending API key
headers = {"x-api-key": "secretkey"}
async with sse_client(url="http://localhost:8100/sse", headers=headers) as (in_stream, out_stream):
async with ClientSession(in_stream, out_stream) as session:
info
= await session.initialize()
tools = await session.list_tools()
# Server: Validating API key
def check_auth(request: Request):
api_key = request.headers.get("x-api-key")
if api_key == "secretkey":
return True
raise HTTPException(status_code=401, detail="Unauthorized")

Pros

  • Simplicity: Minimal setup for rapid development.
  • Low Overhead: No token management or cryptographic operations.
  • Compatibility: Works with any HTTP client.

Cons

  • Security Risks: Static keys are vulnerable to leakage (e.g., in logs or client code).
  • No Granularity: Lacks role-based access control (RBAC).
  • Scalability Issues: Managing multiple keys is cumbersome for large systems.

Use Case

Best for internal tools or low-security prototypes, such as a simple weather query service or time lookup tool.

2. JWT-Based Authentication with Custom Implementation

Overview

This method uses JSON Web Tokens (JWT) with a custom token issuance endpoint, providing time-limited, signed tokens for improved security over API keys. It balances security and implementation complexity.

How It Works

  • Client Side: The client sends a POST request to http://localhost:8100/token with a client_id (e.g., test_client) and client_secret (e.g., secret_1234). The returned JWT is included as a Bearer token in the Authorization header for SSE requests.
  • Server Side: The server validates credentials against a mock client store (CLIENTS dictionary), issues a JWT with a 60-minute expiration, and verifies tokens using the HS256 algorithm and a secret key (my_super_secret_key).
  • Implementation Details: The client queries tools like weather_tool to fetch data, and the server enforces token validity, ensuring only authorized clients access tools.

Code Snippet

# Client: Fetching and using JWT
async def get_token():
payload = {"client_id": "test_client", "client_secret": "secret_1234"}
async with aiohttp.ClientSession() as session:
async with session.post("http://localhost:8100/token", json=payload) as resp:
data = await resp.json()
return data["access_token"]

headers = {"Authorization": f"Bearer {await get_token()}"}
async with sse_client(url="http://localhost:8100/sse", headers=headers) as (in_stream, out_stream):
async with ClientSession(in_stream, out_stream) as session:
info = await session.initialize()
# Server: Generating and validating JWT
@app.post("/token")
def generate_token(request: TokenRequest):
if request.client_id in CLIENTS and CLIENTS[request.client_id] == request.client_secret:
payload = {
"sub": request.client_id,
"exp": datetime.datetime.now() + datetime.timedelta(minutes=60)
}
token = jwt.encode(payload, "my_super_secret_key", algorithm="HS256")
return {"access_token": token}

def check_auth(request: Request):
auth = request.headers.get("authorization", "")
if auth.startswith("Bearer "):
token = auth.split(" ", 1)[1]
try:
payload = jwt.decode(token, "my_super_secret_key", algorithms=["HS256"])
return True
except jwt.ExpiredSignatureError:
raise HTTPException(status_code=401, detail="Token expired")

Pros

  • Improved Security: Expiring tokens reduce long-term exposure compared to static keys.
  • Customizable: Payloads can include user-specific data like client IDs or roles.
  • Scalable: Centralized token issuance simplifies client authentication for larger systems.

Cons

  • Complexity: Requires a token endpoint and client store management.
  • Overhead: Token encoding and decoding add slight latency.
  • Limited RBAC: Offers basic access control compared to advanced frameworks.

Use Case

Suitable for secure APIs with moderate complexity, such as authenticated weather or time services, where time-limited access is needed.

3. JWT-Based Authentication with FastMCP’s Built-In Auth

Overview

FastMCP’s BearerAuthProvider leverages RSA-signed JWTs with role-based access control (RBAC), making it ideal for enterprise applications requiring fine-grained permissions and robust security.

How It Works

  • Key Generation: A script (generate_key.py) creates RSA public/private key pairs, stored in mcp_auth/public.pem and mcp_auth/private.pem.
  • Client Side: The client signs a JWT with the private key, including claims like subject (e.g., alice), issuer, audience, and job_role (e.g., Manager). The token is sent in the Authorization header for SSE requests to servers like http://localhost:8001/sse.
  • Server Side: The server validates JWTs using the public key and enforces RBAC, allowing Managers access to approval, inventory, and order servers, while Officers are limited to order. Tools like create_project_task and get_project_tasks are restricted based on roles.
  • Implementation Details: The MCPServerAdapter manages multi-server connections, and safety protocols prompt for user confirmation before data modifications (e.g., creating tasks).

Code Snippet

# Client: Generating RSA-signed JWT
with open("mcp_auth/private.pem", "r") as f:
private_key_pem = f.read()
key_pair = RSAKeyPair(private_key=SecretStr(private_key_pem), public_key=public_key_pem)
token = key_pair.create_token(subject="alice", issuer="https://dev-issuer.com", audience="my-mcp-server", additional_claims={"job_role": "Manager", "id": "123", "name": "Alice"})
headers = {"Authorization": f"Bearer {token}"}

claims = jwt.decode(
token,
public_key_pem,
algorithms=["RS256"],
audience="my-mcp-server",
issuer="https://dev-issuer.com"
)
print('------------------------------')
print(claims)
print('--------------------------------')
role = claims.get("job_role", "")
print(f"Authenticated as {claims['name']} with role {role} with id {claims['id']}")

# Setup allowed servers by role
if role == "Manager":
servers = [
{"url": "http://localhost:8001/sse", "transport": "sse", "headers": headers}, # HR Management
{"url": "http://localhost:8002/sse", "transport": "sse", "headers": headers}, # Project Management
{"url": "http://localhost:8003/sse", "transport": "sse", "headers": headers}, # CRM
]
permitted_server = ['hr_management', 'project_management', 'crm']
non_permitted_server = ['NA']

elif role == "AssistantManager":
servers = [
{"url": "http://localhost:8001/sse", "transport": "sse", "headers": headers}, # HR Management
{"url": "http://localhost:8002/sse", "transport": "sse", "headers": headers}, # Project Management
]
permitted_server = ['hr_management', 'project_management']
non_permitted_server = ['crm']

else:
servers = [{"url": "http://localhost:8001/sse", "transport": "sse", "headers": headers}] # HR Management only
permitted_server = ['hr_management']
non_permitted_server = ['project_management', 'crm']
# Server: Configuring FastMCP
with open("mcp_auth/public.pem", "r") as f:
public_key = f.read()
auth = BearerAuthProvider(public_key=public_key, issuer="https://dev-issuer.com", audience="my-mcp-server")
mcp = FastMCP(name="ProjectManagementMCP", auth=auth)

Pros

  • Robust Security: RSA signatures provide strong cryptographic guarantees.
  • RBAC Support: Fine-grained access control for complex systems.
  • Scalability: Supports multi-server setups with built-in safety prompts for data modifications.
  • Enterprise-Ready: Designed for production-grade applications.

Cons

  • Complexity: Requires key pair management and RBAC configuration.
  • Setup Overhead: Generating and distributing RSA keys adds initial effort.
  • Performance Cost: RSA operations are slower than HS256 or API key checks.

Use Case

Ideal for enterprise systems like project management platforms, where different roles (e.g., Manager, AssistantManager) need specific access to tools and servers.

Comparison of Authentication Methods

Aspect API Key-Based JWT Custom JWT FastMCP Security Low (static key) Medium (expiring tokens) High (RSA, RBAC) Complexity Low Medium High Scalability Limited Good Excellent Access Control None Basic Advanced (RBAC) Use Case Prototypes Secure APIs Enterprise systems

Practical Considerations for AI Engineers

Security Best Practices

  • Secure Storage: Store API keys, JWT secrets, and RSA keys in environment variables or a secure vault (e.g., AWS Secrets Manager).
  • Token Expiration: Use short-lived tokens (e.g., 60 minutes) to limit exposure, with refresh mechanisms for JWTs.
  • HTTPS: Enforce HTTPS for all MCP communication to prevent interception of keys or tokens.
  • Logging: Avoid logging sensitive data; use structured logging for audit trails.

Scalability Tips

  • Centralized Auth: For JWT-based methods, use a dedicated token issuance service to streamline client authentication.
  • Caching: Cache RSA public keys or token validation results to reduce latency.
  • Rate Limiting: Apply rate limits to authentication endpoints to prevent abuse.

Implementation Challenges

  • API Key: Key rotation and revocation are difficult in large systems.
  • JWT Custom: Requires robust token refresh logic and client store management.
  • FastMCP JWT: Complex key management and RBAC policy design can be time-intensive.

Choosing the Right Method

  • API Key-Based: Best for rapid prototyping or internal tools with minimal security needs.
  • JWT Custom: Suitable for secure APIs with moderate complexity, like authenticated weather services.
  • JWT FastMCP: Ideal for enterprise applications requiring RBAC, such as project management systems.

Reference Code

Github link: https://github.com/NeelDevenShah/MCP-Auth-Demo

Conclusion

Selecting the right authentication method for MCP depends on your application’s requirements for security, scalability, and complexity. API key-based authentication offers simplicity but lacks robustness, making it suitable for prototypes. Custom JWT implementation provides a balance of security and flexibility for secure APIs. FastMCP’s RSA-based JWT with RBAC is the gold standard for enterprise-grade systems needing fine-grained access control. By understanding the trade-offs and applying best practices, you can build secure, scalable MCP applications tailored to your project’s needs, from simple tools to complex AI-driven platforms.

Join thousands of data leaders on the AI newsletter. Join over 80,000 subscribers and keep up to date with the latest developments in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming a sponsor.

Published via Towards AI


Towards AI Academy

We Build Enterprise-Grade AI. We'll Teach You to Master It Too.

15 engineers. 100,000+ students. Towards AI Academy teaches what actually survives production.

Start free — no commitment:

6-Day Agentic AI Engineering Email Guide — one practical lesson per day

Agents Architecture Cheatsheet — 3 years of architecture decisions in 6 pages

Our courses:

AI Engineering Certification — 90+ lessons from project selection to deployed product. The most comprehensive practical LLM course out there.

Agent Engineering Course — Hands on with production agent architectures, memory, routing, and eval frameworks — built from real enterprise engagements.

AI for Work — Understand, evaluate, and apply AI for complex work tasks.

Note: Article content contains the views of the contributing authors and not Towards AI.