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)