MCP Authentication
The Hooklistener MCP server supports two authentication methods: OAuth 2.0 (recommended) and API keys (legacy).
OAuth 2.0 (recommended)
OAuth 2.0 with PKCE is the recommended way to authenticate with the MCP server. Most MCP clients handle the OAuth flow automatically — you just add the server and the client takes care of the rest.
How it works
- Your MCP client connects to
https://app.hooklistener.com/api/mcp - The server responds with a
401and aWWW-Authenticateheader pointing to the OAuth metadata - The client discovers the authorization server via
/.well-known/oauth-authorization-server - The client registers itself and initiates an authorization flow
- A browser window opens where you sign in and approve access
- The client receives an access token and uses it for subsequent requests
This all happens automatically in clients that support OAuth 2.0 (like Claude Code). You don't need to manage tokens manually.
Token lifetimes
| Token | Lifetime |
|---|---|
| Access token | 1 hour |
| Refresh token | 30 days |
| Authorization code | 10 minutes |
Access tokens are automatically refreshed by the client when they expire, using the refresh token.
Security features
- PKCE required — all authorization flows use Proof Key for Code Exchange (S256 method)
- Token rotation — refresh tokens are rotated on each use
- Revocation support — tokens can be revoked at any time
- No secrets for public clients — native/CLI apps don't need a client secret
OAuth endpoints
| Endpoint | Description |
|---|---|
GET /.well-known/oauth-authorization-server | Authorization server metadata (discovery) |
GET /.well-known/oauth-protected-resource | Protected resource metadata |
POST /oauth/register | Dynamic client registration |
GET /oauth/authorize | Authorization request |
POST /oauth/token | Token exchange and refresh |
POST /oauth/revoke | Token revocation |
Manual OAuth flow
If you're building a custom MCP client, here's the OAuth 2.0 Authorization Code flow with PKCE:
1. Discover the authorization server
curl https://app.hooklistener.com/.well-known/oauth-authorization-server
2. Register your client
curl -X POST https://app.hooklistener.com/oauth/register \
-H "Content-Type: application/json" \
-d '{
"client_name": "My MCP Client",
"redirect_uris": ["http://localhost:8080/callback"],
"application_type": "native",
"token_endpoint_auth_method": "none"
}'
3. Generate PKCE parameters
Generate a random code_verifier (43-128 characters) and compute the code_challenge as the Base64-URL-encoded SHA-256 hash of the verifier.
4. Authorize
Open in a browser:
https://app.hooklistener.com/oauth/authorize?
response_type=code&
client_id=<client_id>&
redirect_uri=http://localhost:8080/callback&
code_challenge=<code_challenge>&
code_challenge_method=S256
The user signs in and approves access. The browser redirects to your callback URL with an authorization code.
5. Exchange code for tokens
curl -X POST https://app.hooklistener.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"code": "<authorization_code>",
"redirect_uri": "http://localhost:8080/callback",
"client_id": "<client_id>",
"code_verifier": "<code_verifier>"
}'
Response:
{
"access_token": "<access_token>",
"refresh_token": "<refresh_token>",
"token_type": "Bearer",
"expires_in": 3600
}
6. Use the access token
curl -X POST https://app.hooklistener.com/api/mcp \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
7. Refresh when expired
curl -X POST https://app.hooklistener.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "refresh_token",
"refresh_token": "<refresh_token>",
"client_id": "<client_id>"
}'
8. Revoke a token
curl -X POST https://app.hooklistener.com/oauth/revoke \
-H "Content-Type: application/json" \
-d '{"token": "<access_or_refresh_token>"}'
API keys (legacy)
API key authentication for MCP is deprecated. We recommend migrating to OAuth 2.0 for improved security. API keys will continue to work, but new integrations should use OAuth 2.0.
You can still authenticate using an API key starting with hklst_:
curl -X POST https://app.hooklistener.com/api/mcp \
-H "Authorization: Bearer hklst_your_api_key" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
See API Keys for how to create and manage keys.
Migrating from API keys to OAuth
- Remove the existing MCP server configuration that includes your API key
- Re-add the server without an API key header — your client will initiate the OAuth flow automatically
- Sign in and approve access when the browser window opens
- Revoke the API key if it's no longer needed elsewhere
For Claude Code:
# Remove the old server
claude mcp remove hooklistener
# Add it back without an API key
claude mcp add --transport http hooklistener https://app.hooklistener.com/api/mcp