feat: add 'login_customer_id' support to enable Manager Account access#10
feat: add 'login_customer_id' support to enable Manager Account access#10balikasg wants to merge 2 commits intogoogleads:mainfrom
Conversation
This commit enables the tool to accept an optional parameter. This is required when accessing client accounts via a Manager Account, as the Google Ads API demands the header in such cases. Changes: - Updated to dynamically create/retrieve a GoogleAdsClient with the specific if provided. - Updated to accept the argument and pass it to the service factory. - Added tool documentation hints.
| conditions: List[str] = None, | ||
| orderings: List[str] = None, | ||
| limit: int | str = None, | ||
| login_customer_id: str = None, |
There was a problem hiding this comment.
The core of this PR. Add support and propagate properly in the project for this parameter.
| """Tests that output values are formatted correctly.""" | ||
|
|
||
| client = utils.get_googleads_client() | ||
| client = utils._get_googleads_client() |
There was a problem hiding this comment.
This is a typo..
Once fixed the tests are green:
OK
nox > Session tests-3.13 was successful in 34 seconds.
nox > Ran 4 sessions in 2 minutes:
nox > * tests-3.10: success, took 35 seconds
nox > * tests-3.11: success, took 31 seconds
nox > * tests-3.12: success, took 34 seconds
nox > * tests-3.13: success, took 34 seconds|
@DeanLukies any chance you could take a look at this? |
|
Does anyone check this? |
|
Hi, thanks for looking into this! We are evaluating adding this feature in a future version of the MCP server, but we won't be doing so right now. Thanks. |
… improvements - utils.py: add login_customer_id per-request param to get_googleads_client/get_googleads_service, add create_field_mask helper, fix format_output_value to handle proto.Message and repeated fields, add lazy _default_client caching (from PR googleads#26 + PR googleads#10) - campaigns.py: add path1/path2 display URL paths to create_responsive_search_ad, add update_ad_group (name update), add set_ad_schedule (dayparting) (from PR googleads#39) - tools/assets.py (new): 10 asset creation tools — sitelink, callout, structured_snippet, call, image, promotion, price, lead_form, text, youtube_video (from PR googleads#39) - tools/asset_links.py (new): link_asset_to_campaign, link_asset_to_ad_group, link_assets_to_customer, remove_campaign_asset (from PR googleads#39) - server.py: import assets and asset_links modules Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ZLeventer
left a comment
There was a problem hiding this comment.
This is a critical feature for anyone running Google Ads through a Manager (MCC) account — which is the standard setup for agencies and most mid-to-large advertisers. Without login_customer_id, the MCP server can only access the account whose credentials are in the env, which is a dealbreaker for multi-account setups.
The implementation looks clean:
- Falls back to
_get_login_customer_id()(env var) when no param is passed, preserving backward compat - Creates a fresh client when a custom
login_customer_idis provided rather than mutating the cached one — good call, avoids state leakage between calls - Test update to use the private
_get_googleads_clientis correct since the public wrapper now has a different signature
One suggestion: the hint text says "Required when accessing a client account through a Manager Account" — worth noting it should also be the Manager Account's own customer ID, not the client account's ID. That distinction trips people up.
This PR adds support for the login_customer_id parameter in the search tool. This is critical for users accessing Client Accounts via a Manager Account, as the Google Ads API explicitly requires the login-customer-id header to be set for these requests.
Problem
Currently, attempting to query a client account (customer_id) while authenticated as a Manager Account results in a USER_PERMISSION_DENIED error with the message to pass a login_customer_id as part of the headers. This happens because the default client initialization uses the global configuration without the specific login-customer-id context required for hierarchy traversal. The MCPs do not currently support passing this information and this PR adds this functionality.