Skip to content

jasonkneen/clawuth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

clawuth

A lightweight X/Twitter client that uses your real browser session tokens to call X's internal GraphQL API. No scraping, no Playwright, no official API keys — just direct HTTP calls.

clawuth tweet "Hello from clawuth!"

What It Is

clawuth makes it easy to interact with X programmatically using the same requests your browser makes. You extract two cookie values from your browser (takes 30 seconds), and clawuth handles all the auth headers, GraphQL wiring, and response parsing.

No dependencies. Node 18+ built-ins only: fetch, fs, path, readline.


60-Second Quickstart

1. Install

git clone https://github.com/yourname/clawuth
cd clawuth
npm link        # makes the `clawuth` command available globally

2. Run setup

clawuth setup

The wizard will:

  1. Tell you to open x.com in your browser
  2. Show you a DevTools snippet to copy your session tokens
  3. Ask for an account name and the pasted JSON
  4. Save everything to ~/.clawuth/accounts.json

3. Tweet!

clawuth tweet "Hello from clawuth! 🚀"

CLI Reference

clawuth <command> [args]
Command Description
setup Interactive account setup wizard
accounts list List all configured accounts
accounts add <name> Add a new account by name
accounts default <name> Set the default account
tweet <text> Post a tweet
tweet <text> --reply <id> Reply to a tweet
like <tweetId> Like a tweet
timeline Show your home timeline (last 10 tweets)
search <query> Search for tweets
whoami Show the current account info

Programmatic API Reference

Setup

import { ClawuthClient } from 'clawuth';

const client = new ClawuthClient();           // uses default account
const client = new ClawuthClient('myacct');   // uses named account

Tweets

// Post a tweet
const tweet = await client.tweet('Hello world!');

// Reply to a tweet
await client.reply('1234567890', 'Great point!');

// Post with options
await client.tweet('Check this out!', {
  replyToId: '1234567890',     // reply to this tweet
  quoteUrl: 'https://x.com/user/status/123',  // quote tweet URL
  mediaIds: ['media_id_1'],    // pre-uploaded media IDs
});

// Delete a tweet
await client.deleteTweet('1234567890');

// Get a single tweet
const tweet = await client.getTweet('1234567890');

Interactions

await client.like('1234567890');
await client.unlike('1234567890');
await client.retweet('1234567890');
await client.unretweet('1234567890');

Timeline

// Home timeline (last 20 tweets)
const { tweets, nextCursor } = await client.timeline({ count: 20 });

// Load more using cursor
const { tweets: more } = await client.timeline({ count: 20, cursor: nextCursor });

// Notifications / mentions
const data = await client.notifications({ count: 20 });
const data = await client.mentions({ count: 20 });

Search

const { tweets, nextCursor } = await client.search('AI agents', {
  count: 20,
  filter: 'Latest',   // 'Latest' | 'Top' | 'People' | 'Photos' | 'Videos'
});

Users

// By screen name (with or without @)
const user = await client.getUser('@myaccount');
const user = await client.getUser('myaccount');

// By numeric ID
const user = await client.getUser('12345678');

// Follow / unfollow
await client.follow('12345678');
await client.unfollow('12345678');

Auth helpers

import { addAccount, listAccounts, setDefault } from 'clawuth';

addAccount('myacct', authToken, ct0, 'myusername');
setDefault('myacct');
const accounts = listAccounts();

Multiple Accounts

You can configure as many accounts as you like:

clawuth accounts add personal
clawuth accounts add work
clawuth accounts list
clawuth accounts default work

Or programmatically:

import { addAccount } from 'clawuth';

addAccount('personal', 'auth_token_1', 'ct0_1', 'myhandle');
addAccount('work', 'auth_token_2', 'ct0_2', 'workhandle');

const client = new ClawuthClient('work');

All accounts are stored in ~/.clawuth/accounts.json.


Token Extraction

Run clawuth setup and follow the prompts — it shows you exactly what to paste in DevTools.

For manual extraction, see scripts/extract-tokens.js for detailed instructions, including the manual cookie extraction method.

⚠️ Token Expiry

