microsoft-ads-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@microsoft-ads-mcpshow me my campaigns"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.
Related MCP server: synter-mcp-server
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 |
| yes | From the developer portal |
| yes | Azure AD app (client) id |
| recommended | Run non-interactively; else mint one via the auth tools |
| no | Only for web/confidential app registrations |
| no | Discovered via |
| no |
|
| no |
|
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-gatedDevelopment
uv run ruff check . && uv run ruff format --check .
uv run ty check
uv run pytest -q
# or all at once:
bash scripts/ci.shLicense
MIT — see LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/shinypebble/microsoft-ads-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server