diff --git a/third_party/x/.cursor-plugin/plugin.json b/third_party/x/.cursor-plugin/plugin.json index 7fa9076c3..19725139c 100644 --- a/third_party/x/.cursor-plugin/plugin.json +++ b/third_party/x/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "x", "displayName": "X", - "version": "2.8.0", + "version": "2.8.1", "minClientVersions": { "cursor": "3.13.0" }, diff --git a/third_party/x/CHANGELOG.md b/third_party/x/CHANGELOG.md index 7e6afd41c..4315c4b35 100644 --- a/third_party/x/CHANGELOG.md +++ b/third_party/x/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this plugin will be documented here. +## 2.8.1 — Stop on UNAUTHORIZED_REQUESTING_USER from add_conversation_keys + +- `UNAUTHORIZED_REQUESTING_USER` from `add_conversation_keys` means the other person can't receive encrypted chats from the owner, almost always because they don't follow the owner. It is final for that conversation for the session: don't re-post, re-prepare keys, or send. Tell the owner the other person has to follow them first, and both accounts need X Chat keys. +- A prepared `add_conversation_keys` body is single-use and must never be saved and re-posted. + ## 2.8.0 — Livestreams - Requested `broadcast.read` and `broadcast.write` so agents can manage the owner's X livestreams on `https://api.x.com/mcp`. diff --git a/third_party/x/skills/x-api-mcp-guide/SKILL.md b/third_party/x/skills/x-api-mcp-guide/SKILL.md index 6401e16df..e4e416b1e 100644 --- a/third_party/x/skills/x-api-mcp-guide/SKILL.md +++ b/third_party/x/skills/x-api-mcp-guide/SKILL.md @@ -261,7 +261,7 @@ Do not tell them to create a Project or App. Do not ask for a Bearer token. Afte > I'll retry in a minute. -400 `invalid-request`: fix params, don't retry unchanged. +400 `invalid-request`: fix params, don't retry unchanged. A prepared `add_conversation_keys` body is single-use and must never be saved and re-posted. 5xx / **503** / **`get_usage_credits` missing while other X tools work**: backoff once or twice. Do not treat it as $0 credits, a missing app, or [error 2](#2-account-not-ready). Other endpoints may still work. Then say: @@ -645,7 +645,7 @@ Do not accept while you are still paging the list. **No conversation key yet** (first message, or only unencrypted messages): self + peer public keys (`public_key` = identity, `key_version` = `public_key_version`) → `session-encrypt` with `prepare` set → MCP `add_conversation_keys` (conversation `id` = thread id from inbox when known) → MCP `send_chat_message` → confirm. -If `add_conversation_keys` returns `UNAUTHORIZED_REQUESTING_USER` or similar: you likely cannot rotate/init keys for that conversation, or the peer is not on XChat — stop and report; do not send ciphertext under an unpublished key. +If `add_conversation_keys` returns `UNAUTHORIZED_REQUESTING_USER`, the other person can't receive encrypted chats from the owner, almost always because they don't follow the owner. This code is final for that conversation for this session: don't re-post, re-prepare keys, or send. Tell the owner the other person has to follow them first, and both accounts need X Chat keys. ### Chat safety