Skip to main content
Glama
rakoo04

analytics-mcp-server

by rakoo04

ga4-gsc-clarity-mcp-server

An MCP server that gives Claude read access to Google Analytics 4 (GA4), Google Search Console (GSC), and Microsoft Clarity — set up once, reusable from any project.

How it's scalable across projects

Connections (a Google account, a Clarity project token) are stored in ~/.analytics-mcp-server/, not inside this repo or any single project. You register the server once with claude mcp add --scope user, and every Claude Code project on your machine can then use list_connections and the ga4_* / gsc_* / clarity_* tools against any connection by name — no per-project setup, no re-authenticating for each new site or repo. Adding a new GA4 property, GSC site, or Clarity project later is just another npm run cli -- add-* call; no code changes needed.

Related MCP server: mcp-marketing-analytics

Important note on auth

Google's GA4 and Search Console APIs support OAuth, and this server uses it. Microsoft Clarity's Data Export API does not support OAuth — Clarity only issues per-project API tokens from its dashboard (Settings → Data Export), capped at 10 requests/day/token. Clarity connections in this server use that token, stored the same way as Google's refresh tokens. This is a limitation of Clarity's API, not a design choice here.

Setup

1. Install

npm install
npm run build

2. Create a Google OAuth client (for GA4 + Search Console)

  1. In Google Cloud Console, create/select a project.

  2. Enable these APIs: Google Analytics Admin API, Google Analytics Data API, Search Console API.

  3. Create an OAuth client with type Desktop app.

  4. Copy .env.example to .env and fill in GOOGLE_OAUTH_CLIENT_ID / GOOGLE_OAUTH_CLIENT_SECRET.

3. Add connections

Each connection is added once via the CLI, which handles secrets outside of any LLM conversation.

# Opens a browser for Google consent, stores a refresh token under the given name.
npm run cli -- add-google my-google         # both GA4 + GSC scopes
npm run cli -- add-google my-google --ga4   # GA4 only
npm run cli -- add-google my-google --gsc   # GSC only

# Stores a Clarity project token (generate one at https://clarity.microsoft.com,
# Settings > Data Export).
npm run cli -- add-clarity my-site --token <token> --label "My Site"

npm run cli -- list
npm run cli -- remove <name>

You can add as many named connections as you like — multiple Google accounts, multiple Clarity projects — and refer to any of them from any project by name.

4. Register the MCP server with Claude Code

claude mcp add --scope user analytics-mcp-server \
  --env GOOGLE_OAUTH_CLIENT_ID=<your-client-id> \
  --env GOOGLE_OAUTH_CLIENT_SECRET=<your-client-secret> \
  -- node /absolute/path/to/analytics-mcp-server/dist/src/index.js

--scope user makes it available in every project, which is the point — connections live outside any repo, so this only needs to be done once per machine.

Tools

Tool

Purpose

list_connections

List configured connections by name

ga4_list_properties

List GA4 properties visible to a Google connection

ga4_run_report

Run a historical GA4 report (dimensions/metrics/date range)

ga4_run_realtime_report

Run a GA4 realtime (~last 30 min) report

gsc_list_sites

List Search Console properties visible to a Google connection

gsc_query_search_analytics

Query clicks/impressions/CTR/position by dimension

gsc_inspect_url

Check a URL's index status

clarity_get_insights

Fetch Clarity traffic/engagement metrics (1-3 day window, cached hourly)

Adding another provider later

Follow the existing pattern to extend this to a new service (e.g. Meta Ads, another analytics tool):

  1. src/providers/<service>.ts — API client functions, no MCP-specific code.

  2. src/tools/<service>Tools.tsregisterTool calls that wrap the provider functions.

  3. Register the new tools in src/index.ts.

  4. If it needs OAuth, add a run<Service>InteractiveAuth in src/auth/ and an add-<service> command in scripts/cli.ts, following googleOAuth.ts. If it only needs an API key/token, just add it to ConnectionStore's Connection union and a CLI command, like Clarity.

