{
  "markdown": "# Bing Ads MCP Server\r\n\r\n[![npm version](https://img.shields.io/npm/v/mcp-bing-ads)](https://www.npmjs.com/package/mcp-bing-ads)\r\n[![npm downloads](https://img.shields.io/npm/dm/mcp-bing-ads)](https://www.npmjs.com/package/mcp-bing-ads)\r\n[![GitHub stars](https://img.shields.io/github/stars/mharnett/mcp-bing-ads)](https://github.com/mharnett/mcp-bing-ads)\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\r\n\r\nProduction-grade MCP server for Microsoft Advertising (Bing Ads) API. Enables Claude to manage Bing/Microsoft Ads accounts with full campaign, ad group, keyword, and performance analysis capabilities.\r\n\r\n**Features:**\r\n- **10 tools** -- production-tested\r\n- Campaign, ad group, and keyword management\r\n- Keyword performance analysis with quality scores\r\n- Search term reporting & bid automation\r\n- Budget & bid strategy optimization\r\n- Campaign-level budget updates\r\n- Negative keyword management (shared + campaign-level)\r\n\r\n**Note:** ⚠️ First open-source Bing Ads MCP with comprehensive tooling\r\n- No serious alternatives exist in the ecosystem\r\n- Battle-tested across multiple accounts\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install mcp-bing-ads\r\n```\r\n\r\n## Configuration\r\n\r\n**Security:** Never share your `.mcp.json` file or commit it to git -- it may contain API credentials. Add `.mcp.json` to your `.gitignore`.\r\n\r\n1. **Get OAuth credentials:**\r\n   - Go to [Microsoft Azure Portal](https://portal.azure.com/)\r\n   - Create an Azure AD app registration\r\n   - Grant API permissions: `Microsoft Advertising API`\r\n   - Scopes: `https://ads.microsoft.com/msads.manage offline_access`\r\n\r\n2. **Create `config.json`:**\r\n   ```bash\r\n   cp config.example.json config.json\r\n   ```\r\n\r\n3. **Fill in your credentials:**\r\n   ```json\r\n   {\r\n     \"oauth\": {\r\n       \"client_id\": \"YOUR_AZURE_CLIENT_ID\",\r\n       \"client_secret\": \"YOUR_AZURE_CLIENT_SECRET\"\r\n     },\r\n     \"clients\": {\r\n       \"default\": {\r\n         \"customer_id\": \"YOUR_CUSTOMER_ID\",\r\n         \"account_id\": \"YOUR_ACCOUNT_ID\",\r\n         \"name\": \"My Account\"\r\n       }\r\n     }\r\n   }\r\n   ```\r\n\r\n4. **Set environment variables (recommended):**\r\n   ```bash\r\n   export BING_ADS_DEVELOPER_TOKEN=\"your_developer_token\"\r\n   export BING_ADS_CLIENT_ID=\"your_client_id\"\r\n   export BING_ADS_REFRESH_TOKEN=\"your_refresh_token\"\r\n   # Optional:\r\n   export BING_ADS_CLIENT_SECRET=\"your_client_secret\"\r\n   # Optional: opt into mutating tools (read-only by default)\r\n   export BING_ADS_MCP_WRITE=\"true\"\r\n   ```\r\n\r\n### Environment Variables\r\n\r\n| Variable | Required | Default | Description |\r\n| --- | --- | --- | --- |\r\n| `BING_ADS_DEVELOPER_TOKEN` | yes | -- | Microsoft Advertising developer token |\r\n| `BING_ADS_CLIENT_ID` | yes | -- | Azure AD app client ID |\r\n| `BING_ADS_REFRESH_TOKEN` | yes | -- | OAuth refresh token |\r\n| `BING_ADS_CLIENT_SECRET` | no | -- | Azure AD app client secret (if confidential client) |\r\n| `BING_ADS_MCP_WRITE` | no | `false` | Set to `true`, `1`, or `yes` to expose mutating tools (pause/update/add). Any other value -- or unset -- keeps the server read-only. |\r\n\r\n### Read-only by default\r\n\r\nMutating tools (`bing_ads_pause_keywords`, `bing_ads_update_campaign_budget`, `bing_ads_add_shared_negatives`) are **hidden from the tool list and refused at call time** unless `BING_ADS_MCP_WRITE=true` is set in the server environment. This is a safety gate against casual write actions -- for example, pausing a keyword or editing a budget based on a throwaway chat message. To make write changes, set the env var explicitly in your `.mcp.json` or shell profile for the session that needs it, then unset it afterwards. Read tools (list/report/performance) are always available.\r\n\r\n## Usage\r\n\r\n### Start the server\r\n```bash\r\nnpm start\r\n```\r\n\r\n### Use with Claude Code\r\nAdd to `~/.claude.json`:\r\n```json\r\n{\r\n  \"mcpServers\": {\r\n    \"bing-ads\": {\r\n      \"type\": \"http\",\r\n      \"url\": \"http://localhost:3002\"\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n**Claude Desktop:** Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\\Claude\\claude_desktop_config.json` (Windows).\r\n\r\n### Example API Calls\r\n```typescript\r\n// Get client context\r\nbing_ads_get_client_context({ working_directory: \"/path/to/project\" })\r\n\r\n// List campaigns\r\nbing_ads_list_campaigns()\r\n\r\n// Get campaign performance\r\nbing_ads_get_campaign_performance({\r\n  start_date: \"2026-01-01\",\r\n  end_date: \"2026-03-01\"\r\n})\r\n\r\n// Get keyword performance\r\nbing_ads_keyword_performance({\r\n  start_date: \"2026-02-01\",\r\n  end_date: \"2026-03-01\"\r\n})\r\n\r\n// Create negative keywords\r\nbing_ads_add_shared_negatives({\r\n  shared_list_id: \"list_123\",\r\n  keywords: [\r\n    { text: \"cheap\", match_type: \"Phrase\" },\r\n    { text: \"discount\", match_type: \"Exact\" }\r\n  ]\r\n})\r\n```\r\n\r\n## API Reference\r\n\r\n### Context\r\n- `bing_ads_get_client_context(working_directory)` -- Detect account from working directory\r\n\r\n### Campaigns\r\n- `bing_ads_list_campaigns()` -- List all campaigns\r\n- `bing_ads_get_campaign_performance(start_date, end_date)` -- Campaign metrics\r\n- `bing_ads_update_campaign_budget(campaign_id, daily_budget)` -- Update daily spend\r\n\r\n### Ad Groups\r\n- `bing_ads_list_ad_groups(campaign_id)` -- List ad groups in campaign\r\n\r\n### Keywords\r\n- `bing_ads_keyword_performance(start_date, end_date, [campaign_ids])` -- Keyword metrics & QS\r\n- `bing_ads_search_term_report(start_date, end_date)` -- Search terms that triggered ads\r\n- `bing_ads_pause_keywords(ad_group_id, keyword_ids)` -- Pause keywords\r\n\r\n### Negative Keywords\r\n- `bing_ads_list_shared_entities([type])` -- List shared negative lists\r\n- `bing_ads_add_shared_negatives(list_id, keywords)` -- Add to shared list\r\n\r\n### Performance Reports\r\n- Campaign performance (ROI, conversions, CTR, CPC)\r\n- Keyword performance (QS, expected CTR, ad relevance, landing page experience)\r\n- Search term insights (which queries are converting)\r\n\r\n## Key Metrics & Definitions\r\n\r\n**Quality Score (QS):** 1-10 rating of keyword quality\r\n- 1-3: Poor\r\n- 4-6: Average\r\n- 7-10: Excellent\r\n\r\n**Expected CTR:** 1-9 rating of expected click-through rate\r\n**Ad Relevance:** 1-9 rating of relevance to search query\r\n**Landing Page Experience:** 1-9 rating of landing page quality\r\n\r\n## CLI Tools\r\n\r\n```bash\r\nnpm run dev                 # Run in dev mode (tsx)\r\nnpm run build             # Compile TypeScript\r\nnpm test                  # Run contract tests\r\n```\r\n\r\n## Architecture\r\n\r\n**Files:**\r\n- `src/index.ts` — MCP server, OAuth flow, tool handlers\r\n- `src/tools.ts` — Tool schema definitions\r\n- `src/errors.ts` — Error handling & classification\r\n- `config.json` — Credentials & client mapping\r\n\r\n**Error Classification:**\r\n- Authentication errors (token expired)\r\n- Rate limit errors (retry with backoff)\r\n- Service errors (API temporarily unavailable)\r\n- Validation errors (bad input)\r\n\r\n## Development\r\n\r\n### Adding a New Tool\r\n1. Define schema in `src/tools.ts`\r\n2. Add handler in `src/index.ts` tool dispatch\r\n3. Add contract test in `.contract.test.ts`\r\n4. Test with `npm test`\r\n\r\n### Testing\r\n```bash\r\nnpm test -- --run        # Single run\r\nnpm test -- --watch      # Watch mode\r\n```\r\n\r\n## Troubleshooting\r\n\r\n### `Config file not found`\r\n```bash\r\ncp config.example.json config.json\r\n# Fill in your Azure credentials and Bing Ads IDs\r\n```\r\n\r\n### `Missing required credentials`\r\nCheck that:\r\n- `BING_ADS_DEVELOPER_TOKEN`, `BING_ADS_CLIENT_ID`, and `BING_ADS_REFRESH_TOKEN` are set\r\n- `BING_ADS_CLIENT_SECRET` is set (if using a confidential app)\r\n- OAuth token is valid (expires, may need refresh)\r\n\r\n### `Rate limit exceeded`\r\nBing Ads applies rate limits. The server handles common retries automatically. If you hit limits frequently:\r\n- Batch operations when possible\r\n- Reduce query frequency\r\n- Wait before retrying\r\n\r\n### `Quality Score is 0`\r\nQS = 0 means keyword hasn't been shown enough times yet. Increase impressions or wait for more data.\r\n\r\n## License\r\n\r\nMIT\r\n\r\n## Contributing\r\n\r\nContributions welcome! Please:\r\n1. Add tests for new features\r\n2. Update README\r\n3. Follow existing code style\r\n4. Tag releases\r\n\r\n## Support\r\n\r\n- **Issues:** GitHub issues for bugs/feature requests\r\n- **Docs:** See `docs/` folder for detailed API reference\r\n- **Community:** GitHub Discussions\r\n\r\n---\r\n\r\n## Built By\r\n\r\n**[Mark Harnett](https://www.linkedin.com/in/markharnett/)** — Demand generation leader and paid media practitioner building AI-powered ad management tools. This is the first comprehensive open-source Bing Ads MCP server — born from managing real campaigns across multiple accounts and wanting Claude to do the heavy lifting.\r\n\r\nBuilt with production workloads in mind: resilient API calls (circuit breakers, retry with backoff, response truncation), full Quality Score diagnostics, and negative keyword management at scale.\r\n\r\n**Also by Mark:** [mcp-linkedin-ads](https://github.com/mharnett/mcp-linkedin-ads) -- LinkedIn Ads MCP server with 7 tools.\r\n\r\n**Last Updated:** 2026-03-13\r\n",
  "bytes": 8936,
  "sha": "cd044af6854f59a95ee0097c0231f1ad9898b76e3fa5e3ff4fcfb6e2d848cb59",
  "repo_slug": "mharnett/mcp-bing-ads",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_mharnett_bing_ads_314cb923/readme"
}