Skip to content

Commit 44528a4

Browse files
committed
Merge branch 'sync-upstream'
# Conflicts: # start.sh
2 parents fbc3a08 + 84e1ce7 commit 44528a4

25 files changed

Lines changed: 1246 additions & 344 deletions

‎.email-allowlist‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ info@pipeboard.co
1313
# pytest decorator false-positive: @pytest.mark.asyncio matches the email regex
1414
# because the diff +@pytest.mark.asyncio has + in the character class
1515
pytest.mark.asyncio
16+
pytest.fixture

‎.github/workflows/ci.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: CI
33

44
on:
55
push:
6-
branches: [ main ]
6+
branches: [ main, sync-upstream ]
77
pull_request:
88
branches: [ main ]
99

@@ -28,7 +28,7 @@ jobs:
2828
deploy:
2929
runs-on: ubuntu-latest
3030
needs: build
31-
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
31+
if: (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/sync-upstream') && github.event_name == 'push'
3232
permissions:
3333
contents: read
3434
packages: write

‎.github/workflows/test.yml‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,13 @@ jobs:
4949
with:
5050
python-version: "3.10"
5151

52-
- name: Check version bump
52+
- name: Check pyproject.toml and server.json versions match
5353
run: |
54-
# This is a simple check - you might want to make it more sophisticated
55-
echo "Current version in pyproject.toml:"
56-
grep "version = " pyproject.toml
54+
PY_VERSION=$(grep -E '^version = ' pyproject.toml | head -1 | sed -E 's/version = "([^"]+)"/\1/')
55+
JSON_VERSION=$(python -c "import json; print(json.load(open('server.json'))['version'])")
56+
echo "pyproject.toml version: $PY_VERSION"
57+
echo "server.json version: $JSON_VERSION"
58+
if [ "$PY_VERSION" != "$JSON_VERSION" ]; then
59+
echo "::error::pyproject.toml ($PY_VERSION) and server.json ($JSON_VERSION) must match. Bump both."
60+
exit 1
61+
fi

‎README.md‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,6 @@ For advanced users who need to self-host, the package can be installed from sour
285285
- `bid_strategy`: Bid strategy (e.g., 'LOWEST_COST_WITHOUT_CAP', 'LOWEST_COST_WITH_MIN_ROAS')
286286
- `bid_constraints`: Bid constraints dict. Required for LOWEST_COST_WITH_MIN_ROAS (e.g., `{"roas_average_floor": 20000}`)
287287
- `start_time`, `end_time`: Optional start/end times (ISO 8601)
288-
- `is_incremental_attribution_enabled`: Set the ad set's "Attribution model" to Incremental (`true`) or Standard (`false`/unset). **Create-only** — Meta silently ignores attempts to change this field on an existing ad set. Pass at creation time or create a new ad set. Maps to the Ads Manager UI dropdown labelled "Attribution model".
289288
- `access_token` (optional): Meta API access token
290289
- Returns: Confirmation with new ad set details
291290

@@ -395,7 +394,6 @@ For advanced users who need to self-host, the package can be installed from sour
395394
- `bid_constraints`: Bid constraints dict. Required for LOWEST_COST_WITH_MIN_ROAS (e.g., `{"roas_average_floor": 20000}`)
396395
- `status`: Update ad set status (ACTIVE, PAUSED, etc.)
397396
- `targeting`: Targeting specifications including targeting_automation
398-
- `is_incremental_attribution_enabled`: The ad set's "Attribution model" (Standard vs Incremental). **Silently ignored on update** — Meta returns success but drops the field, same class as `is_dynamic_creative`. To change the model on an existing ad set, create a new ad set via `create_adset` and pass this field at creation time. Kept here for symmetry.
399397
- `access_token` (optional): Meta API access token (will use cached token if not provided)
400398
- Returns: Confirmation with updated ad set details and a confirmation link
401399

‎meta_ads_mcp/__init__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from meta_ads_mcp.core.server import main
88

9-
__version__ = "1.0.86"
9+
__version__ = "1.0.87"
1010

1111
__all__ = [
1212
'get_ad_accounts',

‎meta_ads_mcp/core/accounts.py‎

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,32 @@ async def get_ad_accounts(access_token: Optional[str] = None, user_id: str = "me
6767
return json.dumps(data, indent=2)
6868

6969

70+
_DEFAULT_ACCOUNT_INFO_FIELDS = (
71+
"id,name,account_id,account_status,amount_spent,balance,currency,age,"
72+
"business_city,business_country_code,timezone_name"
73+
)
74+
75+
7076
@mcp_server.tool()
7177
@meta_api_tool
72-
async def get_account_info(account_id: str, access_token: Optional[str] = None) -> str:
78+
async def get_account_info(account_id: str, access_token: Optional[str] = None,
79+
fields: str = "") -> str:
7380
"""
7481
Get detailed information about a specific ad account.
75-
82+
7683
Args:
7784
account_id: Meta Ads account ID (format: act_XXXXXXXXX)
7885
access_token: Meta API access token (optional - will use cached token if not provided)
86+
fields: Optional comma-separated Graph API fields to return. When provided,
87+
replaces the default field set. Useful for fetching extras like
88+
funding_source_details, spend_cap, is_prepay_account, min_daily_budget,
89+
disable_reason, capabilities. Default fields:
90+
id, name, account_id, account_status, amount_spent, balance, currency,
91+
age, business_city, business_country_code, timezone_name.
92+
For prepaid accounts (is_prepay_account=true, common in Brazil), the
93+
Business Manager "available balance" is the sum of funding_source_details
94+
STORED_BALANCE entries plus coupons — the `balance` field alone is the
95+
amount due to be billed, not the available pre-paid funds.
7996
"""
8097
if not account_id:
8198
return {
@@ -85,13 +102,13 @@ async def get_account_info(account_id: str, access_token: Optional[str] = None)
85102
"example": "Use account_id='act_123456789' or account_id='123456789'"
86103
}
87104
}
88-
105+
89106
account_id = ensure_act_prefix(account_id)
90-
107+
91108
# Try to get the account info directly first
92109
endpoint = f"{account_id}"
93110
params = {
94-
"fields": "id,name,account_id,account_status,amount_spent,balance,currency,age,business_city,business_country_code,timezone_name"
111+
"fields": fields.strip() if fields and fields.strip() else _DEFAULT_ACCOUNT_INFO_FIELDS
95112
}
96113

97114
data = await make_api_request(endpoint, access_token, params)

0 commit comments

Comments
 (0)