Development

npm run dev     # run the server with auto-reload (tsx)
npm run build   # type-check + compile to dist/

Available Tools

8 tools
clarity_get_insightsGet Microsoft Clarity InsightsA
Read-onlyIdempotent

Fetch Microsoft Clarity's traffic and engagement metrics (sessions, bots, engagement time, scroll depth, rage clicks, quick backs, dead clicks, script errors, and more) for a connected Clarity project, optionally broken down by up to 3 dimensions.

Note: Clarity connections authenticate with a per-project API token generated in the Clarity dashboard (Settings > Data Export), not OAuth — Clarity's Data Export API does not support OAuth. Each token is capped at 10 requests/day; this tool caches results for 1 hour to help stay under that limit.

Args:

  • connection (string): Name of a configured Clarity connection

  • num_of_days (1 | 2 | 3): How many trailing days of data to fetch (Clarity only supports 1-3)

  • dimensions (string[], optional): Up to 3 of: Browser, Device, Country, OS, Source, Medium, Campaign, Channel, URL, PageTitle. Omit for totals with no breakdown.

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Returns raw per-metric breakdowns as reported by Clarity, e.g. one entry per metric name ("Traffic", "EngagementTime", "ScrollDepth", "DeadClickCount", ...) each with an "information" array of rows for the requested dimension breakdown.

Use when: "How is Clarity engagement trending by device over the last 3 days?" -> dimensions=["Device"] Don't use when: You need historical data beyond 3 days (Clarity's export API doesn't support that; use the Clarity dashboard/UI instead).

Error Handling:

  • Returns "Clarity API rate limit reached" if the project's 10-requests/day cap is hit; wait and retry, or reuse a cached result.

