Skip to main content
Zoom Server-to-Server OAuth tokens expire after approximately one hour. The Zoom MCP Server handles most token lifecycle events automatically, but you may occasionally see errors that require manual intervention. This page walks you through each error message and the steps to resolve it.
Error message:
❌ MISSING: ZOOM_ACCESS_TOKEN not found in .env file
Your .env file either doesn’t exist or doesn’t contain a ZOOM_ACCESS_TOKEN entry. Fetch a new token to populate it:
1

Verify your .env file exists

Check that .env is present in the project root and contains your Zoom OAuth credentials:
ls -l .env
If the file is missing, copy the example and fill in your credentials:
cp .env.example .env
2

Fetch a new token

Run the token fetch script. It checks for an existing valid token first and only calls the Zoom API if needed:
./scripts/get_zoom_token.sh
Error message:
⏰ EXPIRED: Token expired at [time]
Your token has passed its expiration time. Fetch a fresh one:
./scripts/get_zoom_token.sh
The script checks the existing token before making an API call, so it will only request a new one if the current token is actually expired or missing.
Zoom Server-to-Server OAuth tokens are valid for approximately one hour. The MCP server monitors expiration in the background and automatically refreshes the token when it has less than 5 minutes remaining — no action is required on your part.If you need to manage the token manually, use these commands:
CommandBehavior
./scripts/get_zoom_token.shSmart fetch — only requests a new token if the current one is expired
./scripts/get_zoom_token.sh -fForce fetch — always requests a new token regardless of current validity
./run.sh -fForce fetch a new token, then start the server
Adjust how early the server triggers an automatic refresh by setting ZOOM_AUTO_REFRESH_THRESHOLD in your .env file. The value is in seconds; the default is 300 (5 minutes).
If the token fetch appears to succeed but the new token isn’t reflected in your .env file, check the following:Verify the token was written (the character count should be greater than 600):
grep ZOOM_ACCESS_TOKEN .env | wc -c
Check file permissions to ensure the script can write to .env:
ls -l .env
If you see partial writes or the token appears truncated, ensure the project directory is writable and not locked by a sync service. Check file permissions with ls -l .env.
Symptom: Running check_zoom_token.sh reports the token as expired immediately after you fetched a new one.This usually means your shell environment still holds the old token value. Reload the environment and re-run the check:
source .env && ./scripts/check_zoom_token.sh
You can also verify the token length directly in the file:
grep ZOOM_ACCESS_TOKEN .env | grep -o 'ey[A-Za-z0-9]*' | wc -c
The character count should be greater than 100. A shorter result indicates the token is malformed or truncated.
The server has built-in protection against refresh loops: it enforces a 30-second cooldown between attempts and disables auto-refresh after 3 consecutive failures. When auto-refresh is disabled, you’ll see this message in the terminal:
CRITICAL: Max refresh failures reached. Auto-refresh disabled.
To recover manually, force a new token and update the Claude Desktop config in one step:
./scripts/get_zoom_token.sh -f && bash scripts/update_claude_config.sh
After running this command, restart Claude Desktop so it picks up the new token.
The token validation scripts use Python 3 to parse the JWT expiration claim. If python3 is not available on your system, the scripts fall back to a token refresh for safety, but you’ll see an error.Install Python 3 via Homebrew on macOS:
brew install python3
Alternatively, install jq for JSON parsing:
brew install jq
Verify the installation:
python3 --version