From 458dd1650329364e5bc7e9c381f16abf13af2b46 Mon Sep 17 00:00:00 2001 From: Nathan Lee Date: Tue, 1 Sep 2026 18:10:05 -0700 Subject: [PATCH 1/3] Add X Ads third-party MCP plugin New plugin, separate from the existing X plugin, pointing at X's hosted ads MCP server (https://ads-api.x.com/mcp). Auth is per protected resource: ads-api.x.com advertises its own OAuth metadata and scopes (ads.read, ads.write), so it cannot share the X plugin's authorization even though it reuses the same OAuth client ID. Co-authored-by: Cursor --- .cursor-plugin/marketplace.json | 5 ++ README.md | 1 + third_party/x-ads/.cursor-plugin/plugin.json | 35 ++++++++++ third_party/x-ads/CHANGELOG.md | 10 +++ third_party/x-ads/LICENSE | 21 ++++++ third_party/x-ads/README.md | 69 ++++++++++++++++++++ third_party/x-ads/assets/logo.svg | 5 ++ third_party/x-ads/mcp.json | 16 +++++ 8 files changed, 162 insertions(+) create mode 100644 third_party/x-ads/.cursor-plugin/plugin.json create mode 100644 third_party/x-ads/CHANGELOG.md create mode 100644 third_party/x-ads/LICENSE create mode 100644 third_party/x-ads/README.md create mode 100644 third_party/x-ads/assets/logo.svg create mode 100644 third_party/x-ads/mcp.json diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json index a43116e9..c091c153 100644 --- a/.cursor-plugin/marketplace.json +++ b/.cursor-plugin/marketplace.json @@ -322,6 +322,11 @@ "name": "onedrive", "source": "third_party/onedrive", "description": "Browse, search, and read Microsoft OneDrive files." + }, + { + "name": "x-ads", + "source": "third_party/x-ads", + "description": "Manage ad campaigns, create ads, track conversions, and pull performance stats." } ] } diff --git a/README.md b/README.md index bbe4867f..62440cd7 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ Official Cursor plugins for popular developer tools, frameworks, and SaaS produc | `readwise` | [Readwise](third_party/readwise/) | Cursor | Integrations | Search highlights and Reader documents, save articles. | | `similarweb` | [Similarweb](third_party/similarweb/) | Cursor | Integrations | Analyze website traffic, audiences, and competitors. | | `xero` | [Xero](third_party/xero/) | Cursor | Integrations | Read and write invoices, contacts, reports, and payroll. | +| `x-ads` | [X Ads](third_party/x-ads/) | Cursor | Integrations | Manage ad campaigns, create ads, track conversions, and pull performance stats. | Author values match each plugin’s `plugin.json` `author.name` (Cursor lists `plugins@cursor.com` in the manifest). ## Repository structure diff --git a/third_party/x-ads/.cursor-plugin/plugin.json b/third_party/x-ads/.cursor-plugin/plugin.json new file mode 100644 index 00000000..bb143b7c --- /dev/null +++ b/third_party/x-ads/.cursor-plugin/plugin.json @@ -0,0 +1,35 @@ +{ + "name": "x-ads", + "displayName": "X Ads", + "version": "1.0.0", + "minClientVersions": { + "cursor": "3.13.0" + }, + "description": "Manage ad campaigns, create ads, track conversions, and pull performance stats.", + "author": { + "name": "Cursor", + "email": "plugins@cursor.com" + }, + "homepage": "https://docs.x.com/x-ads-api/introduction", + "repository": "https://github.com/cursor/plugins", + "license": "MIT", + "logo": "assets/logo.svg", + "keywords": [ + "x", + "twitter", + "ads", + "advertising", + "campaigns", + "conversions", + "analytics", + "mcp" + ], + "category": "integrations", + "tags": [ + "x", + "ads", + "advertising", + "mcp" + ], + "mcpServers": "./mcp.json" +} diff --git a/third_party/x-ads/CHANGELOG.md b/third_party/x-ads/CHANGELOG.md new file mode 100644 index 00000000..c4db7abb --- /dev/null +++ b/third_party/x-ads/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changelog + +All notable changes to this plugin will be documented here. + +## 1.0.0 — initial release + +- Added the `x-ads` MCP server pointing at `https://ads-api.x.com/mcp`. +- OAuth user sign-in using X's client ID `NGdZYmo4VVp2T1BnRG55NlExOGQ6MTpjaQ` (the same client the X connector uses), requesting `ads.read`, `ads.write`, and `offline.access`. +- Separate plugin from X: `ads-api.x.com` is a different protected resource than `api.x.com` with different scopes, so it requires its own authorization. +- Logo: X's official mark from the X brand toolkit, on a black tile matching X's own app icon. diff --git a/third_party/x-ads/LICENSE b/third_party/x-ads/LICENSE new file mode 100644 index 00000000..ca2bba77 --- /dev/null +++ b/third_party/x-ads/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Cursor + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/third_party/x-ads/README.md b/third_party/x-ads/README.md new file mode 100644 index 00000000..c51d2643 --- /dev/null +++ b/third_party/x-ads/README.md @@ -0,0 +1,69 @@ +# X Ads + +Cursor plugin that connects agents to the [X Ads API](https://docs.x.com/x-ads-api/introduction) through X's official hosted [Model Context Protocol](https://modelcontextprotocol.io/) server at `https://ads-api.x.com/mcp`. + +This plugin signs you in with OAuth as your own X account and works with the ads accounts you can access. Agents can manage campaigns, create ads, set up pixels and conversion tracking, and pull performance stats. + +This is a separate plugin from the [X](../x/) plugin: the ads MCP server lives on a different subdomain (`ads-api.x.com` vs `api.x.com`) and requires different OAuth scopes, so it needs its own authorization. Installing both means signing in twice — once per plugin. + +## Install + +1. Open **Cursor Settings → Plugins**. +2. Search for **X Ads**. +3. Click **Install**, then complete the OAuth sign-in when prompted. + +Or run `/add-plugin x-ads` in chat. + +## MCP + +```json +{ + "mcpServers": { + "x-ads": { + "type": "http", + "url": "https://ads-api.x.com/mcp", + "auth": { + "CLIENT_ID": "NGdZYmo4VVp2T1BnRG55NlExOGQ6MTpjaQ", + "scopes": [ + "ads.read", + "ads.write", + "offline.access" + ] + } + } + } +} +``` + +## What agents can do + +| Category | Capabilities | +| --- | --- | +| Accounts | Read your ads accounts, funding instruments, and settings | +| Campaigns | Create, update, pause, and read campaigns and line items | +| Ads & creatives | Create and manage promoted ads and creatives | +| Audiences | Read and manage targeting and audiences | +| Pixels & conversions | Set up the X pixel and conversion tracking | +| Analytics | Pull campaign, line item, and ad performance stats | + +## Setup + +No token to paste — the plugin ships with X's OAuth client ID (the same one the X connector uses) and requests the scopes below. 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. + +Requests run in your user context against the ads accounts your X account can access. You can revoke access at any time from your X account's connected apps settings. + +## Scopes requested + +`ads.read`, `ads.write`, `offline.access` + +## Docs + +- X Ads API: https://docs.x.com/x-ads-api/introduction +- OAuth protected resource metadata: https://ads-api.x.com/.well-known/oauth-protected-resource +- Authentication overview: https://docs.x.com/fundamentals/authentication/overview + +Logo is X's official mark from the [X brand toolkit](https://about.x.com/en/who-we-are/brand-toolkit), placed on a black tile matching X's own app icon. + +## License + +MIT diff --git a/third_party/x-ads/assets/logo.svg b/third_party/x-ads/assets/logo.svg new file mode 100644 index 00000000..c63bbbd6 --- /dev/null +++ b/third_party/x-ads/assets/logo.svg @@ -0,0 +1,5 @@ + + X + + + diff --git a/third_party/x-ads/mcp.json b/third_party/x-ads/mcp.json new file mode 100644 index 00000000..15d4cfa9 --- /dev/null +++ b/third_party/x-ads/mcp.json @@ -0,0 +1,16 @@ +{ + "mcpServers": { + "x-ads": { + "type": "http", + "url": "https://ads-api.x.com/mcp", + "auth": { + "CLIENT_ID": "NGdZYmo4VVp2T1BnRG55NlExOGQ6MTpjaQ", + "scopes": [ + "ads.read", + "ads.write", + "offline.access" + ] + } + } + } +} From d726d6735a8417be14971f6f7fb7ede0c5b19762 Mon Sep 17 00:00:00 2001 From: Nathan Lee Date: Tue, 1 Sep 2026 18:26:08 -0700 Subject: [PATCH 2/3] Request media.write so media upload tools work without re-auth Co-authored-by: Cursor --- third_party/x-ads/CHANGELOG.md | 2 +- third_party/x-ads/README.md | 3 ++- third_party/x-ads/mcp.json | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/third_party/x-ads/CHANGELOG.md b/third_party/x-ads/CHANGELOG.md index c4db7abb..70b7cd81 100644 --- a/third_party/x-ads/CHANGELOG.md +++ b/third_party/x-ads/CHANGELOG.md @@ -5,6 +5,6 @@ All notable changes to this plugin will be documented here. ## 1.0.0 — initial release - Added the `x-ads` MCP server pointing at `https://ads-api.x.com/mcp`. -- OAuth user sign-in using X's client ID `NGdZYmo4VVp2T1BnRG55NlExOGQ6MTpjaQ` (the same client the X connector uses), requesting `ads.read`, `ads.write`, and `offline.access`. +- OAuth user sign-in using X's client ID `NGdZYmo4VVp2T1BnRG55NlExOGQ6MTpjaQ` (the same client the X connector uses), requesting `ads.read`, `ads.write`, `media.write`, and `offline.access`. - Separate plugin from X: `ads-api.x.com` is a different protected resource than `api.x.com` with different scopes, so it requires its own authorization. - Logo: X's official mark from the X brand toolkit, on a black tile matching X's own app icon. diff --git a/third_party/x-ads/README.md b/third_party/x-ads/README.md index c51d2643..44e9aab1 100644 --- a/third_party/x-ads/README.md +++ b/third_party/x-ads/README.md @@ -27,6 +27,7 @@ Or run `/add-plugin x-ads` in chat. "scopes": [ "ads.read", "ads.write", + "media.write", "offline.access" ] } @@ -54,7 +55,7 @@ Requests run in your user context against the ads accounts your X account can ac ## Scopes requested -`ads.read`, `ads.write`, `offline.access` +`ads.read`, `ads.write`, `media.write`, `offline.access` ## Docs diff --git a/third_party/x-ads/mcp.json b/third_party/x-ads/mcp.json index 15d4cfa9..a0f9afce 100644 --- a/third_party/x-ads/mcp.json +++ b/third_party/x-ads/mcp.json @@ -8,6 +8,7 @@ "scopes": [ "ads.read", "ads.write", + "media.write", "offline.access" ] } From 164c5395da45ff5e4c02066cd8fb3d465f0e69cb Mon Sep 17 00:00:00 2001 From: Nathan Lee Date: Tue, 1 Sep 2026 18:39:46 -0700 Subject: [PATCH 3/3] Replace X Ads plugin logo with X Ads wordmark. Co-authored-by: Cursor --- third_party/x-ads/.cursor-plugin/plugin.json | 2 +- third_party/x-ads/assets/logo.png | Bin 0 -> 5379 bytes third_party/x-ads/assets/logo.svg | 5 ----- 3 files changed, 1 insertion(+), 6 deletions(-) create mode 100644 third_party/x-ads/assets/logo.png delete mode 100644 third_party/x-ads/assets/logo.svg diff --git a/third_party/x-ads/.cursor-plugin/plugin.json b/third_party/x-ads/.cursor-plugin/plugin.json index bb143b7c..08cb49e3 100644 --- a/third_party/x-ads/.cursor-plugin/plugin.json +++ b/third_party/x-ads/.cursor-plugin/plugin.json @@ -13,7 +13,7 @@ "homepage": "https://docs.x.com/x-ads-api/introduction", "repository": "https://github.com/cursor/plugins", "license": "MIT", - "logo": "assets/logo.svg", + "logo": "assets/logo.png", "keywords": [ "x", "twitter", diff --git a/third_party/x-ads/assets/logo.png b/third_party/x-ads/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b3170753b3acf9f217a8d3c0081adbeb9563d920 GIT binary patch literal 5379 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 - X - - -