Metadata-Version: 2.5
Name: flin-microsoft-ads-mcp
Version: 0.1.1
Summary: Read-only Microsoft Advertising API reporting for Claude Desktop.
Project-URL: Repository, https://github.com/flin-agency/flin-microsoft-ads-mcp
Project-URL: Issues, https://github.com/flin-agency/flin-microsoft-ads-mcp/issues
Author: flin.agency
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.11
Requires-Dist: mcp<3,>=2.3
Requires-Dist: msads<14,>=13.0.31
Requires-Dist: pydantic<3,>=2.14.3
Requires-Dist: requests<3,>=2.34.2
Provides-Extra: dev
Requires-Dist: pytest<10,>=8; extra == 'dev'
Description-Content-Type: text/markdown

# flin-microsoft-ads-mcp

Read-only Microsoft Advertising REST API v13 reporting in Claude Desktop. Built with Microsoft's official `msads` Python SDK, MCPServer and the same UV/MCPB setup as flin Google Ads MCP.

## Setup

You need two values before connecting: a **production developer token** from Microsoft Advertising and an **application (client) ID** from Microsoft Entra. Follow the steps below to obtain both.

### 1. Get a production developer token

1. Open [Microsoft Advertising → Developer settings](https://ads.microsoft.com/cc/Settings/DevSettings). This is the current portal; it replaces the old Developer Portal linked in older guides.
2. Sign in with a Microsoft Advertising user that has the **Super Admin** role. A Microsoft Advertising account is required; if you do not have one, [create it first](https://ads.microsoft.com/).
3. Select the user to associate with the token, then click **Request Token** and complete any requested information. If a universal developer token is already available, use that token.
4. Copy the token for the extension's **Developer token** field in step 3 below. For manual configuration, the corresponding environment variable is `MICROSOFT_ADS_DEVELOPER_TOKEN`.

One **universal developer token** can be used across multiple users and client accounts. It does not grant access to additional advertising accounts: the user who signs in during step 4 must already have access to the accounts you want to query. This server requires a production token; the shared sandbox token will not work.

If you cannot request a token, first check that you are signed in with the correct Microsoft Advertising user and have the **Super Admin** role. See Microsoft's [developer token instructions](https://learn.microsoft.com/en-us/advertising/guides/get-started?view=bingads-13#get-a-developer-token) for details.

### 2. Register the sign-in application

1. Open [Microsoft Entra app registrations](https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade) and register your own application.
2. Select **Accounts in any organizational directory and personal Microsoft accounts**.
3. Copy the **Application (client) ID** for the extension's **OAuth client ID** field.
4. Under **Authentication**, add the **Mobile and desktop applications** platform and redirect URI **`http://localhost/`**.

This public-client authorization-code flow uses PKCE; **no client secret is needed**. Do not register it as a Web application. If your organization restricts app consent, ask its administrator to approve the application.

### 3. Install and configure the extension

1. [Download the Mac extension](https://github.com/flin-agency/flin-microsoft-ads-mcp/releases/latest/download/flin-microsoft-ads-mcp.mcpb).
2. In Claude Desktop, open **Settings → Extensions → Advanced settings → Install Extension…** and select the downloaded file. Requires a Claude version supporting the MCPB UV runtime.
3. Enter the two values in the extension settings:

| Extension setting | Value |
|---|---|
| **Developer token** | Production developer token from Microsoft Advertising (step 1) |
| **OAuth client ID** | Application (client) ID from Microsoft Entra (step 2) |

Enter credentials in settings, never in chat. Leave **Refresh token**, **Default account ID** and **Default customer ID** empty for the initial setup; they are optional.

### 4. Sign in to Microsoft Advertising

1. Enable the extension and ask Claude to run **`get_auth_url`**.
2. Open the returned Microsoft URL on the same computer, sign in with a Microsoft user who has access to the advertising accounts, and grant Microsoft Advertising access.
3. Keep Claude running until the browser confirms completion. Tokens are saved automatically; do not copy tokens or callback URLs into chat.

### 5. Check the connection and select an account

1. Ask Claude to run **`connection_status(check_live=true)`**, then **`list_accounts`**.
2. Use **Id** as `account_id` and **ParentCustomerId** as `customer_id`. These are numeric API IDs, not the account number. You can now save them as optional defaults in the extension settings.
3. Ask for campaigns or a report, for example: «Show campaign spend, clicks and conversions from 2026-11-01 to 2026-11-07 for account ID … and customer ID …».

The extension is macOS-targeted (Apple Silicon and Intel). The Python stdio server can also be configured manually on Windows/Linux. Internet is required at startup; the new extension resolves stable `>=0.1.1,<0.2` releases. Existing 0.1.0 extensions also accept 0.1.1 updates. Updates apply after restart, while local tokens persist. Python 3.12 is selected by the extension runtime.

## Updates and versions

The installed MCPB checks PyPI whenever Claude starts its MCP process. It installs the latest stable **0.1.x** server available there, including bug fixes, before starting. To load an update, fully quit Claude Desktop (**Cmd+Q**) and reopen it. An existing session keeps its current version. Local code changes or a GitHub push alone do not update an installed extension; the new server must be published on PyPI first.

Run **`connection_status(check_live=false)`** to see the actual `server_version`, `api_transport`, `microsoft_sdk_version` and `mcp_sdk_version`. These are the running versions; Claude's extension listing can still show the version of the originally installed MCPB. Saved sign-in tokens remain available after an update.

A new MCPB is needed for launcher/settings changes or to move beyond the configured `<0.2` server range. Ordinary server updates within 0.1.x do not require reinstalling the extension.

Verified package versions on **2026-11-14**:

| Component | Version / transport |
|---|---|
| Microsoft Advertising API | v13, REST/JSON |
| Microsoft Python SDK | `msads` 13.0.31 |
| MCP Python SDK | `mcp` 2.3.0 |
| Requests | 2.34.2 |
| Pydantic | 2.14.3 |

`uv.lock` records the exact tested dependencies. Microsoft [recommends migrating to REST](https://learn.microsoft.com/en-us/advertising/guides/migrate-to-rest?view=bingads-13) before SOAP is retired on January 31, 2027. The `msads` package still uses the Python import namespace `bingads`; do not install the legacy `bingads` package alongside it.

## Tools

| Tool | Purpose |
|---|---|
| `connection_status` | Local configuration/version; optional live check |
| `auth_status` | Local authentication and browser sign-in state |
| `get_auth_url` | Start browser OAuth; localhost callback expires after 10 minutes |
| `clear_auth_token` | Delete local token and cancel pending sign-in |
| `list_accounts` | Accessible accounts, paginated using `page_index` |
| `get_campaigns` | Search, Shopping, Dynamic Search, Audience and Performance Max campaigns |
| `get_ad_groups` | Ad groups in a campaign |
| `get_ads` | Supported ad types and their creative fields |
| `get_keywords` | Configured keywords in an ad group |
| `get_insights` | Account, campaign, ad group, ad, keyword or actual search-term performance |

Reports require inclusive ISO dates (`YYYY-MM-DD`), up to 367 days per request; `daily=true` adds daily rows. Default report timezone is `AmsterdamBerlinBernRomeStockholmVienna` (Swiss local time, including daylight saving). UK and Pacific timezones are also exposed. Metrics retain Microsoft CSV strings; unavailable values are not zero. Spend/revenue use account currency, not micros. Report downloads can take two minutes; SDK authentication can add up to five minutes if Microsoft is unresponsive. Recent data may be incomplete; search queries can be withheld by Microsoft. `truncated=true` means the output limit was reached; narrow dates/scope or increase limit (maximum 1,000). Entity limits cap returned data, not the upstream download. No campaign mutation, arbitrary API execution, bulk download or billing tools are exposed.

## Manual Claude configuration

For a manual installation, add to `claude_desktop_config.json` (merge with existing servers):

```json
{
  "mcpServers": {
    "flin-microsoft-ads-mcp": {
      "command": "uvx",
      "args": ["--prerelease", "disallow", "--upgrade-package", "flin-microsoft-ads-mcp", "--from", "flin-microsoft-ads-mcp>=0.1.1,<0.2", "flin-microsoft-ads-mcp"],
      "env": {
        "MICROSOFT_ADS_DEVELOPER_TOKEN": "YOUR_DEVELOPER_TOKEN",
        "MICROSOFT_ADS_CLIENT_ID": "YOUR_APPLICATION_CLIENT_ID"
      }
    }
  }
}
```

Use an absolute path to `uvx` if Claude cannot find it. On macOS the config is `~/Library/Application Support/Claude/claude_desktop_config.json`; on Windows `%APPDATA%\Claude\claude_desktop_config.json`.

For source checkout, use command `uv`, args `["run", "--directory", "/absolute/path/to/flin-microsoft-ads-mcp", "flin-microsoft-ads-mcp"]` and the same environment.

Optional environment settings:
- `MICROSOFT_ADS_ACCOUNT_ID`, `MICROSOFT_ADS_CUSTOMER_ID`: default API IDs.
- `MICROSOFT_ADS_AUTH_FILE`: defaults to `~/.config/flin-microsoft-ads-mcp/auth.json`.
- `MICROSOFT_ADS_REFRESH_TOKEN`: optional bootstrap token; saved/rotated token takes precedence. Remove it before signing out permanently.
- `MICROSOFT_ADS_OAUTH_REDIRECT_URI`: optional `http://localhost:PORT/`; defaults to a temporary available port. Register `http://localhost/` in Entra.

Production Microsoft accounts are supported. No sandbox or Google-identity sign-in is implemented. No `.env` file is loaded automatically: set process environment variables or use Claude settings.

## Development and release

```sh
uv sync --extra dev
uv run pytest
uv run python scripts/check_api_schema.py  # REST model/JSON checks, no credentials
uv build
uv run python scripts/build_mcpb.py
uv run python scripts/smoke_mcpb.py dist/flin-microsoft-ads-mcp.mcpb --wheel dist/flin_microsoft_ads_mcp-0.1.1-py3-none-any.whl --expected-version 0.1.1
```

CI tests Python 3.11–3.14, validates the REST models, builds distributions and validates the MCPB manifest. Releases on `v*` tags test/build, publish via PyPI Trusted Publishing, smoke-test the published package and attach MCPB/wheel/sdist to GitHub Releases.

PyPI trusted publisher: project **flin-microsoft-ads-mcp**, owner **flin-agency**, repository **flin-microsoft-ads-mcp**, workflow **release.yml**, environment **pypi** (an unrestricted publisher also matches). No PyPI token secret is needed. To release: match project/manifest/desktop/server versions, commit, tag `v0.1.1` and push the tag.

See [testing](docs/testing.md), [desktop setup](docs/claude-desktop-mac.md), [privacy](PRIVACY.md), [security](SECURITY.md), and [support](SUPPORT.md).

## API references

- [Microsoft OAuth application registration](https://learn.microsoft.com/en-us/advertising/guides/authentication-oauth-register?view=bingads-13)
- [Microsoft SDK authentication](https://learn.microsoft.com/en-us/advertising/guides/sdk-authentication?view=bingads-13)
- [SearchAccounts](https://learn.microsoft.com/en-us/advertising/customer-management-service/searchaccounts?view=bingads-13)
- [Reporting service](https://learn.microsoft.com/en-us/advertising/reporting-service/reporting-service-reference?view=bingads-13)

- [Microsoft Python REST SDK migration](https://learn.microsoft.com/en-us/advertising/guides/python-sdk-migration-soap-to-rest?view=bingads-13)
- [MCP Python SDK v2 migration](https://github.com/modelcontextprotocol/python-sdk/blob/main/docs/migration.md)
