Loading...
Loading...
X/Twitter via xurl CLI: post, search, DM, media, v2 API.
npx skill4agent add nousresearch/hermes-agent xurlxurlxitterxurl~/.xurl~/.xurl~--verbose-vxurl auth status--bearer-token--consumer-key--consumer-secret--access-token--token-secret--client-id--client-secretxurl auth oauth2~/.xurlgo install# Shell script (installs to ~/.local/bin, no sudo, works on Linux + macOS)
curl -fsSL https://raw.githubusercontent.com/xdevplatform/xurl/main/install.sh | bash
# Homebrew (macOS)
brew install --cask xdevplatform/tap/xurl
# npm
npm install -g @xdevplatform/xurl
# Go
go install github.com/xdevplatform/xurl@latestxurl --help
xurl auth statusxurlauth statushttp://localhost:8080/callbackxurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET--appxurl auth oauth2 --app my-appUsernameNotFound/2/users/mexurl auth oauth2 --app my-app YOUR_USERNAME/2/users/mexurl auth default my-appxurl auth status
xurl whoamiCommon pitfall: If you omitfrom--app my-app, the OAuth token is saved to the built-inxurl auth oauth2app profile — which has no client-id or client-secret. Commands will fail with auth errors even though the OAuth flow appeared to succeed. If you hit this, re-rundefaultandxurl auth oauth2 --app my-app.xurl auth default my-app
Docker HOME pitfall: In the official Hermes Docker layout,is/opt/data, but Hermes tool subprocesses useHERMES_HOMEas/opt/data/home. That meansHOMEresolves to~/.xurlfor Hermes-run/opt/data/home/.xurlcommands, notxurl. Run the user setup with the same HOME:/opt/data/.xurlbashHOME=/opt/data/home xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET HOME=/opt/data/home xurl auth oauth2 --app my-app YOUR_USERNAME HOME=/opt/data/home xurl auth default my-app YOUR_USERNAME HOME=/opt/data/home xurl auth statusIfsucceeds butHOME=/opt/data xurl auth statusshows no apps or tokens, Hermes tool calls will not see the credentials.HOME=/opt/data/home xurl auth status
| Action | Command |
|---|---|
| Post | |
| Reply | |
| Quote | |
| Delete a post | |
| Read a post | |
| Search posts | |
| Who am I | |
| Look up a user | |
| Home timeline | |
| Mentions | |
| Like / Unlike | |
| Repost / Undo | |
| Bookmark / Remove | |
| List bookmarks / likes | |
| Follow / Unfollow | |
| Following / Followers | |
| Block / Unblock | |
| Mute / Unmute | |
| Send DM | |
| List DMs | |
| Upload media | |
| Media status | |
| List apps | |
| Remove app | |
| Set default app | |
| Per-request app | |
| Auth status | |
POST_IDhttps://x.com/user/status/1234567890@xurl post "Hello world!"
xurl post "Check this out" --media-id MEDIA_ID
xurl post "Thread pics" --media-id 111 --media-id 222
xurl reply 1234567890 "Great point!"
xurl reply https://x.com/user/status/1234567890 "Agreed!"
xurl reply 1234567890 "Look at this" --media-id MEDIA_ID
xurl quote 1234567890 "Adding my thoughts"
xurl delete 1234567890xurl read 1234567890
xurl read https://x.com/user/status/1234567890
xurl search "golang"
xurl search "from:elonmusk" -n 20
xurl search "#buildinpublic lang:en" -n 15xurl whoami
xurl user elonmusk
xurl user @XDevelopers
xurl timeline -n 25
xurl mentions -n 20xurl like 1234567890
xurl unlike 1234567890
xurl repost 1234567890
xurl unrepost 1234567890
xurl bookmark 1234567890
xurl unbookmark 1234567890
xurl bookmarks -n 20
xurl likes -n 20xurl follow @XDevelopers
xurl unfollow @XDevelopers
xurl following -n 50
xurl followers -n 50
# Another user's graph
xurl following --of elonmusk -n 20
xurl followers --of elonmusk -n 20
xurl block @spammer
xurl unblock @spammer
xurl mute @annoying
xurl unmute @annoyingxurl dm @someuser "Hey, saw your post!"
xurl dms -n 25# Auto-detect type
xurl media upload photo.jpg
xurl media upload video.mp4
# Explicit type/category
xurl media upload --media-type image/jpeg --category tweet_image photo.jpg
# Videos need server-side processing — check status (or poll)
xurl media status MEDIA_ID
xurl media status --wait MEDIA_ID
# Full workflow
xurl media upload meme.png # returns media id
xurl post "lol" --media-id MEDIA_ID# GET
xurl /2/users/me
# POST with JSON body
xurl -X POST /2/tweets -d '{"text":"Hello world!"}'
# DELETE / PUT / PATCH
xurl -X DELETE /2/tweets/1234567890
# Custom headers
xurl -H "Content-Type: application/json" /2/some/endpoint
# Force streaming
xurl -s /2/tweets/search/stream
# Full URLs also work
xurl https://api.x.com/2/users/me| Flag | Short | Description |
|---|---|---|
| Use a specific registered app (overrides default) | |
| Force auth type: | |
| | Which OAuth2 account to use (if multiple exist) |
| | Forbidden in agent sessions — leaks auth headers |
| | Add |
/2/tweets/search/stream/2/tweets/sample/stream/2/tweets/sample10/stream-s{ "data": { "id": "1234567890", "text": "Hello world!" } }{ "errors": [ { "message": "Not authorized", "code": 403 } ] }xurl media upload photo.jpg
xurl post "Check out this photo!" --media-id MEDIA_IDxurl read https://x.com/user/status/1234567890
xurl reply 1234567890 "Here are my thoughts..."xurl search "topic of interest" -n 10
xurl like POST_ID_FROM_RESULTS
xurl reply POST_ID_FROM_RESULTS "Great point!"xurl whoami
xurl mentions -n 20
xurl timeline -n 20xurl auth default prod alice # prod app, alice user
xurl --app staging /2/users/me # one-off against stagingxurl auth oauth2/2/users/mexurl --helpxurl auth statusauth status▸oauth2: (none)xurl auth default <that-app>defaultxurl whoamixurl user @handlexurl search ... -n 3~/.xurl| Symptom | Cause | Fix |
|---|---|---|
| Auth errors after successful OAuth flow | Token saved to | |
| App type set to "Native App" in X dashboard | Change to "Web app, automated app or bot" in User Authentication Settings |
| X not returning username reliably from | Re-run |
| 401 on every request | Token expired or wrong default app | Check |
| X platform enrollment issue | Dashboard → Apps → Manage → Move to "Pay-per-use" package → Production environment |
| $0 balance on X API | Buy credits (min $5) in Developer Console → Billing |
| Default category is | Add |
| Two "Client Secret" values in X dashboard | UI bug — first is actually Client ID | Confirm on the "Keys and tokens" page; ID ends in |
xurl auth oauth2xurl auth default--app-u / --usernamexurl auth default APP USER~/.xurl/opt/data/home/opt/data/home/.xurl