Guide

Google Analytics MCP server

one URL, sign in with Google, nothing to install · part of the Anacrafter Elite plan · --demo needs no account
What it does

anacraft serves a Google Analytics 4 property over the Model Context Protocol, so Claude, ChatGPT or any MCP client answers how is the site doing without a human reading a dashboard.

Twelve tools. One URL to paste, or one command in a terminal. Eleven of them only read, and one of them — audit_site — tells the assistant whether the other eleven are worth quoting.

01Wire it up

Nothing to install, and no terminal. Add one URL to your AI tool:

https://app.anacraft.dev/mcp
  1. In Claude, open Settings → Connectors → Add custom connector and paste the URL. In ChatGPT it is Settings → Connectors → Create; in Cursor, add it as a remote MCP server.
  2. Your tool opens a sign-in page. Sign in with the Google account that has your Analytics, pick your site, and press Allow.
  3. Ask it how your site is doing.

It reads the site you picked. Pick Every property instead and it can read all of them, asking which one you mean. The connect page names the app it is sending you back to — if that is not the tool you started from, do not allow it. To disconnect every tool at once, open mcp on any row at app.anacraft.dev and turn your connector off.

Or paste a link for one property

For a tool that has no sign-in step, or to give an assistant only one site: sign in at app.anacraft.dev, press mcp on that site's row, and paste the link it gives you in place of the URL above. The link has its token built in and reads only that property. It is the same link next week and on every device, so treat it like a password; the same switch turns every link off at once.

For developers: from the terminal

Optional — skip this if the link above works for you. It keeps everything on your own machine, and it is how Cursor, Windsurf and other local clients connect.

Claude Desktop is one command. It merges into the config and leaves any other servers alone.

# sign in, pick a property, then install
$ craft login
$ craft use 397412345
$ craft mcp --install

# or try it first — synthetic data, no account
$ craft mcp --install --demo

# and take it back out again
$ craft mcp --uninstall

Restart the client and ask it how the site is doing. For Claude Code the command is claude mcp add anacraft -- craft mcp; any other client takes the same command and argument. Writing a config by hand, use an absolute path — a desktop app is not launched from a shell and does not inherit the PATH where craft works. which craft gives the value to paste.

{
  "mcpServers": {
    "anacraft": {
      "command": "/usr/local/bin/craft",
      "args": ["mcp"]
    }
  }
}

When the client cannot spawn it

A sandboxed client may not be able to run craft at all. A strictly confined snap cannot read a hidden directory at the top of your home, which is both where the binary usually sits and where ~/.anacraft/ keeps the credentials; a Mac App Store build is walled into its container; a container may have no home directory worth the name. All of them can open a loopback socket. So leave the process outside the sandbox and give the client a URL instead of a command:

$ craft serve --idle 0 --no-open

The server prints one string with the token already in it:

http://127.0.0.1:7777/v1/mcp?token=<token>

That is the whole configuration for a client whose only field is a URL. For Claude Code the server prints the command too — claude mcp add --transport http anacraft 'http://127.0.0.1:7777/v1/mcp?token=<token>' — and a client with somewhere to put a header can send the token as Authorization: Bearer <token> against the bare /v1/mcp instead. All three are on the server's own page, behind one mcp link per property in the list, and on c in craft, which puts the link on the clipboard. Your Google credentials stay in ~/.anacraft/ and never enter the sandbox; the client only ever holds a token to a port on your own machine. It is the same twelve tools, answering the same way.

A token in a query string is usually a thing to avoid, because query strings turn up in access logs and Referer headers. This one goes to a server on loopback that writes no log and is never a web page's origin, and it was going to sit in the client's config file either way — so treat the link like a password and nothing more.

It is the same line tomorrow. The port is the one the server took last time, and the token is an HMAC of your Google account id and the property id under a secret minted once and kept at 0600 in ~/.anacraft/mcp-http.json — so a client configured today is still configured next week, where a freshly minted token would have quietly stopped working overnight. There is one token per property and it names the property it was cut for, so a connector goes on reading the site it was wired to no matter which property the dashboard is showing. --token still overrides the lot, for a caller that has to know the token in advance.

02The twelve tools

