JWT Authentication
JWT (JSON Web Token) authentication provides a secure, claims-based mechanism for authenticating requests to your MCP servers. This guide covers how to set up, use, and manage JWT tokens for your MCP servers.
What are JWT Tokens?
JWT (JSON Web Token) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. In MCP Cloud, JWT tokens are used to authenticate API requests to your MCP server, allowing clients to establish their identity and access secured endpoints.
JWT tokens consist of three parts separated by dots (.
):
- Header: Contains metadata about the token, such as the algorithm used for signing
- Payload: Contains claims (statements about the entity making the request)
- Signature: Ensures the token hasn't been altered after it was signed
Setting Up JWT Authentication
Step 1: Generate a JWT Secret
Before creating JWT tokens, you need a secure secret to sign them. MCP Cloud automatically generates a JWT secret for your account when you create your first token. This secret is used to sign all your JWT tokens, ensuring their authenticity.
Step 2: Create a JWT Token
To create a JWT token:
- Navigate to the Servers section in your dashboard
- Click the Settings icon (⚙️) for the server you want to secure
- Select the JWT Auth tab
- Click the Generate Token button
- Provide a description (e.g., "Production API Access")
- Choose token expiration settings:
- Indefinite tokens never expire (good for development)
- Time-limited tokens expire after a set period (recommended for production)
- Click Create Token
Step 3: Associate Token with Your Server
After creating the token, you'll need to associate it with your server:
- In the JWT Auth tab, you'll see your newly created token
- Click the Associate with Server button
- The token is now linked to your server, and JWT authentication is enabled
When JWT authentication is enabled, requests to your server must include a valid JWT token or they will be rejected with a 401 Unauthorized response.
Viewing and Managing Your JWT Tokens
Viewing Token Details
To view the details of your JWT tokens:
- From the Servers list, expand the Advanced section for your server
- If the JWT Auth status shows "Enabled", click View JWT Token
- The token details will be displayed, including:
- Token status (Active/Inactive)
- Token value (truncated for security)
- Creation date
- Last used date
- Usage example
Copying Your Token
To copy a JWT token for use in client applications:
- View the token details as described above
- Click the Copy button (📋) next to the token
- The token will be copied to your clipboard, ready to use in your applications
Revoking Tokens
If a token is compromised or no longer needed:
- Navigate to the Tokens section in your settings
- Find the token you want to revoke
- Click Revoke
- Confirm the action
Once a token is revoked, it can no longer be used for authentication. Any applications using the revoked token will need to be updated with a new token.
Using JWT Tokens in Client Applications
HTTP Headers
To authenticate requests with your JWT token, add an Authorization header:
Authorization: Bearer YOUR_JWT_TOKEN
cURL Example
curl -X POST https://your-server-url.run.app/sse \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{"query": "What's the weather like today?"}'
JavaScript Example
fetch('https://your-server-url.run.app/sse', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
},
body: JSON.stringify({
query: "What's the weather like today?"
})
})
.then(response => response.json())
.then(data => console.log(data));
Python Example
import requests
jwt_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
headers = {
"Authorization": f"Bearer {jwt_token}",
"Content-Type": "application/json"
}
payload = {
"query": "What's the weather like today?"
}
response = requests.post(
"https://your-server-url.run.app/sse",
headers=headers,
json=payload
)
print(response.json())
JWT Token Payload
MCP Cloud JWT tokens include the following standard claims:
sub
: The ID of the user who created the tokenemail
: The email address of the username
: The display name of the usertier
: The subscription tier of the userjti
: A unique identifier for the tokeniat
: The time at which the token was issued (timestamp)exp
: The expiration time (only for time-limited tokens)
Integration with Popular Frameworks
Express.js (Node.js)
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
// Middleware to verify JWT token
function verifyToken(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (!token) return res.status(401).json({ error: 'No token provided' });
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (err) {
return res.status(403).json({ error: 'Invalid token' });
}
}
// Protected route
app.get('/api/protected', verifyToken, (req, res) => {
res.json({ message: 'Protected data', user: req.user });
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Django (Python)
Using Django REST framework with JWT:
# settings.py
INSTALLED_APPS = [
# ...
'rest_framework',
'rest_framework_simplejwt',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
}
# urls.py
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
urlpatterns = [
# ...
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
class ProtectedView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request):
return Response({'message': 'Protected data', 'user': request.user.username})
Security Best Practices
1. Use HTTPS
Always use HTTPS when transmitting JWT tokens to prevent token interception through man-in-the-middle attacks.
2. Set Appropriate Expiration
For production environments, use tokens with an expiration time. Short-lived tokens (e.g., 15-60 minutes) minimize the damage if a token is compromised.
3. Implement Token Refresh Mechanism
For better security with time-limited tokens, implement a token refresh flow:
// Example token refresh logic
async function refreshToken(refreshToken) {
const response = await fetch('https://your-auth-server/refresh', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ refresh_token: refreshToken })
});
const data = await response.json();
return data.access_token;
}
4. Store Tokens Securely
- Backend: Store tokens in secure variables or environment configuration
- Frontend: Store tokens in memory or HTTP-only cookies
- Mobile: Use secure storage mechanisms like Keychain (iOS) or KeyStore (Android)
5. Validate Tokens Properly
When validating tokens, check:
- Signature validity
- Token expiration
- Required claims
- Intended audience
6. Monitor Token Usage
Regularly check your token usage through the MCP Cloud dashboard. Unexpected usage patterns may indicate a compromised token.
Troubleshooting JWT Authentication
Common Issues
Invalid Signature
- Ensure the token was signed with the correct secret
- Check if the token has been tampered with
Expired Token
- Token has passed its expiration time
- Implement token refresh or obtain a new token
Missing or Malformed Authorization Header
- Ensure the Authorization header uses the format:
Bearer YOUR_JWT_TOKEN
- Check for whitespace or encoding issues in the token
- Ensure the Authorization header uses the format:
Wrong Token Format
- Verify the token has all three parts: header, payload, and signature
- Ensure there are no extra characters or spaces
Debugging Tips
Decode the Token
- Use tools like jwt.io to decode and verify your token
- Check the claims are correctly set
Test with cURL
- Use cURL to isolate client-side issues:
curl -v https://your-server-url.run.app/sse \ -H "Authorization: Bearer YOUR_JWT_TOKEN"
- Use cURL to isolate client-side issues:
Check Server Logs
- If you have access to your MCP server logs, check for authentication errors
Verify Token Creation
- Ensure the token was created with the correct parameters and claims