MCP server for Reddit Ads API v3 -- campaign management, ad creation, performance reporting, and audience targeting via Claude.
- 18 tools covering full CRUD for campaigns, ad groups, and ads
- Performance reports with daily breakdowns
- Subreddit, interest, and geographic targeting
- Bulk pause/enable operations
- Safe by default: all new entities created in PAUSED status
- Budget inputs in dollars (auto-converts to Reddit's microcurrency format)
npm install mcp-reddit-adsOr clone the repository:
git clone https://github.com/mharnett/mcp-reddit-ads.git
cd mcp-reddit-ads
npm install
npm run buildSecurity: Never share your .mcp.json file or commit it to git -- it may contain API credentials. Add .mcp.json to your .gitignore.
Create a Reddit OAuth app at reddit.com/prefs/apps:
- Select "script" type
- Note the client ID and client secret
- Obtain a refresh token with
adsread adsedit readscopes
Set credentials via environment variables:
| Variable | Description |
|---|---|
REDDIT_CLIENT_ID |
OAuth app client ID |
REDDIT_CLIENT_SECRET |
OAuth app client secret |
REDDIT_REFRESH_TOKEN |
OAuth refresh token with ads scopes |
REDDIT_ADS_MCP_WRITE |
Set to true to enable mutating tools (create/update/pause/enable). Unset = read-only (default). |
As of v1.1.0 the MCP starts in read-only mode. The 10 read/report/targeting tools are always exposed, but the 8 mutating tools (create/update campaigns, ad groups, ads, and bulk pause/enable) are hidden from the tool list and refused at call time unless REDDIT_ADS_MCP_WRITE=true is set in the server's environment. This guards against a casual chat message accidentally mutating live ad spend. Enable writes deliberately, for the sessions where you actually intend to ship changes.
Copy config.example.json to config.json and fill in defaults:
{
"reddit_api": {
"base_url": "https://ads-api.reddit.com/api/v3",
"auth": {
"client_id": "",
"client_secret": "",
"refresh_token": "",
"user_agent": "reddit-ad-mcp/1.0"
}
},
"defaults": {
"account_id": "",
"business_id": "",
"report_metrics": ["impressions", "clicks", "spend", "ctr", "cpc", "ecpm"],
"date_range_days": 7
}
}Environment variables take precedence over config file values.
{
"mcpServers": {
"reddit-ads": {
"command": "node",
"args": ["/path/to/mcp-reddit-ads/dist/index.js"],
"env": {
"REDDIT_CLIENT_ID": "$(security find-generic-password -a reddit-ads-mcp -s REDDIT_CLIENT_ID -w)",
"REDDIT_CLIENT_SECRET": "$(security find-generic-password -a reddit-ads-mcp -s REDDIT_CLIENT_SECRET -w)",
"REDDIT_REFRESH_TOKEN": "$(security find-generic-password -a reddit-ads-mcp -s REDDIT_REFRESH_TOKEN -w)"
}
}
}
}Claude Desktop: Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows).
| Tool | Description |
|---|---|
reddit_ads_get_client_context |
Get account info and verify API connectivity |
reddit_ads_get_accounts |
List all ad accounts accessible to the authenticated user |
| Tool | Description |
|---|---|
reddit_ads_get_campaigns |
List campaigns with optional status filter |
reddit_ads_get_ad_groups |
List ad groups for a campaign |
reddit_ads_get_ads |
List ads for an ad group |
reddit_ads_get_performance_report |
Aggregated performance metrics for campaigns/ad groups/ads |
reddit_ads_get_daily_performance |
Day-by-day performance breakdown |
| Tool | Description |
|---|---|
reddit_ads_create_campaign |
Create a new campaign (PAUSED by default) |
reddit_ads_update_campaign |
Update campaign name, budget, objective, or status |
| Tool | Description |
|---|---|
reddit_ads_create_ad_group |
Create a new ad group with targeting (PAUSED by default) |
reddit_ads_update_ad_group |
Update ad group bid, targeting, or status |
| Tool | Description |
|---|---|
reddit_ads_create_ad |
Create a new ad with headline, body, URL, and media (PAUSED by default) |
reddit_ads_update_ad |
Update ad creative or status |
| Tool | Description |
|---|---|
reddit_ads_pause_items |
Pause multiple campaigns, ad groups, or ads at once |
reddit_ads_enable_items |
Enable multiple campaigns, ad groups, or ads at once |
| Tool | Description |
|---|---|
reddit_ads_search_subreddits |
Search for subreddits by keyword for targeting |
reddit_ads_get_interest_categories |
List available interest categories for targeting |
reddit_ads_search_geo_targets |
Search for geographic targeting options (countries, regions, metros) |
- Spend values are returned from the API in microcurrency (1 dollar = 1,000,000 microcurrency units). Divide by 1,000,000 to get dollar amounts. Budget inputs accept dollars and auto-convert.
- Dates and times use ISO 8601 format (
YYYY-MM-DDTHH:MM:SSZ). - New entities default to PAUSED status. Explicitly set status to
ACTIVEto go live. - Report metrics default to the set configured in
config.jsonbut can be overridden per request.
- Resilience: Uses cockatiel for retry policies and circuit breaking on API calls
- Logging: Structured logging via pino
- Response truncation: Large API responses are truncated at 200KB to stay within MCP message limits
- Auth: OAuth 2.0 refresh token flow with automatic access token renewal
MIT -- see LICENSE.
Built by Mark Harnett / drak-marketing.