ParametersJSON Schema
NameRequiredDescriptionDefault
connectionYes
dimensionsNo
num_of_daysNo
response_formatNomarkdown

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry readOnlyHint=true and idempotentHint=true, and the description adds substantial context beyond these: the per-project API-token auth model (explicitly noting Data Export API does not support OAuth), the 10-requests/day cap, 1-hour result caching, and the exact 'Clarity API rate limit reached' error string. The disclosed behavior is consistent with readOnlyHint (fetch-only, non-destructive), so no contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded and the body is organized into labeled sections (Args, Returns, Use when, Don't use when, Error Handling), making it skimmable for an agent. Minor redundancy: the 10-requests/day cap and caching are stated twice (in the auth note and implied in error handling). Slightly long but every section earns its place given the rate-limit stakes.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description appropriately documents the return shape (raw per-metric breakdowns with an 'information' array per metric name). It covers authentication prerequisites, rate limiting, caching, error behavior, parameter semantics, and usage boundaries. Nothing an agent needs to call this correctly is missing for a read-only metrics tool of this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the full burden, and it does: connection is explained as a 'configured' connection, num_of_days gains the constraint rationale ('Clarity only supports 1-3'), dimensions gains the critical semantic 'Omit for totals with no breakdown' beyond the bare enum, and response_format's default is surfaced. Slight redundancy in re-listing the dimensions enum, but the added meaning fully compensates for the absent schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb + resource ('Fetch Microsoft Clarity's traffic and engagement metrics... for a connected Clarity project') and enumerates the concrete metric types (sessions, rage clicks, dead clicks, script errors). This clearly distinguishes it from sibling analytics tools targeting different platforms (ga4_run_report, gsc_query_search_analytics), so an agent can route correctly without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides an explicit 'Use when' rule with a concrete example query mapped to a parameter value ("How is Clarity engagement trending by device over the last 3 days?" -> dimensions=['Device']), plus a 'Don't use when' exclusion naming the limitation (3-day API bound) and the fallback (Clarity dashboard/UI). This is exactly the routing guidance required.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ga4_list_propertiesList GA4 PropertiesA
Read-onlyIdempotent

List every Google Analytics 4 property the connected Google account can access.

Args:

  • connection (string): Name of a configured Google connection (see list_connections)

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Returns property IDs needed by ga4_run_report and ga4_run_realtime_report.

Use when: "What GA4 properties do I have access to?" or to look up a property_id by site name before running a report.

ParametersJSON Schema
NameRequiredDescriptionDefault
connectionYesName of a configured Google connection
response_formatNomarkdown

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint: false. The description adds useful context beyond those: it clarifies that results depend on the connected account, that property IDs are returned for downstream report tools, and that connection must be configured. This is meaningful supplementary behavior for a read-only list tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and well-organized: a one-sentence purpose, then Args, Returns, and Use when sections. Every sentence contributes useful information, and the purpose is front-loaded immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple listing tool, the description covers all needed operational context: required connection, output format choice, what the return value is used for, and when to invoke it. Annotations cover the safety profile, so no critical guidance is missing even without an output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%, so the description partially compensates: it notes connection is a configured Google connection and points to list_connections. For response_format, it restates the enum and default already present in the schema without adding deeper meaning such as when to pick one format over the other. This is adequate but not additive.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'List every Google Analytics 4 property the connected Google account can access.' This clearly distinguishes the tool from siblings by naming GA4 properties specifically, and the scope ('every...can access') is precise.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit use cases: 'What GA4 properties do I have access to?' and looking up a property_id before running a report. It also references list_connections for connection setup. It does not explicitly state when not to use the tool or name an alternative for excluded cases, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ga4_run_realtime_reportRun GA4 Realtime ReportA
Read-onlyIdempotent

Run a Google Analytics 4 realtime report, covering roughly the last 30 minutes of activity.

Args:

  • connection (string): Name of a configured Google connection

  • property_id (string): GA4 property ID (from ga4_list_properties)

  • dimensions (string[]): Realtime dimension API names, e.g. ["country", "unifiedScreenName"]

  • metrics (string[]): Realtime metric API names, e.g. ["activeUsers", "screenPageViews"]

  • limit (number): Max rows to return (default 20, max 250)

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Note: only a subset of GA4 dimensions/metrics support realtime reporting — see https://developers.google.com/analytics/devguides/reporting/data/v1/realtime-api-schema

Use when: "How many people are on the site right now?" or "What pages are active users viewing at this moment?" Don't use when: You need historical trends (use ga4_run_report instead).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
metricsYes
connectionYes
dimensionsYes
property_idYes
response_formatNomarkdown

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint=true, idempotentHint=true, destructiveHint=false). The description adds valuable behavioral context beyond that: the 30-minute time windowchend, the warning that only a subset of GA4 dimensions/metrics support realtime reporting, and the output format default. This goes beyond annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is structured with an overview sentence, an args block, a note, and explicit use/don't-use guidance. Each section earns its place, and the front-loaded purpose sentence allows an agent to quickly understand the tool without digging further. The length is justified given the 0% schema coverage and the need to convey realtime-specific constraints.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers all required parameters, defaults, constraints, and gives a pointer to the official realtime API schema for supported dimensions/metrics. It distinguishes from ga4_run_report. The only minor gap is that it doesn't describe the structure of the returned markdown or json report, and since there's no output schema, a brief note on the report shape would make it fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description fully compensates by listing every parameter with a plain-language explanation. It clarifies critical semantics such as 'Realtime dimension API names' with examples, limit max/default, and the response_format enum. It even references ga4_list_properties as the source for property_id, giving extra meaning beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Run a Google Analytics 4 realtime report.' It also disambiguates from the likely sibling by explicitly framing it as covering 'roughly the last 30 minutes of activity' and later contrasting it with ga4_run_report for historical trends. This leaves no doubt about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage guidance with concrete query examples: 'Use when: "How many people are on the site right now?"' and 'Don't use when: You need historical trends (use ga4_run_report instead).' This directly tells an agent when to select this tool over an alternative, meeting the highest bar for this dimension.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ga4_run_reportRun GA4 ReportA
Read-onlyIdempotent

Run a Google Analytics 4 report over a historical date range, similar to a custom report in the GA4 UI.

Args:

  • connection (string): Name of a configured Google connection

  • property_id (string): GA4 property ID (from ga4_list_properties), digits only, no "properties/" prefix

  • start_date, end_date (string): YYYY-MM-DD, or a GA4 relative keyword such as 'today', 'yesterday', or 'NdaysAgo' (e.g. '28daysAgo')

  • dimensions (string[]): GA4 dimension API names, e.g. ["date", "country", "sessionDefaultChannelGroup"]

  • metrics (string[]): GA4 metric API names, e.g. ["activeUsers", "sessions", "conversions"]

  • limit (number): Max rows to return (default 50, max 1000)

  • offset (number): Rows to skip, for pagination (default 0)

  • dimension_filter_field, dimension_filter_value (string, optional): Restrict to rows where this dimension exactly equals this value

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Full dimension/metric reference: https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema

Returns: For JSON: { "dimensionHeaders": string[], "metricHeaders": string[], "rows": object[], "rowCount": number }

Use when: "How many sessions did we get last week by channel?" -> dimensions=["sessionDefaultChannelGroup"], metrics=["sessions"], start_date/end_date set accordingly. Don't use when: You need live/last-30-minutes data (use ga4_run_realtime_report instead).

Error Handling:

  • Returns an error naming the invalid dimension/metric if GA4 rejects the combination (not every dimension and metric can be combined).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo
metricsYesGA4 metric API names
end_dateYesYYYY-MM-DD, or a GA4 relative keyword such as 'today', 'yesterday', or 'NdaysAgo' (e.g. '28daysAgo')
connectionYes
dimensionsYesGA4 dimension API names
start_dateYesYYYY-MM-DD, or a GA4 relative keyword such as 'today', 'yesterday', or 'NdaysAgo' (e.g. '28daysAgo')
property_idYesGA4 property ID, digits only
response_formatNomarkdown
dimension_filter_fieldNoDimension name to filter on
dimension_filter_valueNoExact value to match, paired with dimension_filter_field

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool read-only, idempotent, and non-destructive. The description adds meaningful behavioral context beyond annotations: historical-only scope, pagination via limit/offset, JSON return shape, and the specific failure mode where GA4 rejects invalid dimension/metric combinations. No contradiction with annotations exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but efficiently organized with clear sections (Args, Returns, Use when, Error Handling) and every line carries operational value. It front-loads the core purpose and then provides scannable details without filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 11-parameter reporting tool with no output schema, the description is highly complete: it covers input semantics, output JSON shape, error behavior, default response format, and pagination. The markdown output shape is not detailed, but the description gives enough context for correct selection and invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Despite 64% schema coverage, the description adds substantial parameter meaning: property_id format and source, date keyword forms, GA4 API names for dimensions/metrics with examples, the exact-match semantics of the filter pair, and limit/offset defaults. This goes well beyond what the schema alone provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and resource: 'Run a Google Analytics 4 report over a historical date range, similar to a custom report in the GA4 UI.' It also references ga4_list_properties for property IDs and explicitly contrasts with ga4_run_realtime_report, making it distinguishable from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives both an explicit 'Use when' example ('How many sessions did we get last week by channel?') with concrete dimension/metric guidance and a 'Don't use when' condition that names the alternative tool ga4_run_realtime_report for live data. This fully satisfies when-to-use and when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gsc_inspect_urlInspect URL in Search ConsoleA
Read-onlyIdempotent

Check a single URL's Google index status via the Search Console URL Inspection API: whether it's indexed, when it was last crawled, and why it might not be indexed.

Args:

  • connection (string): Name of a configured Google connection

  • site_url (string): Exact site URL from gsc_list_sites that owns inspection_url

  • inspection_url (string): Full URL to inspect, must belong to site_url

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Use when: "Why isn't this page showing up in Google?" or "Is this URL indexed?" Don't use when: You need aggregate query/click data (use gsc_query_search_analytics instead).

ParametersJSON Schema
NameRequiredDescriptionDefault
site_urlYes
connectionYes
inspection_urlYes
response_formatNomarkdown

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish that the tool is read-only, idempotent, and non-destructive, so the description does not need to repeat safety behavior. It adds useful context about what the inspection returns and the required relationship between site_url and inspection_url, though it does not mention API quotas or edge-case failure modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with a single-sentence purpose, followed by a compact Args block and Use/Don't-use guidance. Every sentence adds decision-relevant information with minimal redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a four-parameter read-only inspection tool, the description provides the purpose, parameter meanings, expected result dimensions, and sibling routing. Even without an output schema, the response content is summarized well enough for an agent to invoke the tool and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the Args section compensates by explaining each parameter: connection must be configured, site_url comes from gsc_list_sites, inspection_url must belong to site_url, and response_format has a default. It could add a concrete URL example or error conditions, but the core semantics are present.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a concrete verb and resource — 'Check a single URL's Google index status' — and lists the diagnostic outputs (indexed, last crawled, why not indexed). It also contrasts with gsc_query_search_analytics, making it easy for an agent to distinguish this tool from its siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit triggers ('Why isn't this page showing up in Google?', 'Is this URL indexed?') and an explicit exclusion with the alternative tool to use instead. This is clear when-to-use/when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gsc_list_sitesList Search Console SitesA
Read-onlyIdempotent

List every Search Console property (site or domain) the connected Google account can access.

Args:

  • connection (string): Name of a configured Google connection

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Returns site URLs (e.g. "https://example.com/" or "sc-domain:example.com") needed by gsc_query_search_analytics and gsc_inspect_url.

Use when: "What Search Console properties do I have access to?"

ParametersJSON Schema
NameRequiredDescriptionDefault
connectionYes
response_formatNomarkdown

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is well covered. The description adds useful behavioral context: it lists every accessible property for the connected account and explains that the returned site URLs are prerequisites for other Search Console tools. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with the main purpose. The Args section is compact and scannable, the return value is explained with concrete examples, and the 'Use when' line adds a practical trigger without wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with two parameters, the description is largely complete: it states what the tool returns, gives example values, names downstream consumers, and provides a use case. The absence of an output schema is partially mitigated by the return-value explanation. Minor gaps include not mentioning pagination or the exact JSON structure when response_format is 'json', but these are not critical for a simple listing tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description compensates by explaining both parameters: 'connection' is the name of a configured Google connection, and 'response_format' is the output format with default 'markdown'. This adds meaning beyond the raw schema, especially for the connection parameter. It could be improved by noting possible values for connection, though that may come from list_connections.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and resource ('every Search Console property (site or domain) the connected Google account can access'). It clearly distinguishes this from GA4 siblings by naming Search Console, and it explains the returned site URLs are needed by gsc_query_search_analytics and gsc_inspect_url, further differentiating it from those tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides an explicit 'Use when' statement with a concrete user question: 'What Search Console properties do I have access to?'. It also notes the output is needed by sibling tools, giving practical context. It does not explicitly say when not to use it or mention alternatives like ga4_list_properties, but the use case is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gsc_query_search_analyticsQuery Search Console Search AnalyticsA
Read-onlyIdempotent

Query Google Search Console's Search Analytics data: clicks, impressions, CTR, and average position, broken down by dimensions.

Args:

  • connection (string): Name of a configured Google connection

  • site_url (string): Exact site URL from gsc_list_sites (e.g. "sc-domain:example.com")

  • start_date, end_date (string): YYYY-MM-DD. Search Console data typically lags 2-3 days behind today.

  • dimensions (string[]): Any of "query", "page", "country", "device", "date", "searchAppearance" (default: ["query"])

  • row_limit (number): Max rows (default 25, max 25000)

  • start_row (number): Rows to skip, for pagination (default 0)

  • search_type ('web' | 'image' | 'video' | 'news' | 'discover' | 'googleNews'): default 'web'

  • filter_dimension, filter_operator, filter_value: Optional single filter, e.g. filter_dimension="page", filter_operator="contains", filter_value="/blog/"

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Returns: For JSON: { "rows": [{ "keys": string[], "clicks": number, "impressions": number, "ctr": number, "position": number }] } "keys" holds one value per requested dimension, in the same order as the "dimensions" argument.

Use when: "What are our top search queries this month?" -> dimensions=["query"] Use when: "Which pages get the most impressions but low CTR?" -> dimensions=["page"], sort client-side on the returned rows. Don't use when: You need page indexing status (use gsc_inspect_url instead).

ParametersJSON Schema
NameRequiredDescriptionDefault
end_dateYes
site_urlYes
row_limitNo
start_rowNo
connectionYes
dimensionsNo
start_dateYes
search_typeNoweb
filter_valueNo
filter_operatorNo
response_formatNomarkdown
filter_dimensionNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: it notes that Search Console data typically lags 2-3 days behind today, which is a real-world behavioral quirk an agent needs to know. It also documents the return shape for JSON, including that 'keys' holds one value per requested dimension in the same order as the 'dimensions' argument. It doesn't mention pagination behavior beyond start_row, but the schema already documents that parameter. A 4 is appropriate because the description adds meaningful behavioral context without contradicting annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded: it opens with a one-sentence summary of what the tool does, then lists parameters in a compact block, then gives the return shape, then gives usage guidance. Every section earns its place. It's slightly long, but for a 12-parameter tool with 0% schema coverage, the length is justified. The 'Use when' and 'Don't use when' sections are particularly efficient. A 4 is appropriate because it's well-organized and information-dense without being bloated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter tool with no output schema, the description is remarkably complete. It covers the purpose, all parameter semantics, the return format, the data lag behavior, and usage guidance. The only notable gap is that it doesn't explain the exact semantics of each filter_operator (e.g., the difference between 'includingRegex' and 'excludingRegex'), and it doesn't mention that the API may have additional constraints (like date range limits). But given the complexity, the description covers nearly everything an agent needs to call the tool correctly. A 4 is appropriate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden of explaining parameters. It does this well: it explains the site_url format with an example ('sc-domain:example.com'), the date format (YYYY-MM-DD), the valid dimensions list, the search_type enum, the filter parameters with a concrete example (filter_dimension='page', filter_operator='contains', filter_value='/blog/'), and the response_format options. It doesn't explain every parameter in exhaustive detail (e.g., it doesn't explain the exact semantics of each filter_operator), but it covers the essential meaning of all 12 parameters. A 4 is justified because the description compensates well for the 0% schema coverage, though it could go deeper on filter operator semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Query'), a specific resource ('Google Search Console's Search Analytics data'), and enumerates the exact metrics returned (clicks, impressions, CTR, average position) broken down by dimensions. It also distinguishes itself from siblings by explicitly saying 'Don't use when: You need page indexing status (use gsc_inspect_url instead).' This is a clear, specific, and well-differentiated purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit 'Use when' examples with concrete dimensions ('What are our top search queries this month?' -> dimensions=['query']), and an explicit exclusion with a named alternative ('Don't use when: You need page indexing status (use gsc_inspect_url instead)'). This is exactly the kind of when-to-use vs alternatives guidance that helps an agent select the right tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_connectionsList Analytics ConnectionsA
Read-onlyIdempotent

