Add X Ads third-party MCP plugin - #302
Conversation
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 <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
Bugbot Autofix is ON, but it could not run because the branch was deleted or merged before autofix could start.
Reviewed by Cursor Bugbot for commit d726d67. Configure here.
| "scopes": [ | ||
| "ads.read", | ||
| "ads.write", | ||
| "media.write", |
There was a problem hiding this comment.
Unadvertised Ads OAuth scope
High Severity · Bugbot Rules
media.write is not a vendor-advertised scope for the Ads MCP protected resource. Coverage of ads-api.x.com/mcp lists ads.read, ads.write, and offline.access; media.write is a general X API v2 user-media scope on api.x.com. Requesting an unadvertised scope fails the OAuth grant, so sign-in can break.
Additional Locations (2)
Triggered by learned rule: Plugin OAuth scopes must be vendor-advertised
Reviewed by Cursor Bugbot for commit d726d67. Configure here.
There was a problem hiding this comment.
Keeping media.write. The live Ads MCP protected-resource metadata advertises it.
Fetched just now from https://ads-api.x.com/.well-known/oauth-protected-resource (same payload at https://ads-api.x.com/.well-known/oauth-protected-resource/mcp):
{
"authorization_servers": ["https://api.x.com"],
"bearer_methods_supported": ["header"],
"resource": "https://ads-api.x.com/mcp",
"scopes_supported": ["ads.read", "ads.write", "media.write", "offline.access"]
}media.write is vendor-advertised on the ads protected resource, not only on api.x.com. (For comparison, https://api.x.com/.well-known/oauth-protected-resource does not list media.write; the ads PRM does.) Leaving the scope in mcp.json so OAuth matches the PRM.
Co-authored-by: Cursor <cursoragent@cursor.com>


Summary
third_party/x-ads/, pointing at X's hosted ads MCP server (https://ads-api.x.com/mcp) over Streamable HTTP. It lets agents manage campaigns, create ads, set up pixels and conversion tracking, and pull performance stats.ads-api.x.comis a different OAuth protected resource thanapi.x.com(see https://ads-api.x.com/.well-known/oauth-protected-resource), with different scopes, so authorization cannot be shared. Users who install both authorize each one separately.ads.read,ads.write,media.write, andoffline.access(for token refresh, matching the X plugin). The ads MCP server already grants access to this client server-side..cursor-plugin/marketplace.jsonand the root README table.Notes for reviewers
media.writeis included so the creative/media upload tools can work in the future, although we don't currently have thatTest plan
node scripts/validate-plugins.mjs)/add-plugin x-adsNote
Low Risk
Adds a new third-party plugin and marketplace listing only; no changes to shared auth or core app logic, though installed users grant ads write access via OAuth.
Overview
Adds a new X Ads integration plugin so agents can talk to X’s hosted ads MCP at
https://ads-api.x.com/mcpfor campaigns, creatives, pixels/conversions, and performance stats.The change is mostly net-new under
third_party/x-ads/(manifest,mcp.json, README, changelog, license, logo) with OAuth using the same public client ID as the existing X plugin but ads-specific scopes (ads.read,ads.write,media.write,offline.access) on the separateads-api.x.comprotected resource—so users authorize this plugin independently of the main X plugin. The root marketplace manifest and README integrations table registerx-adsalongside existing entries.Reviewed by Cursor Bugbot for commit 164c539. Bugbot is set up for automated code reviews on this repo. Configure here.