X/Twitter Authentication Setup: Configuring AUTH_TOKEN and CT0 in last30days-skill

Place your auth_token and ct0 cookies from x.com into ~/.config/last30days/.env (or a project-local .claude/last30days.env), restrict file permissions to 600, and the skill will automatically route X searches through the bundled Bird client instead of the xAI API.

The last30days-skill repository supports headless X (Twitter) searches without browser automation by authenticating through session cookies. When configured correctly, the skill bypasses external APIs entirely, using a vendored Node.js-based Bird client to execute queries locally.

What AUTH_TOKEN and CT0 Store

The skill recognizes two specific X session cookies that identify a logged-in account:

  • AUTH_TOKEN – Maps to the auth_token cookie from x.com. In scripts/lib/bird_x.py, this value is injected into the Bird client via set_credentials() (lines 29-38) and later passed to subprocess environments through _subprocess_env() (lines 46-53).
  • CT0 – Maps to the ct0 cookie from x.com. This anti-CSRF token accompanies AUTH_TOKEN in all authenticated requests.

When both values are present, bird_x.is_bird_authenticated() returns the literal string "env AUTH_TOKEN" (lines 85-96), signaling that the skill should prefer the local Bird backend over the xAI API.

Configuration File Locations and Priority

According to scripts/lib/env.py (lines 15-31), the loader merges configuration from three sources with the following precedence: shell environment > project file > global file.

Location File Path Use Case
Global ~/.config/last30days/.env Apply credentials across all projects on your machine
Project-specific <repo-root>/.claude/last30days.env Override global settings for a single repository
Shell N/A (export directly) Temporary testing without persisting to disk

The README provides a ready-to-copy snippet at lines 71-78 for quick global setup.

Step-by-Step AUTH_TOKEN and CT0 Setup

Create the global configuration directory and file, then restrict permissions to prevent credential leaks (the loader warns if permissions are too broad, as implemented in env.py lines 50-61):

mkdir -p ~/.config/last30days
cat > ~/.config/last30days/.env <<'EOF'
AUTH_TOKEN=YOUR_X_AUTH_TOKEN_HERE
CT0=YOUR_X_CT0_COOKIE_HERE
EOF
chmod 600 ~/.config/last30days/.env

Verify that the Bird client detects the injected credentials:

node ~/.claude/skills/last30days/scripts/lib/vendor/bird-search/bird-search.mjs --whoami

Expected output: env AUTH_TOKEN

Run a research query to confirm the setup:

python3 scripts/last30days.py "latest AI trends" --debug

For project-specific overrides, create .claude/last30days.env in your repository root with the same two key-value pairs.

How Credentials Flow Through the System

The authentication pipeline follows a strict sequence defined in the source code:

  1. Configuration Loading – env.get_config() (lines 15-31) reads and merges the global ~/.config/last30days/.env, the project-local .claude/last30days.env, and the current process environment.
  2. Credential Injection – The main entry point in scripts/last30days.py (lines 40-46) calls bird_x.set_credentials(), which stores the values in a module-level _credentials dictionary (lines 33-38).
  3. Subprocess Preparation – When executing searches, _subprocess_env() (lines 46-53) constructs a custom environment dictionary that includes the two cookies, ensuring the Bird Node.js process receives them as environment variables.
  4. Authentication Verification – The UI and diagnostic dumps (--diagnose, implemented in last30days.py lines 44-76) rely on is_bird_authenticated() to display the active auth source.

Backend Selection Logic

As implemented in env.get_missing_keys() (lines 61-66), the skill evaluates available X backends in this order:

  • Bird (cookie auth) – Used when AUTH_TOKEN and CT0 are present and Node.js 22+ is available. This is the fastest method and requires no external API key.
  • xAI API – Used when XAI_API_KEY is defined but cookies are missing.

If both authentication methods are available, Bird wins by default because it operates locally without rate-limiting concerns from external services.

Troubleshooting Common AUTH_TOKEN and CT0 Issues

Symptom Root Cause Resolution
bird_x.is_bird_authenticated() returns None Credentials missing from all config sources, or file permissions are too open (readable by others). Verify .env exists with both variables and run chmod 600 ~/.config/last30days/.env.
Node reports "module not found" Node.js 22+ is not in PATH. Bird requires Node 22 or newer. Install Node 22+ (e.g., brew install node@22).
Skill uses xAI API despite valid cookies Project-level .claude/last30days.env exists but lacks the variables, overriding the global config. Add the two cookie lines to the project env file or delete it to inherit global settings.
Credential leak warning in console .env file has group or world read permissions (e.g., 644). The loader warns at lines 50-61; correct with chmod 600 on the file.

Summary

  • Store AUTH_TOKEN and CT0 in ~/.config/last30days/.env (global) or .claude/last30days.env (project-local).
  • Set file permissions to 600 to prevent credential leaks.
  • The env.py loader merges configs with priority: shell > project > global (lines 15-31).
  • bird_x.py injects cookies into the Bird subprocess via _subprocess_env() (lines 46-53).
  • Bird authentication is verified through is_bird_authenticated() returning "env AUTH_TOKEN".
  • If cookies are absent, the skill automatically falls back to XAI_API_KEY when available.

Frequently Asked Questions

What is the difference between AUTH_TOKEN and CT0?

AUTH_TOKEN is the session identifier from x.com's auth_token cookie, while CT0 is the anti-CSRF token required for authenticated POST requests. Both must be present together in the .env file for the Bird client to function, as the bird_x.py wrapper (lines 29-38) expects both values when building the subprocess environment.

Why does the skill ignore my .env file?

The loader silently skips unreadable files or those with overly permissive permissions. Ensure your .env file has mode 600 (owner read/write only). Additionally, check for a project-local .claude/last30days.env that might be overriding your global configuration with empty values, as project files take precedence over global settings according to env.py lines 15-31.

Can I use both X cookies and XAI_API_KEY together?

Yes. You can define all three variables simultaneously. The skill prioritizes the Bird client (cookies) when AUTH_TOKEN and CT0 are present, as determined by env.get_missing_keys() (lines 61-66). If you want to force the xAI API instead, either remove the cookie variables from your environment or temporarily unset them before running the skill.

How do I verify my X authentication is working correctly?

Run the diagnostic flag: python3 scripts/last30days.py --diagnose. This executes the check in last30days.py (lines 44-76) and prints the authentication source detected by bird_x.is_bird_authenticated(). If you see "env AUTH_TOKEN", the cookies are properly injected. If you see None or a fallback message, review your .env file location and permissions.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →