microsoft-ads-mcp
MCP server for Microsoft Advertising (Bing Ads) REST API enabling agent-led campaign management and reporting. It provides tools to manage campaigns, ad groups, keywords, ads, budgets, and pull performance reports.
README
microsoft-ads-mcp
An MCP server for the Microsoft Advertising (Bing Ads) REST API, built for agent-led campaign management and reporting. It exposes a focused set of useful-work tools — walk the campaign tree, add keywords/ads, manage budgets and status, and pull performance reports that are actually downloaded and parsed for you — rather than a 1:1 mirror of the API surface.
Built with FastMCP and the official Microsoft
msads REST SDK (which ships OpenAPI-generated Pydantic
v2 models). Managed with uv, linted/formatted with ruff, type-checked with ty.
This is a ground-up rewrite of the original single-file
server.py, restructured to mirror the architecture of its sibling projectopenai-ads-mcp.
Why REST / msads (not the legacy SOAP bingads SDK)
Microsoft is retiring the SOAP API: new features are REST-only from Oct 1, 2026, and SOAP
is fully deprecated on Jan 31, 2027 (migration guide).
The REST SDK msads gives typed Pydantic models, structured HTTP exceptions, and the same
OAuth/ServiceClient entry points — so this server is built on it directly.
SDK quirks worth knowing
msadsis synchronous (requests/urllib3). Tools here are therefore plain sync functions; FastMCP runs them in a worker thread, so the event loop is never blocked. We do not wrap the SDK in async.msadsdoes not declare itspython-dateutildependency, even thoughopenapi_clientimports it. We pinpython-dateutilexplicitly inpyproject.toml.- The package installs as the
bingads.*(auth +ServiceClient) andopenapi_client.*(models + exceptions) import namespaces — there is no top-levelmsadsmodule.
Quickstart
uv sync # create .venv and install
cp .env.example .env # then set the credentials below
uv run python -m microsoft_ads_mcp # run over stdio (default)
Configuration
Set via environment variables or a local .env (see .env.example):
| Variable | Required | Notes |
|---|---|---|
MICROSOFT_ADS_DEVELOPER_TOKEN |
yes | From the developer portal |
MICROSOFT_ADS_CLIENT_ID |
yes | Azure AD app (client) id |
MICROSOFT_ADS_REFRESH_TOKEN |
recommended | Run non-interactively; else mint one via the auth tools |
MICROSOFT_ADS_CLIENT_SECRET |
no | Only for web/confidential app registrations |
MICROSOFT_ADS_ACCOUNT_ID / MICROSOFT_ADS_CUSTOMER_ID |
no | Discovered via search_accounts if unset |
MICROSOFT_ADS_ENVIRONMENT |
no | production (default) or sandbox |
READ_ONLY |
no | true registers no write tools at all (default false) |
Refresh tokens are persisted to ~/.config/microsoft-ads/tokens.json, created with 0600
permissions (owner read/write only).
Authentication
If you have no refresh token yet, mint one once (interactive):
- Call
get_auth_url()→ open the URL, sign in. - Copy the redirect URL and call
complete_auth(redirect_url). - The refresh token is saved and reused/auto-refreshed thereafter.
MCP client configuration
{
"mcpServers": {
"microsoft-ads": {
"type": "stdio",
"command": "uv",
"args": ["run", "--directory", "${CLAUDE_PROJECT_DIR:-.}", "python", "-m", "microsoft_ads_mcp"],
"env": {
"MICROSOFT_ADS_DEVELOPER_TOKEN": "...",
"MICROSOFT_ADS_CLIENT_ID": "...",
"MICROSOFT_ADS_REFRESH_TOKEN": "...",
"READ_ONLY": "false"
}
}
}
}
Tools
Call account_health first to validate credentials and learn whether writes are enabled.
Read — account_health, search_accounts, account_overview, get_campaigns,
get_ad_groups, get_keywords, get_ads, get_budgets.
Reporting — run_performance_report (submit → poll → download → parse, returns rows),
covering campaign / keyword / search-query / geographic reports.
Write (only when READ_ONLY=false) — create_campaign, update_campaign_status,
create_ad_group, add_keywords, create_responsive_search_ad.
Architecture
src/microsoft_ads_mcp/
config.py # pydantic-settings; all env config
server.py # builds FastMCP, lifespan-manages the client, registers tools
api/
auth.py # OAuth flow + hardened token store
client.py # wraps msads ServiceClient(s); the single dispatch point
errors.py # translate openapi_client exceptions -> MsAdsApiError
domain/
entities.py # lean Pydantic summary/report models for tool outputs
services/
campaigns.py # hierarchy + list reads
mutations.py # create/update flows
reporting.py # submit/poll/download/parse
tools/
health.py read_tools.py write_tools.py reporting_tools.py # registered, READ_ONLY-gated
Development
uv run ruff check . && uv run ruff format --check .
uv run ty check
uv run pytest -q
# or all at once:
bash scripts/ci.sh
License
MIT — see LICENSE.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.