Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion third_party/x/.cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "x",
"displayName": "X",
"version": "2.1.0",
"version": "2.2.0",
"minClientVersions": {
"cursor": "3.13.0"
},
Expand Down
5 changes: 5 additions & 0 deletions third_party/x/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
96 changes: 77 additions & 19 deletions third_party/x/skills/x-api-mcp-guide/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
>
Expand All @@ -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

Expand Down Expand Up @@ -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):

Expand Down Expand Up @@ -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.
Expand All @@ -123,18 +158,20 @@ 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:

> This will cost about $X.XX. Want me to continue?

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`.
Expand Down Expand Up @@ -166,21 +203,42 @@ 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.
- Topic: recent counts → small search page → stop.
- 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.

2 changes: 2 additions & 0 deletions third_party/x/skills/x-api-mcp-guide/references/pricing.md
Original file line number Diff line number Diff line change
Expand Up @@ -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) |
Expand Down Expand Up @@ -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
Expand Down