HS256 with shared secret
Use HS256 when the token issuer and the MCP server share the same symmetric secret. The MCP server validates a Bearer token on every request — suitable for production when you control both sides of authentication.
Video walkthrough
Use this method for private deployments where you issue JWTs yourself. For OAuth/OIDC providers with key rotation, RS256 with JWKS is the better fit.
1. Generate a shared secret
Create a strong random secret. Use the same value in superset_config.py and wherever you sign JWT tokens.
Option A — OpenSSL (recommended):
openssl rand -base64 42
Option B — Python:
python3 -c "import secrets; print(secrets.token_urlsafe(32))"
Copy the output and store it in a password manager or secrets vault. Example output:
K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=
Never commit MCP_JWT_SECRET to git, paste it in chat, or hardcode it in client apps. Treat it like a password.
2. Configure superset_config.py
Enable JWT validation and set a delegated Superset user for tool execution:
MCP_AUTH_ENABLED = True
MCP_DEV_USERNAME = "admin" # Superset user that runs MCP tool calls
MCP_JWT_ALGORITHM = "HS256"
MCP_JWT_SECRET = "K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols="
MCP_JWT_ISSUER = "superset-mcp"
MCP_JWT_AUDIENCE = "superset-mcp-clients"
Replace the example secret with your own generated value. Set the issuer and audience to values you will also use when signing tokens — they must match exactly. MCP_DEV_USERNAME must be an existing Superset username (for example admin).
In Superset 6.1.x, JWT authentication validates the Bearer token at the HTTP transport layer, but tool calls do not yet resolve the Superset user from JWT claims. You must set MCP_DEV_USERNAME so MCP tools can execute — all authenticated requests run as that user.
Per-user JWT identity mapping is fixed on the Superset master branch. Until you upgrade to a release that includes that fix, keep MCP_DEV_USERNAME set even when JWT auth is enabled.
Restart both processes after saving the config:
./run_superset.sh
./run_superset_mcp.sh
3. Generate a JWT for AI clients
The token must be signed with the same secret, algorithm, issuer, and audience. The sub claim must match an existing Superset username (for example admin).
Activate your Superset virtual environment and run:
import datetime
import jwt
SECRET = "K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=" # same as MCP_JWT_SECRET
ISSUER = "superset-mcp"
AUDIENCE = "superset-mcp-clients"
USERNAME = "admin" # must exist in Superset ab_user table
payload = {
"sub": USERNAME,
"iss": ISSUER,
"aud": AUDIENCE,
"exp": datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=24),
}
token = jwt.encode(payload, SECRET, algorithm="HS256")
print(token)
Save as generate_mcp_token.py and run:
source /app/superset/superset_env/bin/activate
python generate_mcp_token.py
Copy the printed token — you will pass it as Authorization: Bearer <token> in your AI client config.
4. Connect an AI client
Pass the token to your AI client using mcp-remote. Remote HTTP endpoints require the --allow-http flag. See Claude or Cursor for full config examples.
If tokens are rejected at the HTTP layer, enable server-side logging:
MCP_JWT_DEBUG_ERRORS = True
Check that iss, aud, and exp in the token match your config and that the token has not expired.
If initialize succeeds but tool calls fail with "No authenticated user found", confirm MCP_DEV_USERNAME is set to a valid Superset user and restart the MCP server.