nevzheng opened a new issue, #12530: URL: https://github.com/apache/gravitino/issues/12530
### Version `main branch` ### Describe what's wrong The Gravitino MCP server accepts a Bearer token via `--token` / `GRAVITINO_TOKEN` and freezes it at process start. The token has a TTL set by the identity provider. Once it expires, every MCP tool call that reaches Gravitino returns HTTP 401 and stays 401 until a human pastes a new token and restarts the MCP process. There is no way for the MCP server to obtain or refresh a token itself. Gravitino already validates OAuth JWTs, and the Java/Python clients already perform `client_credentials` against the same IdP. The MCP server is the only client in this flow that cannot fetch or refresh a service token, so long-running MCP sessions (e.g. Cursor) break on token expiry with no self-service recovery. ### Error message and/or stacktrace No crash. Symptom is repeated Gravitino 401s from MCP tool calls after the configured Bearer's TTL elapses: ``` HTTP 401 Unauthorized (from Gravitino on every tool call after token expiry) ``` Recovery today requires manually replacing `--token` / `GRAVITINO_TOKEN` and restarting the MCP process. ### How to reproduce 1. Start the Gravitino MCP server with `--token <jwt>` (or `GRAVITINO_TOKEN=<jwt>`), where the JWT has a short `exp` (e.g. 60–120s). 2. From an MCP client (Cursor stdio, or HTTP without an incoming `Authorization`), call any tool that hits Gravitino. Observe it works until `exp`. 3. Wait past `exp`. Call the same tool again. Gravitino returns 401 and continues to return 401 for every subsequent call. 4. The MCP server never re-fetches or refreshes the token; only a restart with a new `--token` recovers it. ### Additional context Proposed direction (for the PR): give the MCP server an OAuth `client_credentials` service-identity path alongside the existing `--token`. Hop-2 Authorization precedence would be: incoming HTTP `Authorization` (forward as-is) > `--token` / `GRAVITINO_TOKEN` (static, wins over OAuth) > OAuth `client_credentials` (fetched, cached, refreshed) > anonymous. Token POST uses `client_secret_post` (form body), matching the Java/Python clients. Cache with early-expiry skew; fall back to JWT `exp` when the IdP omits `expires_in`; one retry on Gravitino 401. Gravitino remains the authenticator/authorizer; MCP only attaches `Authorization`. No identity provider is added. Nevin Sent from my 🤖 (Cursor) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
