Hi all!!
I’m building a Streamable HTTP MCP server protected by WorkOS AuthKit MCP auth, and I’m connecting to it from Warp Desktop.
Server URL:
http://localhost:3001/mcp (currently working locally)
WorkOS config:
Dynamic Client Registration: enabled
Client ID Metadata Document: enabled
MCP Resource Indicator: http://localhost:3001/mcp
Redirect URI: warp://mcp/oauth2callback
My MCP server exposes protected resource metadata and an authorization server metadata proxy:
/.well-known/oauth-protected-resource
/.well-known/oauth-protected-resource/mcp
/.well-known/oauth-authorization-server
/.well-known/oauth-authorization-server/mcp
The protected resource metadata returns:
{
"resource": "http://localhost:3001/mcp",
"authorization_servers": ["https://<my-authkit-domain>.authkit.app"],
"scopes_supported": ["openid", "profile", "email"]
}
According to the WorkOS MCP docs, the MCP client should send the configured resource indicator during OAuth, and the access token should have:
aud = http://localhost:3001/mcp
But when Warp finishes OAuth and calls my MCP endpoint, the token has:
aud = client_<workos_client_id>
So strict JWT verification with:
jwtVerify(token, jwks, {
issuer: "https://<my-authkit-domain>.authkit.app",
audience: "http://localhost:3001/mcp",
})
fails with an audience mismatch. Warp then reports:
MCP: preflight connection to MCP server failed:
Transport creation error: Unexpected status code: 401 Unauthorized
The workaround that makes it connect is to allowlist the WorkOS client id as an additional accepted audience:
MCP_ALLOWED_TOKEN_AUDIENCES=client_<workos_client_id>
Then the server accepts both:
http://localhost:3001/mcp
client_<workos_client_id>
My question:
Is Warp expected to request WorkOS MCP access tokens with aud=client_<id> instead of the configured MCP Resource Indicator? Or should Warp be sending the resource=http://localhost:3001/mcp parameter so WorkOS mints a resource-audience token?