55from .api import meta_api_tool , make_api_request
66from .server import mcp_server
77
8+ # Currencies that have no sub-units (i.e., are not denominated in cents).
9+ # Meta API returns amount_spent and balance as integers in the smallest currency
10+ # unit, which is cents for most currencies but the base unit for these.
11+ _ZERO_DECIMAL_CURRENCIES = {
12+ "BIF" , "CLP" , "DJF" , "GNF" , "JPY" , "KMF" , "KRW" , "MGA" ,
13+ "PYG" , "RWF" , "UGX" , "VND" , "VUV" , "XAF" , "XOF" , "XPF" ,
14+ }
15+
16+
17+ def _cents_to_currency (amount , currency : str ) -> str :
18+ """Convert a Meta API monetary value (cents) to a currency-unit string.
19+
20+ Meta returns amount_spent and balance as integers representing the smallest
21+ currency unit (cents for USD/EUR/GBP, base unit for zero-decimal currencies
22+ like JPY). This converts to the human-readable decimal amount.
23+ """
24+ try :
25+ amount_int = int (amount )
26+ except (TypeError , ValueError ):
27+ return str (amount )
28+ if currency .upper () in _ZERO_DECIMAL_CURRENCIES :
29+ return str (amount_int )
30+ return f"{ amount_int / 100 :.2f} "
31+
32+
33+ def _normalize_account_monetary_fields (account : dict ) -> dict :
34+ """Convert amount_spent and balance from cents to currency units in-place."""
35+ currency = account .get ("currency" , "USD" )
36+ for field in ("amount_spent" , "balance" ):
37+ if field in account :
38+ account [field ] = _cents_to_currency (account [field ], currency )
39+ return account
40+
841
942@mcp_server .tool ()
1043@meta_api_tool
1144async def get_ad_accounts (access_token : Optional [str ] = None , user_id : str = "me" , limit : int = 200 ) -> str :
1245 """
1346 Get ad accounts accessible by a user.
14-
47+
48+ amount_spent and balance are returned in currency units (e.g. USD dollars),
49+ not cents.
50+
1551 Args:
1652 access_token: Meta API access token (optional - will use cached token if not provided)
1753 user_id: Meta user ID or "me" for the current user
@@ -22,9 +58,12 @@ async def get_ad_accounts(access_token: Optional[str] = None, user_id: str = "me
2258 "fields" : "id,name,account_id,account_status,amount_spent,balance,currency,age,business_city,business_country_code" ,
2359 "limit" : limit
2460 }
25-
61+
2662 data = await make_api_request (endpoint , access_token , params )
27-
63+
64+ if "data" in data :
65+ data ["data" ] = [_normalize_account_monetary_fields (acc ) for acc in data ["data" ]]
66+
2867 return json .dumps (data , indent = 2 )
2968
3069
@@ -58,7 +97,7 @@ async def get_account_info(account_id: str, access_token: Optional[str] = None)
5897 }
5998
6099 data = await make_api_request (endpoint , access_token , params )
61-
100+
62101 # Check if the API request returned an error
63102 if "error" in data :
64103 # If access was denied, provide helpful error message with accessible accounts
@@ -89,6 +128,8 @@ async def get_account_info(account_id: str, access_token: Optional[str] = None)
89128 # Return the original error for non-permission related issues
90129 return data
91130
131+ _normalize_account_monetary_fields (data )
132+
92133 # Add DSA requirement detection
93134 if "business_country_code" in data :
94135 european_countries = ["DE" , "FR" , "IT" , "ES" , "NL" , "BE" , "AT" , "IE" , "DK" , "SE" , "FI" , "NO" ]
0 commit comments