Tokens expire when you log out of x.com. If you see a 401 Auth error, your tokens have expired. Re-run clawuth setup (or clawuth accounts add <name>) to refresh them.

To avoid expiry: stay logged in to x.com in your browser. Tokens are session-based and tied to your browser login.


Config File

~/.clawuth/accounts.json looks like:

{
  "__default": "myaccount",
  "myaccount": {
    "name": "myaccount",
    "username": "myaccount",
    "authToken": "...",
    "ct0": "...",
    "addedAt": "2024-01-01T00:00:00.000Z"
  }
}

OpenClaw Channel Plugin

clawuth ships a companion OpenClaw channel plugin that makes X a proper two-way messaging channel — @mentions and DMs arrive in any OpenClaw surface (Telegram, webchat, etc.), and replies post back to X automatically.

Install

Copy (or symlink) the plugin into your OpenClaw extensions directory:

cp -r plugins/openclaw-x ~/.openclaw/extensions/x

Or point OpenClaw at it via plugins.load.paths in your config.

Configure

Add to your OpenClaw config (~/.openclaw/config.json5):

{
  channels: {
    x: {
      enabled: true,
      accounts: {
        default: {
          authToken: "your_auth_token",   // from DevTools → Application → Cookies → https://x.com
          ct0: "your_ct0",               // same place
          username: "yourusername",       // without @
          watchMentions: true,
          watchDMs: true,
          pollIntervalMs: 60000           // check every 60s
        }
      }
    }
  }
}

Activate

openclaw gateway restart

X is now a channel. @mentions and DMs flow in; replies flow out.


X Spaces

Hosting a Space (AI host with voice)

clawuth can host a live X Space with AI-generated speech. Two TTS backends are supported:

Option A — Local Voice Lab (recommended, offline)

Runs on your machine using Kokoro TTS. No API key needed.

# Start the Voice Lab server (one-time setup)
cd ~/voice-lab && python server.py

# Start a Space
clawuth space start "AI and the Future of Open Source"

Available voices: af_nicole (default), af_sarah, af_bella, bm_george, bm_lewis, and more.

VOICE_LAB_VOICE=af_sarah clawuth space start "My Topic"

Option B — ElevenLabs (cloud, works anywhere)

export ELEVENLABS_API_KEY=your_key_here

clawuth space start "My Topic"

Available voices: Sarah (default), Liam, Charlotte, Brian, Jessica.

ELEVENLABS_VOICE_ID=TX3LPaxmHKxFdv7VOQHJ clawuth space start "My Topic"

Backend selection

clawuth auto-detects which backend to use:

  1. Voice Lab — if server is running at localhost:8002
  2. ElevenLabs — if ELEVENLABS_API_KEY is set
  3. Error if neither is available

Force a specific backend:

TTS_BACKEND=elevenlabs clawuth space start "My Topic"
TTS_BACKEND=voicelab   clawuth space start "My Topic"

Also requires FFmpeg: brew install ffmpeg


Listening to a Space (keyword alerts)

Monitor any public Space for keywords. Transcribes live audio using Deepgram.

clawuth space listen https://x.com/i/spaces/XXXXX \
  --keywords "openclaw,vibeclaw,agent" \
  --transcript \
  --alert

Options:

  • --keywords "a,b,c" — comma-separated keywords to watch for
  • --transcript — print live transcript to stdout
  • --alert — send OpenClaw notification on keyword match (default: on)
  • --webhook <url> — POST to URL on keyword match
  • --anon — join as anonymous listener (no account needed)
  • --account <name> — use a specific account
# Show Space info without joining
clawuth space info https://x.com/i/spaces/XXXXX

Requirements

  • Node.js 22+ (built-in fetch + WebSocket)
  • An active x.com account
  • FFmpeg (for Spaces): brew install ffmpeg
  • For TTS: Voice Lab (local) OR ELEVENLABS_API_KEY (cloud)
  • For transcription: Deepgram API key (DEEPGRAM_API_KEY)
  • No npm dependencies

License

MIT

About

X/Twitter client using browser session tokens — multi-account CLI + Spaces host/listener

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors