Metadata-Version: 2.5
Name: flin-microsoft-ads-mcp
Version: 0.1.0
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: bingads<14,>=13.0.25
Requires-Dist: mcp<2,>=1.20
Requires-Dist: requests<3,>=2.32
Provides-Extra: dev
Requires-Dist: pytest<10,>=8; extra == 'dev'
Description-Content-Type: text/markdown

# flin-microsoft-ads-mcp

Read-only Microsoft Advertising API v13 reporting in Claude Desktop. Built with the official `bingads` Python SDK (SOAP transport), FastMCP and the same UV/MCPB setup as flin Google Ads MCP.

## Setup

1. Obtain a **production developer token** from the [Microsoft Advertising developer portal](https://developers.ads.microsoft.com/Account). The signed-in Microsoft user must have access to the advertising accounts you want to query.
2. In [Microsoft Entra app registrations](https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade), register your own application. Select **Accounts in any organizational directory and personal Microsoft accounts**. Copy the **Application (client) ID**.
3. 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.
4. [Download the Mac extension](https://github.com/flin-agency/flin-microsoft-ads-mcp/releases/latest/download/flin-microsoft-ads-mcp.mcpb). In Claude Desktop: **Settings → Extensions → Advanced settings → Install Extension…**. Requires a Claude version supporting the MCPB UV runtime. Enter developer token and client ID in settings, never in chat. Default account/customer IDs are optional.
5. Enable the extension and ask Claude to run **`get_auth_url`**. Open its Microsoft URL on the same computer, sign in and grant Microsoft Advertising access. Keep Claude running until the browser confirms completion. Tokens are saved automatically; do not copy tokens or callback URLs into chat.
6. Run **`connection_status(check_live=true)`**, then **`list_accounts`**. Use **Id** as `account_id` and **ParentCustomerId** as `customer_id`. These are numeric API IDs, not the account number.
7. 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 extension resolves stable `>=0.1.0,<0.2` releases. Updates apply after restart, while local tokens persist. Python 3.12 is selected by the extension runtime.

## 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

After PyPI publication, add to `claude_desktop_config.json` (merge with existing servers):

```json
{
  "mcpServers": {
    "flin-microsoft-ads-mcp": {
      "command": "uvx",
      "args": ["--prerelease", "disallow", "--from", "flin-microsoft-ads-mcp>=0.1.0,<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  # public WSDL schema check, 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.0-py3-none-any.whl --expected-version 0.1.0
```

CI tests Python 3.11, 3.12 and 3.13, 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 pending/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 versions, commit, tag `v0.1.0` 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)

The SDK also offers a newer REST package (`msads`); this release deliberately uses the separately distributed `bingads` SOAP SDK and its reporting manager.
