Repository navigation
fix(server): drop the redundant inner traceback import (FR-174) - #212
Closed
Avicennasis wants to merge 11 commits into
Closed
Avicennasis wants to merge 11 commits into
Avicennasis wants to merge 11 commits into
Conversation
Audience exports (Data API v1beta, analytics.readonly-compatible): create_audience_export starts the async export job and returns the operation metadata for polling; get/list/query retrieve state and user rows. Measurement Protocol (plain HTTP, write-capable): validate_event hits only the debug endpoint and never records data. send_event is guarded for AI callers — the API secret comes solely from the ANALYTICS_MCP_MP_API_SECRET env var, dry-run validation is the default, recording requires an explicit confirm=True, and even confirmed sends abort if validation fails.
Fixes from a stargazer review of the server: - coordinator: call_mcp_tool now returns CallToolResult(content=[...], isError=True) on both failure paths (tool raised, and tool-not-found) instead of a plain TextContent that MCP clients read as a *successful* response. This is the one genuinely client-observable fix — clients can now detect failures programmatically. [FR-179] - coordinator: drop the unused `from json import tool` import, which bound `tool` to the json.tool CLI module only for it to be shadowed by later `for tool in ...` loops. [FR-173] - client: `except:` -> `except Exception:` in the package-version fallback so Ctrl-C / SystemExit are no longer swallowed into "unknown". [FR-175] - reporting (core, realtime, audience_exports, conversions): replace truthy `if limit:` / `if offset:` / `if currency_code:` guards with `is not None`. NOTE: these RunReportRequest fields are proto3 scalars with no field presence, so offset=0 / limit=0 serialize identically to unset — this is a correctness/consistency cleanup and a guard against presence-aware fields, NOT a behavior change today (verified by comparing serialized requests). [FR-170, FR-171, FR-172, FR-181] Verified: black --check clean; existing suite (19 tests) green; ad-hoc harness confirms isError=True on both failure paths, the success path still returns list[Content], and offset/limit=0 requests are wire-identical to unset.
Rebuilt on top of current main rather than rebased — the original branch's coordinator.py hunk conflicted through an unterminated import statement, so a union merge produced nested open imports. Reapplied the branch's actual additions (imports, three FunctionTool wrappers, three registry entries, three inputSchema clauses) at the correct anchors in main's current file. pivot.py, compatibility.py and their tests are unchanged from the original branch.
Reapplied onto main after #4 (pivot tools) merged — that touched the same coordinator.py registry, so this branch conflicted again. Same four additions at the same anchors; verified the pivot registrations from #4 are still intact (6 references) rather than clobbered. batch_test.py uses asyncio.run() to match the repo's other tests, and black --check -l 80 is clean across all 27 files.
* feat: add list_key_events tool
Lists the key events (conversions) configured for a GA4 property via
the Admin API properties.keyEvents.list method. Read-only; fits the
existing analytics.readonly scope.
* feat: add list_data_streams tool
Lists the data streams (web, Android, iOS) configured for a GA4
property via the Admin API properties.dataStreams.list method,
including platform-specific details such as web measurement IDs.
Read-only; fits the existing analytics.readonly scope.
* feat: add get_metadata tool for the full dimension and metric catalog
Exposes the complete properties.getMetadata response — standard and
custom dimensions and metrics with descriptions, categories, and
deprecation status — so an LLM can discover available fields before
building a report. The existing get_custom_dimensions_and_metrics
tool is unchanged and still returns only custom definitions.
* feat: add list_properties tool
Lists the GA4 properties under an account via the Admin API
properties.list method with a parent account filter. Returns full
property objects (display name, industry, time zone, currency,
service level), complementing the summary info available from
get_account_summaries. Adds a construct_account_rn helper to utils
mirroring construct_property_rn.
* feat: add list_custom_dimensions and list_custom_metrics tools
Lists custom dimensions and metrics via the Admin API, which returns
richer detail than the Data API metadata endpoint: scope, parameter
name, description, measurement unit, and ads personalization /
restricted metric flags. Read-only; fits the existing
analytics.readonly scope.
* feat: add run_access_report tool
Runs a data access report via the Admin API runAccessReport method,
showing who accessed Analytics data, when, and how. Supports both
property-level and account-level entities. Read-only; the method
accepts the analytics.readonly scope.
* feat: add get_data_retention_settings tool
Retrieves a property's data retention settings via the Admin API,
showing how long event-level and user-level data is kept. Helps
answer compliance questions and explains why older data may be
missing from reports. Read-only; fits the existing
analytics.readonly scope.
* feat: add list_audiences tool
Lists the audiences defined on a GA4 property via the Admin API
alpha channel, following the same pattern as the existing
list_property_annotations tool. Read-only; fits the existing
analytics.readonly scope.
* feat: add get_property_quotas tool
Retrieves the current Data API quota snapshot for a property via the
alpha getPropertyQuotasSnapshot method, so callers can check token
consumption before running expensive batches and back off
intelligently. Read-only; fits the existing analytics.readonly
scope.
* fix: validate property ID before constructing the Data API client
get_metadata and get_custom_dimensions_and_metrics both built the client
in the same expression that validated the property ID:
create_data_api_client().get_metadata(
name=f"{construct_property_rn(property_id)}/metadata"
)
Python evaluates create_data_api_client() first, so on any machine without
Application Default Credentials an invalid property ID surfaced as
google.auth.exceptions.DefaultCredentialsError instead of the ValueError
the docstring promises — which is what failed
metadata_test.TestGetMetadata.test_invalid_property_id_raises in CI.
Hoisting the resource-name construction validates the input before any
credential lookup. Verified by running the suite with ADC disabled
(CLOUDSDK_CONFIG pointed at an empty dir): the test fails with
DefaultCredentialsError before this change and passes after, 31/31 green.
traceback is imported at module top; the re-import inside the except block is redundant.
Author
|
Opened against the wrong base by mistake — this is an internal change to our fork (Avicennasis/google-analytics-mcp), not an upstream contribution. Closing. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #48368. Removes the duplicate
import tracebackinside the except block.py_compileclean.