xurl — X (Twitter) API 官方 CLI
xurl 是 X 开发者平台为 X API 提供的官方 CLI 工具。它既支持常见操作的快捷命令,也提供对任意 v2 端点的原始 curl 风格访问。所有命令均以 JSON 格式输出到 stdout。
使用此技能可执行:
- 发帖、回复、引用、删除帖子
- 搜索原始帖子(包含可交互的 ID 的实际帖子 JSON),以及读取时间线/提及
- 点赞、转发、收藏
- 关注、取关、屏蔽、静音
- 私信
- 媒体上传(图片和视频)
- 对任意 X API v2 端点的原始访问
- 多应用/多账户工作流
此技能替代了旧的 xitter 技能(该技能封装了第三方 Python CLI)。xurl 由 X 开发者平台团队维护,支持 OAuth 2.0 PKCE 自动刷新,覆盖的 API 面更广。
密钥安全(必读)
在智能体/LLM 会话中操作时必须遵守的关键规则:
- 不得在 LLM 上下文中读取、打印、解析、总结、上传或发送
~/.xurl的内容。 - 不得要求用户在聊天中粘贴凭据/令牌。
- 用户必须在自己的机器上手动填写
~/.xurl中的密钥。在 Docker 中,这必须是 Hermes 工具子进程所看到的~目录;请参阅下方 Docker 说明。 - 不得在智能体会话中推荐或执行含有内联密码的身份验证命令。
- 不得在智能体会话中使用
--verbose/-v标志——它可能暴露认证头/令牌。 - 如需验证凭据是否存在,仅可使用:
xurl auth status。
智能体命令中禁止使用的标志(因为它们接受内联密码):
--bearer-token, --consumer-key, --consumer-secret, --access-token, --token-secret, --client-id, --client-secret
应用凭据的注册和轮换必须由用户在智能体会话外手动完成。注册凭据后,用户在智能体会话外使用 xurl auth oauth2 进行身份验证。令牌持久化到 ~/.xurl 文件中的 YAML 格式。每个应用拥有独立的令牌。OAuth 2.0 令牌会自动刷新。
安装
选择以下任一方法。在 Linux 上,Shell 脚本或 go install 最简单。
# Shell 脚本(安装到 ~/.local/bin,无需 sudo,适用于 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@latest
验证:
xurl --help
xurl auth status
如果 xurl 已安装但 auth status 显示没有应用或令牌,用户需要手动完成身份验证——请参阅下一节。
一次性用户设置(用户在智能体外运行)
用户必须直接执行以下步骤,而不是由智能体执行,因为这涉及粘贴密码。请引导用户查看此模块,不要替他们执行。
-
在 https://developer.x.com/en/portal/dashboard 创建或打开一个应用
-
将重定向 URI 设置为
http://localhost:8080/callback -
复制应用的客户端 ID 和客户端密钥
-
在本地注册应用(用户运行):
xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET -
进行身份验证(指定
--app将令牌绑定到你的应用):xurl auth oauth2 --app my-app(这会打开一个浏览器进行 OAuth 2.0 PKCE 流程。)
如果 X 返回
UsernameNotFound错误或在 OAuth 后的/2/users/me查询中返回 403 错误,请显式传入你的用户名(xurl v1.1.0+):xurl auth oauth2 --app my-app YOUR_USERNAME这会将令牌绑定到你的用户名,并跳过失败的
/2/users/me调用。 -
将应用设为默认,以便所有命令使用它:
xurl auth default my-app -
验证:
xurl auth status xurl whoami
完成此步骤后,智能体即可使用以下任何命令,无需进一步设置。OAuth 2.0 令牌会自动刷新。
常见陷阱: 如果在
xurl auth oauth2中省略了--app my-app,OAuth 令牌会保存到内置的default应用配置文件中——该配置文件没有 client-id 或 client-secret。即使 OAuth 流程看似成功,命令也会因认证错误而失败。如果遇到此问题,请重新运行xurl auth oauth2 --app my-app和xurl auth default my-app。
Docker HOME 陷阱: 在官方 Hermes Docker 布局中,
/opt/data是HERMES_HOME,但 Hermes 工具子进程将/opt/data/home视为HOME。这意味着对于 Hermes 运行的xurl命令,~/.xurl解析为/opt/data/home/.xurl,而不是/opt/data/.xurl。请使用相同的 HOME 运行用户设置:HOME=/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 status如果
HOME=/opt/data xurl auth status成功,但HOME=/opt/data/home xurl auth status显示没有应用或令牌,则 Hermes 工具调用将无法看到凭据。
快速参考
| 操作 | 命令 |
|---|---|
| 发帖 | xurl post "Hello world!" |
| 回复 | xurl reply POST_ID "Nice post!" |
| 引用 | xurl quote POST_ID "My take" |
| 删除帖子 | xurl delete POST_ID |
| 读取帖子 | xurl read POST_ID |
| 搜索帖子 | xurl search "QUERY" -n 10 |
| 我是谁 | xurl whoami |
| 查找用户 | xurl user @handle |
| 首页时间线 | xurl timeline -n 20 |
| 提及 | xurl mentions -n 10 |
| 点赞 / 取消点赞 | xurl like POST_ID / xurl unlike POST_ID |
| 转发 / 取消转发 | xurl repost POST_ID / xurl unrepost POST_ID |
| 收藏 / 取消收藏 | xurl bookmark POST_ID / xurl unbookmark POST_ID |
| 列出收藏 / 点赞 | xurl bookmarks -n 10 / xurl likes -n 10 |
| 关注 / 取关 | xurl follow @handle / xurl unfollow @handle |
| 关注中 / 粉丝 | xurl following -n 20 / xurl followers -n 20 |
| 屏蔽 / 取消屏蔽 | xurl block @handle / xurl unblock @handle |
| 静音 / 取消静音 | xurl mute @handle / xurl unmute @handle |
| 发送私信 | xurl dm @handle "message" |
| 列出私信 | xurl dms -n 10 |
| 上传媒体 | xurl media upload path/to/file.mp4 |
| 媒体状态 | xurl media status MEDIA_ID |
| 列出应用 | xurl auth apps list |
| 删除应用 | xurl auth apps remove NAME |
| 设置默认应用 | xurl auth default APP_NAME [USERNAME] |
| 每次请求指定应用 | xurl --app NAME /2/users/me |
| 认证状态 | xurl auth status |
注意:
POST_ID也接受完整的 URL(例如https://x.com/user/status/1234567890)—— xurl 会自动提取 ID。- 用户名可以带或不带开头的
@。
命令详情
发帖
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 1234567890
读取与搜索
xurl search 以经过身份验证的账户查询 X 索引,并返回原始帖子对象——包含 ID、作者、完整文本——因此可以立即对结果进行互动(回复、点赞、转发、引用)。当你需要获取实际帖子而非关于某个话题的摘要答案时,请使用此命令。
xurl 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 15
对于 X 文章,请使用原始 API 模式而非 read 快捷方式。xurl read 期望一个帖子 ID 或帖子 URL;不要在 /2/tweets/... 端点前使用 read。请请求 article 推文字段并从 JSON 响应中提取 data.article.plain_text:
xurl --app APP_NAME '/2/tweets/2057909493250539891?expansions=author_id,attachments.media_keys,referenced_tweets.id&tweet.fields=created_at,lang,public_metrics,context_annotations,entities,possibly_sensitive,conversation_id,in_reply_to_user_id,referenced_tweets,article'
用户、时间线、提及
xurl whoami
xurl user elonmusk
xurl user @XDevelopers
xurl timeline -n 25
xurl mentions -n 20
互动
xurl like 1234567890
xurl unlike 1234567890
xurl repost 1234567890
xurl unrepost 1234567890
xurl bookmark 1234567890
xurl unbookmark 1234567890
xurl bookmarks -n 20
xurl likes -n 20
社交图谱
xurl follow @XDevelopers
xurl unfollow @XDevelopers
xurl following -n 50
xurl followers -n 50
# 其他用户的图谱
xurl following --of elonmusk -n 20
xurl followers --of elonmusk -n 20
xurl block @spammer
xurl unblock @spammer
xurl mute @annoying
xurl unmute @annoying
私信
xurl dm @someuser "Hey, saw your post!"
xurl dms -n 25
媒体上传
# 自动检测类型
xurl media upload photo.jpg
xurl media upload video.mp4
# 显式指定类型/类别
xurl media upload --media-type image/jpeg --category tweet_image photo.jpg
# 视频需要服务器端处理——检查状态(或轮询)
xurl media status MEDIA_ID
xurl media status --wait MEDIA_ID
# 完整工作流
xurl media upload meme.png # 返回媒体 ID
xurl post "lol" --media-id MEDIA_ID
原始 API 访问
快捷方式涵盖常见操作。对于其他操作,请使用原始 curl 风格模式访问任何 X API v2 端点:
# GET
xurl /2/users/me
# POST 带 JSON 请求体
xurl -X POST /2/tweets -d '{"text":"Hello world!"}'
# DELETE / PUT / PATCH
xurl -X DELETE /2/tweets/1234567890
# 自定义请求头
xurl -H "Content-Type: application/json" /2/some/endpoint
# 强制流式传输
xurl -s /2/tweets/search/stream
# 完整 URL 也可以
xurl https://api.x.com/2/users/me
全局标志
| 标志 | 缩写 | 描述 |
|---|---|---|
--app | 使用特定的已注册应用(覆盖默认应用) | |
--auth | 强制指定认证类型:oauth1、oauth2 或 app | |
--username | -u | 要使用的 OAuth2 账户(如果存在多个) |
--verbose | -v | 禁止在智能体会话中使用——会泄漏认证头 |
--trace | -t | 添加 X-B3-Flags: 1 追踪头 |
流式传输
流式端点会自动检测。已知的端点包括:
/2/tweets/search/stream/2/tweets/sample/stream/2/tweets/sample10/stream
使用 -s 强制对任何端点进行流式传输。
输出格式
所有命令均以 JSON 格式输出到 stdout。结构遵循 X API v2:
{ "data": { "id": "1234567890", "text": "Hello world!" } }
错误也是 JSON 格式:
{ "errors": [ { "message": "Not authorized", "code": 403 } ] }
常见工作流
发帖带图片
xurl media upload photo.jpg
xurl post "Check out this photo!" --media-id MEDIA_ID
回复对话
xurl 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 20
多应用(凭据已手动配置)
xurl auth default prod alice # prod 应用,alice 用户
xurl --app staging /2/users/me # 一次性针对 staging 应用
错误处理
- 任何错误均返回非零退出码。
- API 错误仍以 JSON 格式输出到 stdout,因此你可以解析它们。
- 认证错误 → 让用户在智能体会话外重新运行
xurl auth oauth2。 - 需要调用者用户 ID 的命令(如点赞、转发、收藏、关注等)会自动通过
/2/users/me获取。如果认证失败,会显示为认证错误。
智能体工作流
- 验证先决条件:
xurl --help和xurl auth status。 - 使用
xurl search前,确认意图。当任务需要实际的帖子对象、经过身份验证的账户上下文,或需要执行 X 写入操作时,请使用它——这是当用户想要可以互动的帖子(而不仅仅是某个主题的摘要)时的正确接口。 - 检查默认应用是否有凭据。 解析
auth status的输出。默认应用标有▸。如果默认应用显示oauth2: (none),但另一个应用有有效的 oauth2 用户,请告知用户运行xurl auth default <that-app>来修复。这是最常见的设置错误——用户添加了一个自定义名称的应用,但从未将其设为默认,因此 xurl 一直尝试空的default配置文件。 - 如果认证完全缺失,请停止并引导用户查看“一次性用户设置”部分——不要自行尝试注册应用或传递密码。
- 从一次成本较低的读取操作开始(
xurl whoami、xurl user @handle、xurl search ... -n 3)以确认可达性。 - 在任何写入操作(发帖、回复、点赞、转发、私信、关注、屏蔽、删除)之前,确认目标帖子/用户和用户的意图。
- 只有
xurl命令的输出(或原始 X API 响应)才能证明一个改变状态的 X 操作已经发生。切勿基于任何其他来源(搜索结果、摘要或先前的上下文)报告写入操作已完成。 - 直接使用 JSON 输出——每个响应都是结构化数据。
- 切勿将
~/.xurl的内容粘贴回对话中。
故障排除
| 症状 | 原因 | 修复 |
|---|---|---|
| OAuth 流程成功但出现认证错误 | 令牌保存到了 default 应用(没有 client-id/secret),而不是你命名的应用 | xurl auth oauth2 --app my-app 然后 xurl auth default my-app |
OAuth 过程中出现 unauthorized_client | X 控制台中的应用类型设置为“Native App” | 在用户认证设置中更改为“Web app, automated app or bot” |
OAuth 后立即出现 UsernameNotFound 或 403 错误 | X 无法从 /2/users/me 可靠地返回用户名 | 重新运行 xurl auth oauth2 --app my-app YOUR_USERNAME(xurl v1.1.0+)显式传入用户名 |
| 每次请求都返回 401 | 令牌过期或默认应用错误 | 检查 xurl auth status——确认默认应用已有 oauth2 用户。如果没有,运行 xurl auth oauth2 --app my-app |
xurl auth status 显示有凭据,但命令失败(Docker) | Hermes 容器中 HOME 不一致 | 在适当的 HOME 下重新运行身份验证(见上方的 Docker 说明) |
| 媒体上传后帖子没有媒体 | 忘记传递 --media-id | 上传后,将返回的 MEDIA_ID 传递给 xurl post --media-id MEDIA_ID |