From a64e9ccb318b817419bf2cd6483d7ab6ed1ad92b Mon Sep 17 00:00:00 2001 From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:18:37 -0700 Subject: [PATCH] feat: skip OAuth1 browser flow when access tokens are pre-configured When X_OAUTH_ACCESS_TOKEN and X_OAUTH_ACCESS_TOKEN_SECRET are set in the environment, the server uses them directly instead of opening a browser for the interactive OAuth1 consent flow. This allows the server to run in headless environments like containers and CI. --- README.md | 14 +++++++++++--- server.py | 7 ++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f0c9906..13a6509 100644 --- a/README.md +++ b/README.md @@ -84,9 +84,17 @@ allowlist. ## OAuth1 flow (startup behavior) -On startup, the server opens a browser for OAuth1 consent and waits for the -callback. Tokens are kept in memory only for the lifetime of the server -process. Set `X_OAUTH_PRINT_TOKENS=1` to print tokens, or +On startup, the server needs OAuth1 access tokens to sign requests. + +**Non-interactive mode (headless / CI):** Set `X_OAUTH_ACCESS_TOKEN` and +`X_OAUTH_ACCESS_TOKEN_SECRET` in your `.env`. When both are present, the +server skips the browser flow and uses them directly. + +**Interactive mode (default):** If the access token env vars are empty, the +server opens a browser for OAuth1 consent and waits for the callback. Tokens +are kept in memory only for the lifetime of the server process. + +Set `X_OAUTH_PRINT_TOKENS=1` to print tokens, or `X_OAUTH_PRINT_AUTH_HEADER=1` to print request headers. ## Available tool calls (allowlist-ready) diff --git a/server.py b/server.py index bec2a2e..11002e3 100644 --- a/server.py +++ b/server.py @@ -314,7 +314,12 @@ def build_oauth1_client() -> OAuth1Client: raise RuntimeError( "Missing X_OAUTH_CONSUMER_KEY or X_OAUTH_CONSUMER_SECRET for OAuth1 signing." ) - access_token, access_secret = run_oauth1_flow() + access_token = os.getenv("X_OAUTH_ACCESS_TOKEN", "").strip() + access_secret = os.getenv("X_OAUTH_ACCESS_TOKEN_SECRET", "").strip() + if access_token and access_secret: + OAUTH_LOGGER.info("Using pre-configured OAuth1 access tokens.") + else: + access_token, access_secret = run_oauth1_flow() if is_truthy(os.getenv("X_OAUTH_PRINT_TOKENS", "0")): print("OAuth1 access token:", access_token) print("OAuth1 access token secret:", access_secret)