List every configured connection (Google account or Clarity project) available to this MCP server.

Connections are set up once, outside of the LLM conversation, via the CLI (npm run cli -- add-google <name> or npm run cli -- add-clarity <name> --token <token>) and are stored in ~/.analytics-mcp-server, independent of any single project — the same connection can be reused across any project by referring to it by name.

Every other tool in this server takes a "connection" argument matching one of the names returned here.

Args:

  • response_format ('markdown' | 'json'): Output format (default: 'markdown')

Returns: For JSON format: { "connections": [ { "name": string, "type": "google" | "clarity", "label": string, "createdAt": string } ] }

Use when: "What analytics connections do I have set up?" or before calling any ga4_/gsc_/clarity_ tool if the connection name is unknown.

ParametersJSON Schema
NameRequiredDescriptionDefault
response_formatNoOutput format: 'markdown' for human-readable or 'json' for machine-readablemarkdown

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already convey read-only, idempotent, and non-destructive behavior. The description adds meaningful context beyond that: connections live in ~/.analytics-mcp-server, are created outside the LLM conversation, and are not scoped to a single project. It also states that the tool returns all connections with no filtering, and shows the JSON return shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with the core purpose. The setup context and usage guidance add value, and the Returns section is necessary because there is no output schema. However, the 'Args' block repeats schema information, introducing mild redundancy; still, it is organized and readable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read-only list tool with no output schema, the description is complete: it defines the return format for JSON, gives usage triggers, explains the connection model, and notes the relationship to all sibling tools. An agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the input schema already documents response_format with enum values, default, and a clear description. The 'Args' section in the tool description essentially duplicates this schema information without adding new meaning, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'List every configured connection (Google account or Clarity project) available to this MCP server' — a specific verb, resource, and scope. It explicitly names the two connection types and clarifies the role of connections as named arguments for sibling tools, distinguishing it from analytics data tools like ga4_run_report.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use guidance: 'Use when: "What analytics connections do I have set up?" or before calling any ga4_/gsc_/clarity_ tool if the connection name is unknown.' It also explains that connections are pre-configured via CLI and stored independently, so agents understand they must call this tool to discover valid connection names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updatesv1.0.0
    • First observedclarity_get_insights
    • First observedga4_list_properties
    • First observedga4_run_realtime_report
    • First observedga4_run_report
    • First observedgsc_inspect_url
    • First observedgsc_list_sites
    • First observedgsc_query_search_analytics
    • First observedlist_connections

