关于 x-mcp
x-mcp 是面向需要操作本人 X 账户的 Agent 技能,通过官方 X MCP 读取数据,并用用户自己的应用和 OAuth 凭据经 REST API 写入。读取与写入分属不同接口,凭据保存在本机。
主要功能
- 01通过 X MCP 搜索帖子、用户和趋势
- 02读取时间线、提及和书签
- 03通过 REST API 发布、回复和删除内容
- 04点赞、转发、关注及发送私信
- 05使用个人应用与 OAuth 凭据
适用场景
- 01搜索并查看本人 X 时间线与提及
- 02用本人账户发布帖子或回复
- 03点赞、转发或收藏帖子
- 04通过 X 发送私信
MCP 相关
使用官方托管 X MCP 提供 24 项读取工具;写入操作不通过 MCP,而是调用 X v2 REST API。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ starchild-ai-agent/ official-skills --skill x-mcp安装后在 Claude Code 中输入/x-mcp确认已加载。
附带文件scripts/oauth_driver.py
详细介绍
X API — MCP(读取)+ REST(写入),BYOK
连接用户自己的 X 开发者应用,让此 Agent 能够:
- 通过官方托管的 X MCP(
https://api.x.com/mcp)进行读取 — 24 个工具 - 通过 X v2 REST API(
https://api.x.com/2/...)进行写入 — 发帖 / 删除 / 点赞 / 转推 / 回复 / 私信
为什么采用 BYOK(而不是共享的 Starchild 应用): X 的写入访问按应用限流
(约整个应用级别的上限),按使用量计费并由应用所有者承担,且 TOS 责任归属于
应用所有者。共享应用 = 单点故障 + 邻居相互抢用 + 计费集中 + 内容审核责任。因此每个用户
自带应用 + OAuth 令牌。令牌只存在于本机(~/.xurl,
符号链接到持久化工作区 — 见步骤 3),
绝不经过代理。
何时使用此技能
当用户希望用自己的账号/应用在 X 上操作时使用:
- “连接我的 X / Twitter 账号,好让你替我发帖”
- “用我的开发者应用设置 X API”、“使用我的 X 开发者密钥”
- “搜索最近的推文 / 读取我的时间线 / 读取提及”(用他们自己的应用)
- “以我的身份在 X 上发帖 / 回复 / 点赞 / 转推 / 私信”
- “收藏这条推文”
不要使用 — 改用正确的替代方案:
- “总结这条推文” / “@user 在发什么” / cashtag 扫描,无需账号
→ 使用
twitter技能(通过 twitterapi.io 的只读抓取,无需 OAuth) - “添加 X / Grok 模型” → 那是
xai-grok-onboarding(聊天模型),无关 - 用户没有 X 开发者应用且不想要 →
twitter技能,或说明 写入需要他们自己的应用
消歧:twitter = 只读、无需设置、任何人的公开推文。x-mcp =
用户自己已认证的账号,可以写入,需要一次性 OAuth 设置。
另见
twitter技能 — 只读 X 抓取(无需账号、无需 OAuth),可获取任何公开推文config/context/references/model-onboarding.md— 如果用户实际指的是聊天 模型(Grok),而非 X 数据 API
预检 — 构建兼容性(开始前检查)
此技能依赖两项平台能力。设置前请确认二者:
- 原生 MCP 客户端(读取所必需)。 starchild-clawd 必须包含
core/mcp/*并从 agent.yaml 读取defaults.mcp_servers。快速检查:运行/mcp— 如果返回状态块,则客户端存在。如果/mcp未知或 报错,则运行的构建早于 MCP 支持 → 通过 MCP 的读取将不可用。REST 写入路径(xurl)仍然可用;或更新平台镜像。 - 逐轮热重载(自动刷新令牌所必需)。 需要它以便
~2h 的令牌轮换自动重连(步骤 7)。没有它的构建仍可工作,
但每次刷新后需要手动
/mcp reload— 已在 步骤 7 中记录为回退方案。没有干净的运行时探测手段;假设当前构建 具备它,将“MCP 在刷新后约 2h 静默失效,只有/mcp reload能救活它”视为 该构建缺少逐轮钩子的信号。
如果两项 MCP 能力都不存在,而用户只需要读取公开推文,
请在此停止并改用 twitter 技能 — 它不需要任何构建支持。
读取 vs 写入 — 两个独立的系统
| 能力 | 通道 | 已验证 |
|---|---|---|
| 搜索帖子/用户/新闻、时间线、提及、趋势、书签 | MCP(24 个工具) | 已连接 |
| 发帖 / 删除 / 回复 / 点赞 / 转推 / 关注 / 私信 | REST /2/...(不在 MCP 中) | 发帖+删除已测试 |
MCP 的 tools/list 只返回 24 个读取/书签工具。写入端点是一个
独立的 REST API,文档在 docs.x.com — 它们无法通过
MCP 发现。它们列在本技能下文。
STEP 1 — 用户在 X 门户中创建 OAuth 2.0 凭据(手动;X 没有用于此操作的 API)
X 没有提供用于创建/配置应用的 API。这些步骤在 Web 门户中无法避免地需要手动完成。务必做到可精确复制粘贴。
- 前往 developer.x.com → 创建/打开一个应用。
- 默认显示的密钥(API Key / API Secret / Bearer Token)是 OAuth 1.0a —— 不是我们要用的。
- 应用 Settings 标签页 → User authentication settings → Set up。严格按如下填写:
- App permissions: Read and write(如果用户需要私信,则加上 DM)
- Type of App: Web App, Automated App or Bot → Confidential client(只有这个才会生成 Client Secret;Native/Public 不会生成)
- Callback URI / Redirect URL:
http://localhost:8080/callback(必须与 xurl 的监听器逐字节一致) - Website URL:
https://iamstarchild.com(纯粹用于展示的元数据;不参与认证;不要求唯一 —— 每个用户都可以使用相同的值,没有任何技术影响)
- Save → X 会仅显示一次 Client ID + Client Secret。Secret 只显示一次;请立即复制。
这两个 URL 实际控制什么(以便你能回答用户)
- Callback URI = X 返回 OAuth 授权码的位置。xurl 会在
localhost:8080上启动一个本地监听器;授权码在用户自己的机器上从浏览器流向 xurl,绝不会经过任何外部服务器。两边必须完全一致,否则 X 会返回redirect_uri_mismatch。 - Website URL = 仅用于展示的元数据。不属于认证的一部分,也不校验唯一性。所有用户都可以安全地将其设置为
https://iamstarchild.com。
STEP 2 — 安全地收集凭据
request_env_input(绝不要在聊天中索要密钥):
X_OAUTH_CLIENT_ID— X App Client ID(OAuth 2.0)X_OAUTH_CLIENT_SECRET— X App Client Secret(OAuth 2.0)
提醒用户:这是 OAuth 2.0 密钥对(在启用 User authentication settings + Confidential 之后),不是 API Key/Secret(1.0a),也不是 Bearer Token。
STEP 3 — 安装 xurl + 持久化凭据存储 + 注册应用
⚠️ 持久化是必需的,而不是可选的。 xurl 将应用注册和 OAuth token 两者都保存在 ~/.xurl(即 /root/.xurl)中。/root 是临时的 —— 每次容器重启都会被清空,因此如果不做这一步,用户会在下次重启时丢失连接(甚至连应用注册也会丢失),并且必须从头重新进行 OAuth。请将真实文件保存在持久化工作区中,并在每次启动时将其符号链接回来。xurl 会通过符号链接写入(已验证),因此每次 xurl 调用都会透明地使用持久化文件 —— 无需为每条命令添加 HOME 前缀。
npm install -g @xdevplatform/xurl # validated v1.2.2
# Persist install + credential store across container restarts (idempotent).
# Append ONCE to workspace/setup.sh (which re-runs at every boot):
cat >> setup.sh <<'SH'
npm install -g @xdevplatform/xurl
# X (xurl) credential store: /root is ephemeral, keep ~/.xurl in the workspace
XURL_STORE=/data/workspace/.config/x-mcp/xurl_store
mkdir -p "$(dirname "$XURL_STORE")"; chmod 700 "$(dirname "$XURL_STORE")" 2>/dev/null || true
if [ -f /root/.xurl ] && [ ! -L /root/.xurl ]; then mv /root/.xurl "$XURL_STORE"; fi
ln -sf "$XURL_STORE" /root/.xurl
SH
# Run it now so the store is live for this session BEFORE registering the app:
XURL_STORE=/data/workspace/.config/x-mcp/xurl_store
mkdir -p "$(dirname "$XURL_STORE")"; chmod 700 "$(dirname "$XURL_STORE")" 2>/dev/null || true
if [ -f /root/.xurl ] && [ ! -L /root/.xurl ]; then mv /root/.xurl "$XURL_STORE"; fi
ln -sf "$XURL_STORE" /root/.xurl
xurl auth apps add starchild-x \
--client-id "$X_OAUTH_CLIENT_ID" \
--client-secret "$X_OAUTH_CLIENT_SECRET" \
--redirect-uri "http://localhost:8080/callback"
xurl auth status # confirm app registered, redirect_uri shows [app config]
ls -la /data/workspace/.config/x-mcp/xurl_store # confirm store lives in workspace
STEP 4 中获得的 OAuth token 会落到同一个持久化文件中,因此一旦连接成功,该连接就能在重启后继续存活。(agent.yaml 的 MCP bearer 是独立的,并且已经位于工作区中;STEP 7 中的刷新任务会让两者保持同步。)
STEP 4 — 无头 OAuth(此机器没有浏览器 → 用户将 URL 粘贴回来)
xurl auth oauth2 --headless 会打印一个授权 URL,然后阻塞在 stdin 上,等待粘贴回来的授权码。该授权码绑定到一个只存在于该进程内存中的 PKCE code_verifier —— 如果进程在用户粘贴回来之前就终止了,该授权码就永远无法被交换。因此整个流程必须从“打印 URL”一直到“交换授权码”全程保持同一个 xurl 进程存活。
持久驱动模式
运行单个 Python 驱动,通过 subprocess.PIPE 保持 xurl 的 stdin 打开,
将授权 URL 写入文件,等待最多约 10 分钟以获取代码文件,然后输入
代码并捕获结果。关键结构:
proc = subprocess.Popen(["xurl","auth","oauth2","--app","starchild-x","--headless"], # no USERNAME (see token-key note)
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=0)
# 1) read stdout until the oauth2/authorize line → write it to /tmp/xurl_auth_url.txt
# 2) poll /tmp/xurl_code_input.txt (up to 600s) for the pasted callback URL/code
# 3) proc.stdin.write(code+"\n"); flush → 4) read result → write /tmp/xurl_oauth_done.json
使用本技能附带的驱动,位于 skills/x-mcp/scripts/oauth_driver.py,
而不是内联重写它——这样可以保持无 USERNAME 启动和 600s
超时的一致性。启动它时要使其能存活超过 180s 的前台限制——将 stdout
重定向到文件,分离运行,不要让前台 bash 阻塞在它上面:
# clean any stale driver/xurl FIRST (see driver rule 1), then:
python3 skills/x-mcp/scripts/oauth_driver.py >/tmp/oauth_driver_console.log 2>&1 &
sleep 8
cat /tmp/xurl_auth_url.txt # the URL THIS live driver just wrote — give the user THIS one
pgrep -f oauth_driver.py >/dev/null && echo "driver alive, waiting for code"
该驱动运行 xurl auth oauth2 --app starchild-x --headless(无 USERNAME 参数),
将授权 URL 捕获到 /tmp/xurl_auth_url.txt,等待最多 600s(约 10 分钟)以获取
/tmp/xurl_code_input.txt,输入代码,并将结果写入
/tmp/xurl_oauth_done.json。
令牌键 = 解析后的 X 账号句柄。 无论是否传入 USERNAME, xurl 都会通过
/2/users/me解析账号,并将令牌存储在解析后的 X 账号句柄下(例如oauth2_tokens['ud_noel']),而不是存储在空字符串键下。请 动态读取该键,而不是硬编码它。在所有读取令牌的地方都使用此辅助函数—— 它期望恰好一个令牌,如果发现多个,它会停止并列出 各账号句柄,以便你确认使用哪个账号或清除过期的令牌:import yaml, os def _xurl_token(app="starchild-x"): d = yaml.safe_load(open(os.path.expanduser("~/.xurl"))) toks = d["apps"][app]["oauth2_tokens"] # {'<handle>': {...}} keys = list(toks) if not keys: raise SystemExit(f"No OAuth token for app '{app}' — run STEP 4 first.") if len(keys) > 1: raise SystemExit( f"Multiple X accounts authorized under '{app}': {keys}. " "Confirm which handle to use (or remove stale tokens) before continuing.") return keys[0], toks[keys[0]]["oauth2"] # (handle, {access_token, refresh_token, expiration_time})
OAuth 驱动规则
- 一次只运行一个驱动。 启动前,按精确 PID 终止任何过期的
xurl auth oauth2/oauth_driverPID,并排除当前 shell。 此处避免使用pkill -f oauth_driver.py——该模式也会匹配清理 命令自身的 shell。使用:SELF=$$ for pat in "xurl auth oauth2" "oauth_driver.py"; do for pid in $(pgrep -f "$pat"); do [ "$pid" != "$SELF" ] && kill "$pid" 2>/dev/null; done done rm -f /tmp/xurl_auth_url.txt /tmp/xurl_code_input.txt /tmp/xurl_oauth_done.json /tmp/xurl_oauth.pid - 只给用户正在运行的驱动刚刚写入的 URL——在此驱动启动后,
从
/tmp/xurl_auth_url.txt读取它。绝不要粘贴来自 更早尝试或聊天历史的 URL。 - 如果你重启了,之前的授权 URL 就失效了。 告诉用户 丢弃它,只使用最新的那个。
- 如果交换失败,验证
state是否匹配:用户粘贴的回调中的state=必须等于正在运行的驱动生成的 URL 中的state=。不 匹配意味着该回调来自更早的授权 URL。
在可见回复中清楚地告诉用户:
- 在任意设备上的浏览器中打开
https://x.com/i/oauth2/authorize?...URL(正在运行的驱动写入的那个)。 - 点击 Authorize app。
- 浏览器会重定向到
http://localhost:8080/callback?state=...&code=...——该 页面将加载失败(它是这个远程机器的 localhost,用户的浏览器无法 访问它)。这是预期情况。代码就在地址栏中。 - 从地址栏复制完整的重定向 URL,并将其粘贴回聊天中。
将其提供给正在等待的驱动:
echo '<full redirected URL with code=>' > /tmp/xurl_code_input.txt
驱动将其交换为 ~/.xurl 中的令牌,并写入 /tmp/xurl_oauth_done.json。
警告 "could not resolve username via /2/users/me" 不是失败——那是下面的
注册陷阱。
第 5 步 — client-not-enrolled 注册门槛
xurl --app starchild-x /2/users/me 返回:
{"reason":"client-not-enrolled","title":"Client Forbidden",
"detail":"...App that is attached to a Project..."}
OAuth 成功了,但该应用缺少 v2 API 访问权限。在门户中修复(手动):
- 免费层级:在 Dashboard 中,你可以直接在免费应用上切换到按用量付费——这就会授予 v2 访问权限。所需的门槛是按用量付费 / 生产注册。按用量付费可能需要绑定一张卡。
- 注册后,无需重新授权——token 会保留。只需重新运行测试即可。传播可能需要一两分钟。
验证:xurl --app starchild-x /2/users/me 必须返回用户对象(id、name、username),而不是 client-forbidden。
第 6 步 — 将 MCP 接入 agent.yaml(原生 MCP 客户端;无需改动 Agent 代码)
starchild-clawd 有一个原生 MCP 客户端(core/mcp/*:stdio / streamable-http / sse + 静态 headers)。在 defaults.mcp_servers: 下添加(或用户的 agent.yaml 中):
defaults:
mcp_servers: # MAPPING keyed by server name (NOT a YAML list)
xmcp:
transport: streamable-http
url: https://api.x.com/mcp
headers:
Authorization: "Bearer <ACCESS_TOKEN_FROM_~/.xurl>"
timeout: 30
mcp_servers 是一个映射(服务名 → 定义),而不是列表。列表形式(- name: xmcp)会被静默忽略(记录日志 must be a mapping, got list)。
然后运行 /mcp 以确认 24 个工具注册为 mcp__xmcp__<tool>。
第 7 步 — Token 过期与自动刷新
OAuth2 访问 token 约 2 小时后过期(offline.access scope 会授予 refresh_token,因此可以续期)。agent.yaml headers 中的 bearer 是静态的——没有任何东西会自动刷新 TOKEN 值。**如果你只是把当前 token 粘贴进 agent.yaml 而从不刷新,MCP 会在约 2 小时后失效。**你必须运行一个刷新循环来重写 bearer。(在当前 clawd 上,用新 bearer 重新连接是自动的——参见下文“当前 clawd 上的自动重载”——但 token 本身仍然必须被刷新并写入。)
用 xurl 刷新,然后在 agent.yaml 中重写 bearer(重新连接是自动的):
# read current access token after xurl refreshes it
xurl --app starchild-x /2/users/me >/dev/null 2>&1 # xurl auto-refreshes when near expiry on use
# read the token via the _xurl_token() helper from STEP 4 (single-token check + handle-keyed lookup)
ACCESS=$(python3 -c "
import yaml, os
d = yaml.safe_load(open(os.path.expanduser('~/.xurl')))
t = d['apps']['starchild-x']['oauth2_tokens']
keys = list(t)
assert len(keys) == 1, f'expected one X account, found {keys} — confirm/clean before refresh'
print(t[keys[0]]['oauth2']['access_token'])
")
# patch agent.yaml header to the fresh token (a small python/yaml rewrite).
# On current clawd that's all — the next chat turn auto-reconnects (see below).
刷新机制
- 机密客户端刷新:
POST https://api.x.com/2/oauth2/token,使用 HTTP Basic auth(base64(client_id:client_secret))和请求体grant_type=refresh_token&refresh_token=<rt>。返回一个新的access_token(expires_in 7200)以及一个新的轮换后的refresh_token。 - refresh_token 每次刷新都会轮换——旧的会被失效。你必须持久化新的 refresh_token(写回
~/.xurl),否则下一次刷新会失败。 - ✅ 优先使用 xurl 自身的按需刷新(
xurl --app starchild-x /2/users/me):xurl 会在临近过期时刷新,并把轮换后的 token 写回~/.xurl本身,通过符号链接(已验证)——持久化保持完好,你无需触碰该文件。 - 🚫 如果你确实要自己写入
~/.xurl,绝不要使用原子重命名写入(tempfile+os.replace/os.rename)。由于~/.xurl是指向持久化工作区存储的符号链接(第 3 步),重命名会用一个位于临时/root中的普通文件替换该符号链接——持久化会悄无声息地失效,token 会在下次重启时消失。(这是 ChatGPT/Grokstore.py使用的标准“安全”模式——对真实文件是正确的,对符号链接则是致命的。)已验证:os.replace会破坏符号链接;原地open(path,"w")和 xurl 都会通过它写入。因此只能原地写入:# safe: follows the symlink, lands in the persistent workspace store with open(os.path.expanduser("~/.xurl"), "w") as f: yaml.safe_dump(data, f)
在当前 clawd 上自动重新加载
当前 starchild-clawd 在每一轮 /chat 和 /chat/stream 的开始时调用 maybe_hot_reload()(受 mtime 门控,只需一次廉价的 stat)。因此,在刷新任务重写 agent.yaml 中的 bearer 之后,下一轮对话就会自动使用新 token 重新连接——用户永远不需要运行 /mcp reload。 MCP 服务配置签名包含排序后的 headers,因此 bearer 变更会被正确归类为重新连接。
因此,刷新任务只需做两件事:
- 刷新 token(Basic auth)并将轮换后的 refresh_token 持久化写入
~/.xurl(就地写入或仅通过 xurl 写入——不要用原子重命名,参见上文符号链接警告), - 将新的 access_token 写入 agent.yaml 的
headers.Authorizationbearer(agent.yaml 已在工作区中,因此在那里用原子写入没问题)。
无需 /mcp reload,无需手动步骤。(计划任务本身无法重新加载连接——任务 run.py 是独立进程,无法访问进程内的 MCP 管理器单例——但也无需如此:每轮钩子会处理重新连接。)
没有每轮热重载的旧版 clawd 构建:如果运行的构建早于每轮 maybe_hot_reload() 调用,则实时连接不会采用新的 bearer,直到有人运行 /mcp reload——在这种情况下,让刷新任务额外触发一次重新加载,或者指示用户在每次约 2 小时的刷新后运行 /mcp reload。
将刷新设置为每约 60–90 分钟执行一次的 scheduled_task(token 有效期约 2 小时):
刷新 token(Basic auth)→ 将轮换后的 refresh_token 持久化到 ~/.xurl → 将新的 access_token 写入 agent.yaml 的 bearer。在当前 clawd 上,这完全自动。
Token 存储路径:~/.xurl → apps.starchild-x.oauth2_tokens['<resolved-handle>'].oauth2.{access_token,refresh_token,expiration_time}。
对应的键是 xurl 从 /2/users/me 解析出的 X handle(例如 'ud_noel'),不是空字符串——通过 STEP 4 中的 _xurl_token() 辅助函数动态读取(通常每个应用一个 token;该辅助函数会标记出现多个 token 的情况,以便你挑选/清理)。
~/.xurl 是指向持久化路径 /data/workspace/.config/x-mcp/xurl_store 的符号链接(在 STEP 3 中设置)——照常读写 ~/.xurl;持久化是透明的。
REST 写入端点(不在 MCP 中——通过 xurl 使用同一 token 调用)
全部使用 OAuth2 bearer 认证。xurl 会自动处理认证和刷新:
| 操作 | 方法 + 端点 | 请求体 / 说明 | 状态 |
|---|---|---|---|
| 发推文 | POST /2/tweets | {"text":"..."} | 已测试 |
| 回复 | POST /2/tweets | {"text":"...","reply":{"in_reply_to_tweet_id":"<id>"}} | 有文档 |
| 引用 | POST /2/tweets | {"text":"...","quote_tweet_id":"<id>"} | 有文档 |
| 删除推文 | DELETE /2/tweets/{id} | — | 已测试 |
| 点赞 | POST /2/users/{user_id}/likes | {"tweet_id":"<id>"} | 有文档 |
| 取消点赞 | DELETE /2/users/{user_id}/likes/{tweet_id} | — | 有文档 |
| 转推 | POST /2/users/{user_id}/retweets | {"tweet_id":"<id>"} | 有文档 |
| 关注 | POST /2/users/{user_id}/following | {"target_user_id":"<id>"} | 有文档 |
| 私信 | POST /2/dm_conversations/with/{participant_id}/messages | {"text":"..."} | 有文档 |
示例(通过 xurl 发帖):
xurl --app starchild-x -X POST /2/tweets -d '{"text":"hello from my agent"}'
点赞/转推的 user_id = 已认证用户从 /2/users/me 获取的 id。
标记为“有文档”的端点来自 docs.x.com,尚未在此处进行完整的往返测试——首次实际使用时请验证并标记为已测试。
24 个 MCP READ 工具(注册为 mcp__xmcp__<tool>)
搜索/新闻:search_posts_all、search_news、get_news、search_users、
get_trends_by_woeid、get_posts_counts_recent。
帖子:get_posts_by_id、get_posts_by_ids、get_posts_liking_users、
get_posts_quoted_posts、get_posts_reposted_by。
用户:get_users_me、get_users_by_id、get_users_by_username、
get_users_by_usernames、get_users_timeline、get_users_posts、
get_users_mentions。
书签(偏写入):get_users_bookmarks、get_users_bookmarks_by_folder_id、
get_users_bookmark_folders、create_users_bookmark、create_users_bookmark_folder、
delete_users_bookmark。
常用参数:max_results、*.fields(逗号分隔列表)、expansions。search_posts_all
接受一个 query(支持 from:、min_faves:、$CASHTAG 等运算符)。
FAQ
- "我只看到一个 OAuth 1.0a 应用 / 没有 Client ID。" 你还没有启用 User authentication settings。在你启用之前,Keys & tokens 只会显示 1.0a。见 STEP 1。
redirect_uri_mismatch。 Portal Callback URI ≠http://localhost:8080/callback。 必须完全一致。- 没有提供 Client Secret。 应用的 Type 是 Native/Public。切换到 Confidential(Web App / Bot)。
- OAuth 成功后出现
client-not-enrolled。 应用缺少 v2 访问权限 → 迁移到 Pay-per-use(STEP 5)。 - 回调页面无法加载。 这是预期行为——它是远程机器的 localhost。授权 码在地址栏中;把完整 URL 粘贴回来。
- MCP 可用,但约 2 小时后停止工作。 访问令牌已过期,agent.yaml 中的 bearer 已
失效。设置重写 bearer 的刷新任务(STEP 7)——
在当前的 clawd 上,下一轮对话会自动重新连接,无需
/mcp reload。 - 我可以通过 MCP 发帖吗? 不可以。写入通过 REST
/2/...进行(见表格)。MCP 仅 支持读取 + 书签。
关键规则
- 绝不要将 access_token 或 refresh_token 回显到聊天中。 它们是
~/.xurl中的 持久凭证。展示配置时,请遮盖 bearer (Bearer S0tHdk…)。令牌绝不会经过代理或进入聊天记录。 - 绝不要在聊天中索要 Client ID / Secret。 始终通过
request_env_input收集(STEP 2)。 - 不要自动轮询 / 催促 OAuth 步骤。 打印授权 URL 后,等待
用户表示已批准并将重定向 URL 粘贴回来。在用户粘贴之前就写入
授权码文件(
/tmp/xurl_code_input.txt)只会让驱动程序 等待空输入。 - 遇到
client-not-enrolled时,不要盲目重试。 这是门户注册门槛 (STEP 5),不是临时错误——重试同样的调用会持续失败。引导 用户迁移到 Pay-per-use,然后重新测试一次。 - 写入是 REST,不是 MCP。 不要寻找
create_postMCP 工具——它不 存在。请使用 REST 表格。 - 令牌每次刷新都会轮换。 始终持久化新的 refresh_token,否则 下次刷新就会失败(STEP 7)。
更新策略(X 发生变化 → 升级此 skill)
当以下任何一项发生变化时,更新 + 升级版本(然后提 PR,绝不要直接推送 main):
- MCP 工具集(新增/重命名/移除工具、schema 变更)→ MINOR
- REST 写入端点(路径/请求体变更)→ MINOR,如果签名破坏则为 MAJOR
- X 门户注册流程(Pay-per-use 的 UI/步骤、认证设置)→ PATCH/MINOR
- xurl CLI 标志/行为 → PATCH/MINOR
独立性(仅 skill,无需更改 agent 代码)
此 skill 需要对 agent 代码不做任何更改。它依赖已是原生功能的 MCP
客户端(core/mcp/*)加上纯配置(agent.yaml 的 mcp_servers)和一个计划
刷新任务——全部由 agent 按照此 skill 编排。唯一的前提是
运行的构建版本包含 MCP 客户端。不使用用户自己的应用进行只读抓取 → 请改用
twitter skill。
已验证:xurl 1.2.2 · MCP 服务 xmcp 1.0.0(协议 2025-06-18)· 24 个工具 ·
access-level read-write-directmessages · 默认重定向 http://localhost:8080/callback。