Switch X plugin to OAuth user sign-in with write scopes

Co-authored-by: Alex Vandak Maloney  <maloney.a12@gmail.com>
This commit is contained in:
Cursor Agent
2026-08-13 21:55:28 +00:00
parent 3af3c85b1d
commit 6a39659599
4 changed files with 59 additions and 50 deletions
+4 -15
View File
@@ -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"
@@ -21,6 +21,8 @@
"search",
"trends",
"news",
"lists",
"bookmarks",
"social",
"mcp"
],
@@ -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
View File
@@ -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.
+30 -33
View File
@@ -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.
@@ -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"
]
}
}
}
@@ -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
+18 -2
View File
@@ -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",
"offline.access"
]
}
}
}