From cec2a250d2e00855d14ab473d2d794e0fdaeaef9 Mon Sep 17 00:00:00 2001 From: Paul Vann Date: Mon, 24 Aug 2026 13:44:55 -0400 Subject: [PATCH 1/4] Document the X credits endpoint in the MCP guide skill. Agents now fetch GET /2/usage/credits on connect and suggest work that fits the user's dollar balance. Co-authored-by: Cursor --- third_party/x/.cursor-plugin/plugin.json | 2 +- third_party/x/CHANGELOG.md | 5 + third_party/x/skills/x-api-mcp-guide/SKILL.md | 96 +++++++++++++++---- .../x-api-mcp-guide/references/pricing.md | 2 + 4 files changed, 85 insertions(+), 20 deletions(-) diff --git a/third_party/x/.cursor-plugin/plugin.json b/third_party/x/.cursor-plugin/plugin.json index 129505b8..5ca54ee8 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.1.0", + "version": "2.2.0", "minClientVersions": { "cursor": "3.13.0" }, diff --git a/third_party/x/CHANGELOG.md b/third_party/x/CHANGELOG.md index dcde62a2..5254dfe9 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.2.0 — Credit balance on connect + +- Agents fetch `GET /2/usage/credits` on connect, at session start when X calls are needed, and when the user asks what they can do. The capabilities message now includes the dollar balance and 2–3 ideas that fit it. +- Added budget-tier workflows (from $0 through $1,000+) so suggestions scale with remaining credits. If a job would exceed the balance, offer a cheaper alternative and send the user to https://console.x.com. + ## 2.1.0 — X MCP guide skill - Added the X MCP guide skill: tells agents how to handle sign-in, onboarding, and out-of-credits errors with simple user-facing messages, plus session-start, search, pagination, and cost-aware workflow rules. 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 1fb1d089..69e983eb 100644 --- a/third_party/x/skills/x-api-mcp-guide/SKILL.md +++ b/third_party/x/skills/x-api-mcp-guide/SKILL.md @@ -3,19 +3,50 @@ name: X MCP guide description: >- ALWAYS read this when a user connects the X plugin or any X MCP, before using any X connection, and again on any X error. Do not call an X tool until this - file has been read in the current turn. On first connect, send the user the - capabilities message defined here. Estimate the cost of every X call before - making it and confirm with the user before anything expensive. + file has been read in the current turn. On first connect, fetch the credit + balance, send the capabilities message defined here, and suggest work that + fits their balance. Estimate the cost of every X call before making it and + confirm with the user before anything expensive. --- # X MCP guide This plugin uses **X MCP**. The user taps Connect and signs in with X. They are not setting up an API app. -Probe the current user before search, timeline, bookmarks, or news. On a core error, stop. Name the simple issue, then the next step. Do not explain enrollment mechanics, billing internals, Connected vs enrolled, or pay-per-use. Never retry 401 / 403-enrollment / credits-blocked unchanged. Never ask for keys. Never tell them to create an app, Project, or Production env. +Probe the current user and their credit balance before search, timeline, bookmarks, or news. On a core error, stop. Name the simple issue, then the next step. Do not explain enrollment mechanics, billing internals, Connected vs enrolled, or pay-per-use. Never retry 401 / 403-enrollment / credits-blocked unchanged. Never ask for keys. Never tell them to create an app, Project, or Production env. + +## Credit balance + +Call **`get_usage_credits`** (`GET /2/usage/credits`). It is free. + +Response (values are **USD dollars and cents**; `20.0` = $20.00): + +```json +{ + "data": { + "free_balance": 20.0, + "free_grants": [ + { "amount": 10.0, "expires_at": "2026-11-19T02:14:28.000Z" }, + { "amount": 10.0, "expires_at": "2026-11-19T16:02:51.000Z" } + ], + "prepaid_balance": 0.0, + "total_balance": 20.0 + } +} +``` + +Use **`data.total_balance`** only. Cache it as `{credits}`. Quote it to the user in dollars (`$20.00`). Ignore `free_balance`, `free_grants`, and `prepaid_balance` — do not explain them or choose what to spend. + +Fetch it: + +1. **On connect** — before the capabilities message. +2. **When a session starts and X calls are required** — alongside `get_users_me`. +3. **When the user asks what they can do** — ideas, a setup, a budget, “what’s possible,” and similar. + +Do not fetch on every message. If this call hits error 1, 2, or 3, stop and say that error’s line. ## On connect -The first time the user connects X — or on their first X interaction in a session — send this capabilities message once. Adapt the wording to your voice, keep every line of content: +The first time the user connects X — or on their first X interaction in a session — fetch `{credits}`, then send this capabilities message once. Adapt the wording to your voice. Keep every capability bullet. Then state their balance and suggest **2–3** things from the matching [By budget](#by-budget) row (plus a cheaper starter if useful). Do not pitch work above `{credits}`. > You're connected to X. Here's what I can do: > @@ -26,9 +57,15 @@ The first time the user connects X — or on their first X interaction in a sess > - **News & trends** — search X news stories and get trends by location > - **Bookmarks** — list, add, and remove bookmarks, and organize them into folders > -> Requests use credits: you'll need to purchase credits at https://console.x.com for this to work. I'll show you a cost estimate before anything expensive. +> You have about $X.XX in credits. +> +> With that, we could: (2–3 ideas from the matching budget row). +> +> I'll show a cost estimate before anything expensive. Add credits anytime at https://console.x.com. + +If `{credits}` is ~$0, keep the bullets, say they have $0.00, suggest only free lookups, and send them to https://console.x.com — skip “With that, we could.” -Send it once per session, not on every message. If their first message already contains an ask, send this first, then do the ask. +Send it once per session, not on every message. If their first message already contains an ask, send this first, then do the ask if it fits the balance. ## The three errors @@ -62,7 +99,7 @@ Do not retry. Do not search. Do not mention apps, projects, or pay-per-use. If t > You're out of credits. Go to https://console.x.com and add credits, then I'll retry. -Stop. Do not retry. +Stop. Do not retry. Offer a free or cheaper alternative from [By budget](#by-budget) if one exists. If the payload is only `usage-capped` (no enrollment reason): @@ -103,18 +140,16 @@ If `user-not-enrolled` or `client-not-enrolled` is present, that is #2, not this ## Session start -Resolve the current user (`user.fields=id,name,username,description,public_metrics`). +When X calls are required this session, resolve the current user (`user.fields=id,name,username,description,public_metrics`) and fetch `{credits}`. | Result | Next | | ---------------- | ------------------------------------------------------------------------------------ | -| Success | Cache `id` as `{me}`. Do their ask. Prefer `{me}` for timeline, mentions, bookmarks. | +| Success | Cache `id` as `{me}` and `total_balance` as `{credits}`. Do their ask if it fits. Prefer `{me}` for timeline, mentions, bookmarks. | | Error 1, 2, or 3 | Stop. Say that error's line. Do not search. | | 200 + `errors[]` | Keep `data`. | - - ## Cost awareness Every X call can charge the user. Estimate the cost **before** calling. Read [references/pricing.md](references/pricing.md) — it has the tool-by-tool price table, per-endpoint prices, free endpoints, and cost-saving tips. Once per session, fetch live pricing from https://console.x.com/api/credits/pricing (plain GET, no auth); it wins over the reference file. @@ -123,11 +158,11 @@ The live payload: - `eventTypePricing` — price **per resource returned** (each post, user, news story…). - `requestTypePricing` — price **per request** (writes, counts, trends…). -- All prices are **USD dollars**: `0.005` = $0.005 = half a cent. Fractional cents to 3 decimal places are normal. $1.00 = 1,000 credits — that conversion is for your own math; quote costs to the user in dollars only. +- All prices are **USD dollars**: `0.005` = $0.005 = half a cent. Fractional cents to 3 decimal places are normal. $1.00 = 1,000 credits — that conversion is for your own math; quote costs to the user in dollars only. `{credits}` from `/2/usage/credits` is already dollars. Estimate = (resources requested × per-resource price) + per-request price. `max_results` bounds a read: a search with `max_results=100` returning posts + expanded authors can cost ~100 × $0.005 + 100 × $0.01. Each pagination page bills again. Only request expansions you'll use — expanded objects bill too. -**Under ~$0.25:** just do it — don't nag about pennies. Keep `max_results` small (10–25) unless they asked for more. +**Under ~$0.25, and it fits `{credits}`:** just do it — don't nag about pennies. Keep `max_results` small (10–25) unless they asked for more. **Over ~$0.25, or any pagination loop / bulk job:** stop first. Give a one-line estimate and ask: @@ -135,6 +170,8 @@ Estimate = (resources requested × per-resource price) + per-request price. `max Wait for a yes. Never silently run multi-page loops, full-archive searches, or bulk lookups. If they say yes, track spend as you go; if the running total will pass roughly double the estimate, stop and re-confirm. +**Estimate larger than `{credits}`:** do not run it. Offer a cheaper alternative from [By budget](#by-budget) that fits. Tell them this would run them out, and send them to https://console.x.com to add credits. If they top up, re-fetch `{credits}` before retrying. + ## Fields, pagination Request fields. If the tool takes `tweet.fields` or `post.fields`, send `created_at,public_metrics,author_id,lang,conversation_id`. Also `user.fields=created_at,description,public_metrics,verified,location` and `expansions=author_id,referenced_tweets.id`. @@ -166,7 +203,30 @@ Spaces = AND. Recent query max 512 characters; full-archive 1,024. Use `min_like ## Workflows -Current user first. Stop on errors 1–3. +Current user first. Stop on errors 1–3. Tailor suggestions to `{credits}`. + +### By budget + +Pick from the **matching row**, not above it. Larger jobs still need an estimate and a yes. `$0.005`/post, `$0.01`/user, expansions bill too. + + +| `{credits}` | Suggest | +| ----------- | ------- | +| ~$0 | `{me}` (free). Likers of a post (free). Bookmark folders (free). Then: add credits at https://console.x.com. | +| under ~$0.25 | One post from a link. One user by handle. Recent post counts on a topic. | +| ~$0.25–$1 | A small search (10–25 posts). One page of home or mentions. | +| ~$1–$5 | A few targeted searches. News on a topic plus trends for a location. Tidy bookmarks. | +| ~$5–$20 | Compare 2–3 accounts (profile + recent posts). A short research pass: counts, then a couple of search angles. | +| ~$20–$50 | Deeper research: several angles, a handful of accounts, news on the topic. One account’s recent posts across a few pages (confirm). | +| ~$50–$100 | A full-archive slice on one query. A competitive set of ~5–10 accounts. Paginated timelines (confirm). | +| ~$100–$500 | Large archive jobs. Many queries or many accounts. Broad topic monitoring across pages — always confirm. | +| ~$500–$1,000 | Org-scale historical pulls. Multi-query archive. Large comparative studies — confirm each large chunk. | +| $1,000+ | Very large archive / bulk historical. Long-running research. Never silent pagination; confirm every large chunk. | + + +When they ask what they can do, re-fetch `{credits}`, then give 2–3 ideas from the matching row. + +### Common tasks - Home / mentions / my posts: `{me}`, modest `max_results`. Paginate only if asked. - Handle: username → posts. Else user search, then ask. @@ -174,13 +234,11 @@ Current user first. Stop on errors 1–3. - Bookmarks: list `{me}`. Save: parse status id, create bookmark. - One post: parse status id, lookup. - - ## Don't -- Explain deep details (pay-per-use, Connected vs enrolled, billing internals). Do name the simple issue. +- Explain deep details (pay-per-use, Connected vs enrolled, billing internals, free vs prepaid grants). Do name the simple issue. - Say pay-per-use, Project, Production, or "create an app". - Ask for secrets. - Retry 403 or credits-blocked in a loop. +- Pitch or run work above `{credits}`. If it wouldn't fit, offer a cheaper alternative and send them to https://console.x.com. - Run an expensive request (over ~$0.25, pagination loops, bulk lookups) without giving an estimate and getting a yes. - diff --git a/third_party/x/skills/x-api-mcp-guide/references/pricing.md b/third_party/x/skills/x-api-mcp-guide/references/pricing.md index 07852593..f59240b5 100644 --- a/third_party/x/skills/x-api-mcp-guide/references/pricing.md +++ b/third_party/x/skills/x-api-mcp-guide/references/pricing.md @@ -14,6 +14,7 @@ Reference prices for cost estimates. May drift; the live endpoint https://consol | Tool | Wraps | Cost | |---|---|---| | `get_users_me` | `GET /2/users/me` | free | +| `get_usage_credits` | `GET /2/usage/credits` | free | | `get_users_by_id` / `get_users_by_username` / `get_users_by_usernames` / `search_users` | user lookup/search | $0.01/user | | `get_posts_by_id` / `get_posts_by_ids` / `search_posts_all` / `get_posts_quoted_posts` | post lookup/search | $0.005/post | | `get_users_posts` / `get_users_mentions` / `get_users_timeline` / `get_users_bookmarks` | user timelines | $0.005/post ($0.001 own data) | @@ -116,6 +117,7 @@ Reference prices for cost estimates. May drift; the live endpoint https://consol ## Free endpoints (no per-use charge) - `GET /2/users/me` +- `GET /2/usage/credits` (MCP: `get_usage_credits`) - `GET /2/tweets/:id/liking_users` - `GET /2/media` · `GET /2/media/:media_key` - Bookmark folders: `GET /2/users/:id/bookmarks/folders` (and by folder id) · folder create From 29e8468729486e5b47c0e35d72cc18b5d385ba04 Mon Sep 17 00:00:00 2001 From: Paul Vann Date: Tue, 25 Aug 2026 20:32:41 -0400 Subject: [PATCH 2/4] Never tell users to buy X credits before checking their balance. Fetch get_usage_credits before any on-connect copy, and only mention console.x.com when the balance is ~$0 or a job would not fit. Co-authored-by: Cursor --- third_party/x/CHANGELOG.md | 1 + third_party/x/skills/x-api-mcp-guide/SKILL.md | 22 +++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/third_party/x/CHANGELOG.md b/third_party/x/CHANGELOG.md index 5254dfe9..c61ae844 100644 --- a/third_party/x/CHANGELOG.md +++ b/third_party/x/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this plugin will be documented here. - Agents fetch `GET /2/usage/credits` on connect, at session start when X calls are needed, and when the user asks what they can do. The capabilities message now includes the dollar balance and 2–3 ideas that fit it. - Added budget-tier workflows (from $0 through $1,000+) so suggestions scale with remaining credits. If a job would exceed the balance, offer a cheaper alternative and send the user to https://console.x.com. +- Never tell the user to buy credits until after `get_usage_credits` returns. The on-connect message states the balance; console.x.com is only mentioned when the balance is ~$0 or a job would not fit. ## 2.1.0 — X MCP guide skill 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 69e983eb..30f69576 100644 --- a/third_party/x/skills/x-api-mcp-guide/SKILL.md +++ b/third_party/x/skills/x-api-mcp-guide/SKILL.md @@ -3,10 +3,11 @@ name: X MCP guide description: >- ALWAYS read this when a user connects the X plugin or any X MCP, before using any X connection, and again on any X error. Do not call an X tool until this - file has been read in the current turn. On first connect, fetch the credit - balance, send the capabilities message defined here, and suggest work that - fits their balance. Estimate the cost of every X call before making it and - confirm with the user before anything expensive. + file has been read in the current turn. On first connect, fetch get_usage_credits + BEFORE any user-facing text, then send the capabilities message. Never tell the + user to buy credits until that check returns ~$0 or a job would exceed the + balance. Estimate the cost of every X call before making it and confirm with + the user before anything expensive. --- # X MCP guide @@ -14,6 +15,8 @@ This plugin uses **X MCP**. The user taps Connect and signs in with X. They are Probe the current user and their credit balance before search, timeline, bookmarks, or news. On a core error, stop. Name the simple issue, then the next step. Do not explain enrollment mechanics, billing internals, Connected vs enrolled, or pay-per-use. Never retry 401 / 403-enrollment / credits-blocked unchanged. Never ask for keys. Never tell them to create an app, Project, or Production env. +**Never tell the user to buy, purchase, or add credits until `get_usage_credits` has returned and `{credits}` is ~$0 or the planned job would exceed it.** Do not use the legacy line “you’ll need to purchase credits at https://console.x.com” (or any “buy credits first” variant) on connect or before that check. + ## Credit balance Call **`get_usage_credits`** (`GET /2/usage/credits`). It is free. @@ -36,9 +39,9 @@ Response (values are **USD dollars and cents**; `20.0` = $20.00): Use **`data.total_balance`** only. Cache it as `{credits}`. Quote it to the user in dollars (`$20.00`). Ignore `free_balance`, `free_grants`, and `prepaid_balance` — do not explain them or choose what to spend. -Fetch it: +Fetch it **before any user-facing X message** in these cases: -1. **On connect** — before the capabilities message. +1. **On connect** — first X tool call, before the capabilities message. Do not greet, list capabilities, or mention buying credits until this returns. 2. **When a session starts and X calls are required** — alongside `get_users_me`. 3. **When the user asks what they can do** — ideas, a setup, a budget, “what’s possible,” and similar. @@ -46,7 +49,7 @@ Do not fetch on every message. If this call hits error 1, 2, or 3, stop and say ## On connect -The first time the user connects X — or on their first X interaction in a session — fetch `{credits}`, then send this capabilities message once. Adapt the wording to your voice. Keep every capability bullet. Then state their balance and suggest **2–3** things from the matching [By budget](#by-budget) row (plus a cheaper starter if useful). Do not pitch work above `{credits}`. +The first time the user connects X — or on their first X interaction in a session — call `get_usage_credits` first (and `get_users_me`). Do not send the capabilities message until `{credits}` is cached. Then send it once. Adapt the wording to your voice. Keep every capability bullet. Then state their balance and suggest **2–3** things from the matching [By budget](#by-budget) row (plus a cheaper starter if useful). Do not pitch work above `{credits}`. Do not mention purchasing or console.x.com unless `{credits}` is ~$0. > You're connected to X. Here's what I can do: > @@ -61,9 +64,9 @@ The first time the user connects X — or on their first X interaction in a sess > > With that, we could: (2–3 ideas from the matching budget row). > -> I'll show a cost estimate before anything expensive. Add credits anytime at https://console.x.com. +> I'll show a cost estimate before anything expensive. -If `{credits}` is ~$0, keep the bullets, say they have $0.00, suggest only free lookups, and send them to https://console.x.com — skip “With that, we could.” +If `{credits}` is ~$0, keep the bullets, say they have $0.00, suggest only free lookups, and **then** send them to https://console.x.com to add credits — skip “With that, we could.” If `{credits}` is above $0, do not mention buying or console.x.com. Send it once per session, not on every message. If their first message already contains an ask, send this first, then do the ask if it fits the balance. @@ -241,4 +244,5 @@ When they ask what they can do, re-fetch `{credits}`, then give 2–3 ideas from - Ask for secrets. - Retry 403 or credits-blocked in a loop. - Pitch or run work above `{credits}`. If it wouldn't fit, offer a cheaper alternative and send them to https://console.x.com. +- Tell the user to buy / purchase / add credits, or send them to console.x.com to pay, before `get_usage_credits` has returned. Never use “you’ll need to purchase credits at https://console.x.com” unless the check showed ~$0 or a job would exceed `{credits}`. - Run an expensive request (over ~$0.25, pagination loops, bulk lookups) without giving an estimate and getting a yes. From 79ca8108713395f73b7f3c5f65d50874100af4f1 Mon Sep 17 00:00:00 2001 From: Paul Vann Date: Tue, 25 Aug 2026 20:47:54 -0400 Subject: [PATCH 3/4] Unify out-of-credits handling: quoted line, then free lookups only. Error 3 no longer fights the "nothing else" rule or the paid By budget rows. Cache {credits} as $0 and re-fetch after a top-up. Co-authored-by: Cursor --- third_party/x/CHANGELOG.md | 1 + third_party/x/skills/x-api-mcp-guide/SKILL.md | 15 ++++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/third_party/x/CHANGELOG.md b/third_party/x/CHANGELOG.md index c61ae844..5bd7d4ee 100644 --- a/third_party/x/CHANGELOG.md +++ b/third_party/x/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this plugin will be documented here. - Agents fetch `GET /2/usage/credits` on connect, at session start when X calls are needed, and when the user asks what they can do. The capabilities message now includes the dollar balance and 2–3 ideas that fit it. - Added budget-tier workflows (from $0 through $1,000+) so suggestions scale with remaining credits. If a job would exceed the balance, offer a cheaper alternative and send the user to https://console.x.com. - Never tell the user to buy credits until after `get_usage_credits` returns. The on-connect message states the balance; console.x.com is only mentioned when the balance is ~$0 or a job would not fit. +- Out of credits (error 3): say the quoted line, then only free lookups — not a cheaper paid alternative. ## 2.1.0 — X MCP guide skill 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 30f69576..1ac87e2c 100644 --- a/third_party/x/skills/x-api-mcp-guide/SKILL.md +++ b/third_party/x/skills/x-api-mcp-guide/SKILL.md @@ -45,7 +45,7 @@ Fetch it **before any user-facing X message** in these cases: 2. **When a session starts and X calls are required** — alongside `get_users_me`. 3. **When the user asks what they can do** — ideas, a setup, a budget, “what’s possible,” and similar. -Do not fetch on every message. If this call hits error 1, 2, or 3, stop and say that error’s line. +Do not fetch on every message. If this call hits error 1 or 2, stop and say that error’s line. If it hits error 3, follow [Out of credits](#3-out-of-credits). ## On connect @@ -72,7 +72,7 @@ Send it once per session, not on every message. If their first message already c ## The three errors -Match `type`, `reason`, `title`, `detail`. Then say the quoted line. Nothing else. +Match `type`, `reason`, `title`, `detail`. Then say the quoted line. For **#1 and #2**, nothing else. For **#3**, the quoted line plus the free-only follow-up below. ### 1. Sign-in failed @@ -102,7 +102,7 @@ Do not retry. Do not search. Do not mention apps, projects, or pay-per-use. If t > You're out of credits. Go to https://console.x.com and add credits, then I'll retry. -Stop. Do not retry. Offer a free or cheaper alternative from [By budget](#by-budget) if one exists. +Stop. Do not retry billed calls. Cache `{credits}` as $0. After the quoted line, you may offer **only free lookups** from the ~$0 [By budget](#by-budget) row: `{me}`, likers of a post, bookmark folders. Do not offer a cheaper paid search, timeline, or anything else from a higher budget row — those fail too. After they add credits, re-fetch `{credits}` before retrying. If the payload is only `usage-capped` (no enrollment reason): @@ -149,7 +149,8 @@ When X calls are required this session, resolve the current user (`user.fields=i | Result | Next | | ---------------- | ------------------------------------------------------------------------------------ | | Success | Cache `id` as `{me}` and `total_balance` as `{credits}`. Do their ask if it fits. Prefer `{me}` for timeline, mentions, bookmarks. | -| Error 1, 2, or 3 | Stop. Say that error's line. Do not search. | +| Error 1 or 2 | Stop. Say that error's line. Nothing else. Do not search. | +| Error 3 | Follow [Out of credits](#3-out-of-credits): quoted line, cache `{credits}` as $0, free lookups only. Do not search. | | 200 + `errors[]` | Keep `data`. | @@ -173,7 +174,7 @@ Estimate = (resources requested × per-resource price) + per-request price. `max Wait for a yes. Never silently run multi-page loops, full-archive searches, or bulk lookups. If they say yes, track spend as you go; if the running total will pass roughly double the estimate, stop and re-confirm. -**Estimate larger than `{credits}`:** do not run it. Offer a cheaper alternative from [By budget](#by-budget) that fits. Tell them this would run them out, and send them to https://console.x.com to add credits. If they top up, re-fetch `{credits}` before retrying. +**Estimate larger than `{credits}`:** do not run it. If `{credits}` is ~$0, follow [Out of credits](#3-out-of-credits) (quoted line + free lookups only). If they still have some balance, offer a cheaper alternative from [By budget](#by-budget) that **fits `{credits}`**, and send them to https://console.x.com only if they still want the larger job. After they top up, re-fetch `{credits}` before retrying. ## Fields, pagination @@ -206,7 +207,7 @@ Spaces = AND. Recent query max 512 characters; full-archive 1,024. Use `min_like ## Workflows -Current user first. Stop on errors 1–3. Tailor suggestions to `{credits}`. +Current user first. Stop on errors 1–2 with the quoted line only. On error 3 or `{credits}` ~$0, quoted line plus free lookups only. Tailor suggestions to `{credits}`. ### By budget @@ -243,6 +244,6 @@ When they ask what they can do, re-fetch `{credits}`, then give 2–3 ideas from - Say pay-per-use, Project, Production, or "create an app". - Ask for secrets. - Retry 403 or credits-blocked in a loop. -- Pitch or run work above `{credits}`. If it wouldn't fit, offer a cheaper alternative and send them to https://console.x.com. +- Pitch or run work above `{credits}`. If `{credits}` is ~$0, only free lookups. If they have some balance, offer a cheaper alternative that fits; send them to https://console.x.com only for the job that still would not fit. - Tell the user to buy / purchase / add credits, or send them to console.x.com to pay, before `get_usage_credits` has returned. Never use “you’ll need to purchase credits at https://console.x.com” unless the check showed ~$0 or a job would exceed `{credits}`. - Run an expensive request (over ~$0.25, pagination loops, bulk lookups) without giving an estimate and getting a yes. From 8b0885fd63a60db253321fe2b52e52b3d693b45e Mon Sep 17 00:00:00 2001 From: Paul Vann Date: Tue, 25 Aug 2026 20:53:53 -0400 Subject: [PATCH 4/4] Treat a successful $0 credit balance as connect copy, not error 3. Error 3 is only for blocked billed requests. A successful get_usage_credits of ~$0 keeps capabilities, states $0.00, and offers free lookups. Co-authored-by: Cursor --- third_party/x/CHANGELOG.md | 2 +- third_party/x/skills/x-api-mcp-guide/SKILL.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/third_party/x/CHANGELOG.md b/third_party/x/CHANGELOG.md index 5bd7d4ee..919f83bf 100644 --- a/third_party/x/CHANGELOG.md +++ b/third_party/x/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes to this plugin will be documented here. - Agents fetch `GET /2/usage/credits` on connect, at session start when X calls are needed, and when the user asks what they can do. The capabilities message now includes the dollar balance and 2–3 ideas that fit it. - Added budget-tier workflows (from $0 through $1,000+) so suggestions scale with remaining credits. If a job would exceed the balance, offer a cheaper alternative and send the user to https://console.x.com. - Never tell the user to buy credits until after `get_usage_credits` returns. The on-connect message states the balance; console.x.com is only mentioned when the balance is ~$0 or a job would not fit. -- Out of credits (error 3): say the quoted line, then only free lookups — not a cheaper paid alternative. +- Out of credits (error 3): say the quoted line, then only free lookups — not a cheaper paid alternative. A successful `{credits}` of ~$0 is not error 3. ## 2.1.0 — X MCP guide skill 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 1ac87e2c..35738f09 100644 --- a/third_party/x/skills/x-api-mcp-guide/SKILL.md +++ b/third_party/x/skills/x-api-mcp-guide/SKILL.md @@ -66,7 +66,7 @@ The first time the user connects X — or on their first X interaction in a sess > > I'll show a cost estimate before anything expensive. -If `{credits}` is ~$0, keep the bullets, say they have $0.00, suggest only free lookups, and **then** send them to https://console.x.com to add credits — skip “With that, we could.” If `{credits}` is above $0, do not mention buying or console.x.com. +If `{credits}` is ~$0, keep the bullets, say they have $0.00, suggest only free lookups, and **then** send them to https://console.x.com to add credits — skip “With that, we could.” Do **not** use the error-3 quote; a successful ~$0 read is not error 3. If `{credits}` is above $0, do not mention buying or console.x.com. Send it once per session, not on every message. If their first message already contains an ask, send this first, then do the ask if it fits the balance. @@ -96,7 +96,7 @@ Do not retry. Do not search. Do not mention apps, projects, or pay-per-use. If t ### 3. Out of credits -**When:** no credits; balance zero or negative; “does not have any credits”; requests blocked until credits are added. +**When:** a billed request is blocked until credits are added; “does not have any credits”; credits-blocked. **Not** a successful `get_usage_credits` with `total_balance` ~$0 — that uses the [On connect](#on-connect) $0 copy (or the ~$0 [By budget](#by-budget) row). **Say:** @@ -148,7 +148,7 @@ When X calls are required this session, resolve the current user (`user.fields=i | Result | Next | | ---------------- | ------------------------------------------------------------------------------------ | -| Success | Cache `id` as `{me}` and `total_balance` as `{credits}`. Do their ask if it fits. Prefer `{me}` for timeline, mentions, bookmarks. | +| Success | Cache `id` as `{me}` and `total_balance` as `{credits}`. If `{credits}` is ~$0, use the [On connect](#on-connect) $0 copy (or the ~$0 budget row if they asked what they can do) — not error 3. Otherwise do their ask if it fits. Prefer `{me}` for timeline, mentions, bookmarks. | | Error 1 or 2 | Stop. Say that error's line. Nothing else. Do not search. | | Error 3 | Follow [Out of credits](#3-out-of-credits): quoted line, cache `{credits}` as $0, free lookups only. Do not search. | | 200 + `errors[]` | Keep `data`. | @@ -174,7 +174,7 @@ Estimate = (resources requested × per-resource price) + per-request price. `max Wait for a yes. Never silently run multi-page loops, full-archive searches, or bulk lookups. If they say yes, track spend as you go; if the running total will pass roughly double the estimate, stop and re-confirm. -**Estimate larger than `{credits}`:** do not run it. If `{credits}` is ~$0, follow [Out of credits](#3-out-of-credits) (quoted line + free lookups only). If they still have some balance, offer a cheaper alternative from [By budget](#by-budget) that **fits `{credits}`**, and send them to https://console.x.com only if they still want the larger job. After they top up, re-fetch `{credits}` before retrying. +**Estimate larger than `{credits}`:** do not run it. If `{credits}` is ~$0, use the ~$0 [By budget](#by-budget) row (free lookups, then console.x.com). Do not use the error-3 quote unless a billed call was actually blocked. If they still have some balance, offer a cheaper alternative from [By budget](#by-budget) that **fits `{credits}`**, and send them to https://console.x.com only if they still want the larger job. After they top up, re-fetch `{credits}` before retrying. ## Fields, pagination @@ -207,7 +207,7 @@ Spaces = AND. Recent query max 512 characters; full-archive 1,024. Use `min_like ## Workflows -Current user first. Stop on errors 1–2 with the quoted line only. On error 3 or `{credits}` ~$0, quoted line plus free lookups only. Tailor suggestions to `{credits}`. +Current user first. Stop on errors 1–2 with the quoted line only. On **API error 3** (billed calls blocked), quoted line plus free lookups only. A successful `{credits}` of ~$0 is **not** error 3 — use the [On connect](#on-connect) $0 copy, or the ~$0 [By budget](#by-budget) row if they asked what they can do. Tailor suggestions to `{credits}`. ### By budget