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 theauth_tokencookie from x.com. Inscripts/lib/bird_x.py, this value is injected into the Bird client viaset_credentials()(lines 29-38) and later passed to subprocess environments through_subprocess_env()(lines 46-53).CT0– Maps to thect0cookie from x.com. This anti-CSRF token accompaniesAUTH_TOKENin 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:
- 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. - Credential Injection – The main entry point in
scripts/last30days.py(lines 40-46) callsbird_x.set_credentials(), which stores the values in a module-level_credentialsdictionary (lines 33-38). - 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. - Authentication Verification – The UI and diagnostic dumps (
--diagnose, implemented inlast30days.pylines 44-76) rely onis_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_TOKENandCT0are present and Node.js 22+ is available. This is the fastest method and requires no external API key. - xAI API – Used when
XAI_API_KEYis 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_TOKENandCT0in~/.config/last30days/.env(global) or.claude/last30days.env(project-local). - Set file permissions to
600to prevent credential leaks. - The
env.pyloader merges configs with priority: shell > project > global (lines 15-31). bird_x.pyinjects 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_KEYwhen 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →