Skip to content
Merged
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
19 changes: 4 additions & 15 deletions third_party/x/.cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "x",
"displayName": "X",
"version": "1.0.0",
"version": "2.0.0",
"minClientVersions": {
"cursor": "3.13.0"
},
"description": "Read-only access to the X API — search posts and users, read timelines and mentions, and pull trends and news — via X's official hosted MCP server.",
"description": "Connect to the X API — search posts and users, read timelines and mentions, pull trends and news, and manage lists, bookmarks, blocks, and mutes — via X's official hosted MCP server.",
"author": {
"name": "Cursor",
"email": "plugins@cursor.com"
Expand All @@ -21,6 +21,8 @@
"search",
"trends",
"news",
"lists",
"bookmarks",
"social",
"mcp"
],
Expand All @@ -31,18 +33,5 @@
"search",
"mcp"
],
"variables": {
"type": "object",
"properties": {
"X_BEARER_TOKEN": {
"type": "string",
"title": "X app-only Bearer token",
"description": "App-only Bearer token from your app's Keys and tokens page in the X Developer Portal (https://developer.x.com). Grants read-only access to the X API with no user context."
}
},
"required": [
"X_BEARER_TOKEN"
]
},
"mcpServers": "./mcp.json"
}
7 changes: 7 additions & 0 deletions third_party/x/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to this plugin will be documented here.

## 2.0.0 — OAuth user sign-in, no longer read-only

- Replaced the `X_BEARER_TOKEN` app-only route with OAuth user sign-in using X's client ID `NGdZYmo4VVp2T1BnRG55NlExOGQ6MTpjaQ`.
- Requested scopes: `tweet.read`, `users.read`, `follows.read`, `space.read`, `mute.read`, `like.read`, `list.read`, `list.write`, `block.read`, `block.write`, `bookmark.read`, `bookmark.write`, `billing.write`, `offline.access`.
- Agents can now manage lists, bookmarks, blocks, and mutes in your user context. Posting is still not possible (`tweet.write` is not requested).
- Removed the `X_BEARER_TOKEN` plugin variable — no credential to paste anymore.

## 1.0.0 — initial release

- Logo: X's official mark from the X brand toolkit, on a black tile matching X's own app icon.
Expand Down
63 changes: 30 additions & 33 deletions third_party/x/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

Cursor plugin that connects agents to the [X API](https://docs.x.com) through X's official hosted [Model Context Protocol](https://modelcontextprotocol.io/) server at `https://api.x.com/mcp`.

This plugin uses X's **app-only Bearer** route, which is read-only: agents can search and read public X data, but cannot post, bookmark, publish Articles, or act as any user.
This plugin signs you in with OAuth as your own X account. It is no longer read-only: alongside searching and reading public X data, agents can manage your lists, bookmarks, blocks, and mutes.

## Install

1. Open **Cursor Settings → Plugins**.
2. Search for **X**.
3. Click **Install**, then set your app-only Bearer token (below).
3. Click **Install**, then complete the OAuth sign-in when prompted.

Or run `/add-plugin x` in chat.

Expand All @@ -20,8 +20,24 @@ Or run `/add-plugin x` in chat.
"x": {
"type": "http",
"url": "https://api.x.com/mcp",
"headers": {
"Authorization": "Bearer ${X_BEARER_TOKEN}"
"auth": {
"CLIENT_ID": "NGdZYmo4VVp2T1BnRG55NlExOGQ6MTpjaQ",
"scopes": [
"tweet.read",
"users.read",
"follows.read",
"space.read",
"mute.read",
"like.read",
"list.read",
"list.write",
"block.read",
"block.write",
"bookmark.read",
"bookmark.write",
"billing.write",
"offline.access"
]
}
}
}
Expand All @@ -30,47 +46,28 @@ Or run `/add-plugin x` in chat.

## What agents can do

| Category | Read-only capabilities |
| Category | Capabilities |
| --- | --- |
| Posts | Fetch posts, see likers / reposters / quoters, recent counts |
| Search | Full-archive post search, user search, news search |
| Users | Look up users by id or handle; read a user's posts, timeline, and mentions |
| News & trends | Get news stories, get trends for a location (WOEID) |
| Follows, likes & Spaces | Read your follows, likes, and Spaces |
| Lists | Read and manage your lists |
| Bookmarks | Read and manage your bookmarks |
| Blocks & mutes | Read your blocks and mutes; add or remove blocks |

Write tools and user-context tools (bookmarks, Articles, resolving the current user) are not reachable with an app-only token. See [Full user-context access](#full-user-context-access) if you need them.
Posting is not included: the plugin does not request the `tweet.write` scope, so agents cannot publish posts as you.

## Setup

No credential ships with this plugin — it carries only a `${X_BEARER_TOKEN}` placeholder, and each install supplies its own token.
No token to paste — the plugin ships with X's OAuth client ID and requests the scopes above. On first use, Cursor opens a browser window where you sign in to X and approve access. The `offline.access` scope lets Cursor refresh the session automatically, so you only sign in once.

1. Create an app in the [X Developer Portal](https://developer.x.com).
2. Open the app's **Keys and tokens** page and copy the **Bearer Token** (the app-only token).
3. In **Dashboard → Plugins → Configure**, set **X app-only Bearer token** to that value.
Requests run in your user context, so they count against your account's rate limits. You can revoke access at any time from your X account's connected apps settings.

The token carries your app's own quota and rate limits rather than a user's. Rotate or regenerate it from the developer portal if it is ever exposed.
## Scopes requested

On a team marketplace an admin sets the token once for everyone, so every member's tool calls share that app's rate limits.

## Full user-context access

X's other route runs the open-source [`xurl`](https://github.com/xdevplatform/xurl) bridge locally over stdio. It performs an OAuth 2.0 PKCE browser login, refreshes tokens automatically, and unlocks writes and user-context tools:

```json
{
"mcpServers": {
"x": {
"command": "npx",
"args": ["-y", "@xdevplatform/xurl", "mcp", "https://api.x.com/mcp"],
"env": {
"CLIENT_ID": "YOUR_X_APP_CLIENT_ID",
"CLIENT_SECRET": "YOUR_X_APP_CLIENT_SECRET"
}
}
}
}
```

That route needs OAuth 2.0 enabled on the app, `http://localhost:8080/callback` registered as a redirect URI, Node.js for `npx`, and a reachable browser for the first login — so it is deliberately not what this plugin ships.
`tweet.read`, `users.read`, `follows.read`, `space.read`, `mute.read`, `like.read`, `list.read`, `list.write`, `block.read`, `block.write`, `bookmark.read`, `bookmark.write`, `billing.write`, `offline.access`

## X documentation search

Expand Down
20 changes: 18 additions & 2 deletions third_party/x/mcp.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,24 @@
"x": {
"type": "http",
"url": "https://api.x.com/mcp",
"headers": {
"Authorization": "Bearer ${X_BEARER_TOKEN}"
"auth": {
"CLIENT_ID": "NGdZYmo4VVp2T1BnRG55NlExOGQ6MTpjaQ",
"scopes": [
"tweet.read",
"users.read",
"follows.read",
"space.read",
"mute.read",
"like.read",
"list.read",
"list.write",
"block.read",
"block.write",
"bookmark.read",
"bookmark.write",
"billing.write",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid billing.write OAuth scope

High Severity · Logic Bug

billing.write is not a documented X OAuth 2.0 scope. Requesting it on sign-in can cause X to reject the consent request, so the new user OAuth flow fails before any MCP tools run. It also does not match any capability this plugin documents.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6a39659. Configure here.

"offline.access"
]
}
}
}
Expand Down
Loading