ToolAnswers
site_statusHow the site is doing — every headline metric against the period before it, the daily user series, and the milestones the numbers crossed
audit_siteWhether those numbers can be trusted — twelve graded checks on how the property is measuring. What it checks →
live_visitorsWho is on the site right now, by country. Realtime, so it ignores the window
list_pagesMost-visited pages, by views
list_eventsEvents by count, with the per-day total against the previous period
list_referrersThe URLs sending traffic, by sessions
list_traffic_sourcesGA4 source / medium pairs, by sessions
list_countriesTraffic by country
list_propertiesEvery property this account can read, and which is the default
search_pagesPages whose path contains a substring
search_eventsEvents whose name contains a substring
configure_siteThe one write — creates the property and web stream for a domain and returns the tag to paste

Every report tool takes an optional property and falls back to the saved default, so an assistant that knows nothing about your config still gets answers. Each carries its own days default rather than sharing one, because the window a question needs is part of the question: seven days is the right answer to how are we doing and the wrong one to is anything broken, so audit_site advertises twenty-eight.

03What comes back

Labelled JSON, not rendered panels. Every answer carries the property id and the exact window it covers, so an assistant can attribute the numbers it quotes rather than reporting a figure with no period attached to it.

The window is reported as the first and last day the API actually returned, rather than computed locally: last 7 days resolves in the property's reporting time zone, which is not necessarily the machine's. Identical reports are cached for a minute — and say so in the answer, so an assistant watching a number that will not move knows why rather than concluding the site went quiet.

04One writer, and it is obvious which

configure_site takes a domain, creates the Google Analytics property and web stream for it, and hands back the tag with its real measurement id. It is annotated in the schema as the one tool that is not read-only, which is what makes a client show it differently and think before calling it.

Nothing here signs in, writes credentials to disk, or moves your default property. login and use stay human-only commands, and configure_site never changes what the dashboard opens on. If no credentials are stored, the tools say to run craft login rather than opening a browser inside your client's subprocess.

05What it will not do

It serves one property at a time and it serves Google Analytics. There is no Search Console, no Google Ads and no Meta here, so an assistant asked to explain a drop can say which channel carried it and not which campaign paid for it.

And it will not pretend a broken property is a quiet one. That is what audit_site is for: a site with nothing marked as a key event reports zero conversions perfectly truthfully, and saying nothing here is marked as a conversion is a different answer from conversions fell.

06Try it without an account

# synthetic data over the same twelve tools
$ craft mcp --demo

No Google account, no subscription. The wiring can be tested and the answers looked at first.

The live server is part of the Anacrafter Elite ($9.99) plan. Without a login or a subscription it still starts, and its tools say which one is missing — so the client never reports it as disconnected, and the answer arrives where you asked the question.

Building with Lovable? anacraft × Lovable adds GA4 to your app, then reads the numbers back from Claude or any MCP client.

09Questions

What is an MCP server for Google Analytics?

The Model Context Protocol is a standard way for an AI assistant to call tools. An MCP server for Google Analytics exposes the reporting API as tools the assistant can call, so it can read a property's real numbers instead of being pasted a screenshot. craft mcp is one: a single command that speaks the protocol on stdin and stdout, which the client spawns as a child process. A client that cannot spawn one — a confined snap, a Mac App Store build, a container — reaches the same tools over HTTP instead, at craft serve's /v1/mcp.

How do I connect Claude to Google Analytics?

Add https://app.anacraft.dev/mcp as a custom connector in Claude (Settings, Connectors, Add custom connector), sign in with the Google account that has your Analytics, and press Allow. From a terminal instead: craft login, craft use to pick a property, then craft mcp --install to write the server into Claude Desktop's config. For Claude Code the command is claude mcp add anacraft -- craft mcp.

Can the assistant change anything in my Analytics account?

Eleven of the twelve tools only read. The exception is configure_site, which creates a property and web data stream for a domain the account does not measure yet and returns the tag to paste. Nothing signs in, writes credentials to disk, or changes which property the dashboard opens on — login and use stay human-only commands.

Does it work without a Google account?

craft mcp --demo serves synthetic data over the same twelve tools, so the wiring can be tested and the answers looked at before any account is connected. It needs no login and no subscription.

What does the assistant get back?

Labelled JSON carrying the property id and the exact date window the numbers cover, so an assistant can attribute what it quotes rather than reporting a figure with no period attached. Identical reports are cached for a minute, so a chatty agent does not burn the API quota the dashboard needs.