Skip to content

Commit cb35116

Browse files
committed
fix: reduce token count of get_account_summaries (closes #69)
Strip redundant fields (name, parent, property_type) from account and property summaries to cut token usage for agencies with many GA4 accounts. Add an optional `query` parameter for case-insensitive display-name filtering so callers can narrow results without post-processing the full list.
1 parent 60bc5f4 commit cb35116

1 file changed

Lines changed: 56 additions & 3 deletions

File tree

analytics_mcp/tools/admin/info.py

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
"""Tools for gathering Google Analytics account and property information."""
1616

17-
from typing import Any, Dict, List
17+
from typing import Any, Dict, List, Optional
1818

1919
from analytics_mcp.tools.utils import (
2020
construct_property_rn,
@@ -24,16 +24,69 @@
2424
)
2525
from google.analytics import admin_v1beta, admin_v1alpha
2626

27+
# Fields stripped from account summaries to reduce token count.
28+
_ACCOUNT_STRIP_FIELDS = {"name"}
29+
_PROPERTY_STRIP_FIELDS = {"name", "parent", "property_type"}
2730

28-
async def get_account_summaries() -> List[Dict[str, Any]]:
29-
"""Retrieves information about the user's Google Analytics accounts and properties."""
31+
32+
def _strip_account_summary(account: Dict[str, Any]) -> Dict[str, Any]:
33+
"""Remove redundant fields from an account summary and its properties."""
34+
cleaned = {k: v for k, v in account.items() if k not in _ACCOUNT_STRIP_FIELDS}
35+
if "property_summaries" in cleaned:
36+
cleaned["property_summaries"] = [
37+
{k: v for k, v in prop.items() if k not in _PROPERTY_STRIP_FIELDS}
38+
for prop in cleaned["property_summaries"]
39+
]
40+
return cleaned
41+
42+
43+
async def get_account_summaries(
44+
query: Optional[str] = None,
45+
) -> List[Dict[str, Any]]:
46+
"""Retrieves the user's Google Analytics accounts and properties.
47+
48+
Returns a compact representation with redundant fields (name, parent,
49+
property_type) stripped to reduce token usage. Each account keeps its
50+
``account`` resource-name and ``display_name``; each property keeps its
51+
``property`` resource-name and ``display_name``.
52+
53+
Args:
54+
query: Optional case-insensitive search string. When provided, only
55+
accounts or properties whose display name contains the query are
56+
returned. An account is included if its own display name matches
57+
**or** any of its properties match; non-matching properties on an
58+
otherwise-matching account are still filtered out.
59+
"""
3060

3161
# Uses an async list comprehension so the pager returned by
3262
# list_account_summaries retrieves all pages.
3363
summary_pager = await create_admin_api_client().list_account_summaries()
3464
all_pages = [
3565
proto_to_dict(summary_page) async for summary_page in summary_pager
3666
]
67+
68+
# Strip redundant fields.
69+
all_pages = [_strip_account_summary(s) for s in all_pages]
70+
71+
# Apply optional display-name filter.
72+
if query:
73+
q = query.lower()
74+
filtered = []
75+
for account in all_pages:
76+
acct_match = q in account.get("display_name", "").lower()
77+
matching_props = [
78+
p
79+
for p in account.get("property_summaries", [])
80+
if q in p.get("display_name", "").lower()
81+
]
82+
if acct_match or matching_props:
83+
account = dict(account)
84+
if not acct_match:
85+
# Only include properties that matched.
86+
account["property_summaries"] = matching_props
87+
filtered.append(account)
88+
all_pages = filtered
89+
3790
return all_pages
3891

3992

0 commit comments

Comments
 (0)