TDQS

A4.5/5.0

Scored across 8 tools

Disambiguation5/5

Each tool targets a distinct service and action combination: connection listing, GA4 property listing, historical GA4 reports, GA4 realtime reports, GSC site listing, URL inspection, search analytics queries, and Clarity insights. The only near-overlap (ga4_run_report vs ga4_run_realtime_report) is clearly disambiguated by time range and explicit 'Don't use when' guidance.

Naming Consistency4/5

Most tools follow a consistent service-prefix_verb_noun pattern (ga4_list_properties, ga4_run_report, gsc_query_search_analytics, clarity_get_insights). The bare list_connections is a minor deviation, and verbs vary across services (run vs query vs get), but the pattern is still predictable and readable.

Tool Count5/5

Eight tools is well-scoped for an analytics MCP server covering three distinct platforms (GA4, GSC, Clarity). Each tool serves a concrete, necessary purpose without redundancy, and the count stays comfortably within the ideal range.

Completeness4/5

The server covers the core read/report lifecycle for each integration: property/site discovery, historical and realtime GA4 reports, GSC search analytics and URL inspection, and Clarity insights. Minor gaps exist (no GA4 dimension/metric metadata lookup, no GSC sitemap functionality), but agents can accomplish primary analytics workflows without dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    Not graded
    maintenance
    Connects Claude AI to Google Search Console with OAuth 2.0 authentication, enabling users to analyze search performance, inspect URLs, manage sitemaps, and export analytics data through natural language conversations.
    2
    -
  • A
    license
    A
    quality
    A
    maintenance
    Connect Claude to your marketing data from Google and Meta, enabling read and write operations on Search Console, Analytics, Tag Manager, Business Profile, and Meta platforms.
    35
    Apache 2.0
  • F
    license
    A
    quality
    C
    maintenance
    Connects Claude to Google Analytics 4 for querying website analytics via natural language, enabling traffic summaries, top pages, traffic sources, and user engagement.
    4
    -