Yandex Metrica for AI agents: counters, goals, Reporting API and Logs API export over stdio.
Runs on your machine from its package; the steps are below.
Not assessed yet.
Odel charges nothing per call. The publisher may charge for its own service.
Runs locally over stdio
This server isn't hosted — your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).
Run
docker run -i --rm ghcr.io/stufently/yandex-metrica-mcp:0.2.3
MCP client config
{
"mcpServers": {
"yandex-metrica-mcp": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/stufently/yandex-metrica-mcp:0.2.3"
]
}
}
}MCP server for the Yandex Metrica Reporting API, Logs API and counter management, designed for use with Claude Code and Codex CLI. Eight of its 13 tools only read; five change your Metrica account — create and delete a counter, and create, cancel and clean a Logs API export. Each tool says which it is in its MCP annotations (readOnlyHint, destructiveHint).
Runs locally over stdio. No web server, no persistent storage, no background daemons.
Yandex Metrica has two distinct APIs that serve different purposes:
/stat/v1/data) — aggregated, sampled statistics. Use this to build reports, query traffic sources, behavior metrics, goal conversions, etc./management/v1/counter/{id}/logrequests) — raw, non-aggregated event export. Use this when you need row-level session or hit data for custom analytics pipelines.This MCP server exposes both APIs as named tools that an LLM can call directly.
| Tool | Description |
|---|---|
yandex_metrica_list_counters | List accessible counters (tags) |
yandex_metrica_get_counter | Get counter details by ID |
yandex_metrica_list_goals | List goals for a counter |
yandex_metrica_create_counter | Create a new counter (add a site) |
yandex_metrica_delete_counter | Delete a counter permanently |
| Tool | Description |
|---|---|
yandex_metrica_get_report | Run a Reporting API query |
For period comparison, pass
date1_b/date2_btoyandex_metrica_get_report. The tool automatically routes to/stat/v1/data/comparison;date1/date2become segment A,date1_b/date2_bbecome segment B. Each result row returnsmetrics: { a, b }.
| Tool | Description |
|---|---|
yandex_metrica_evaluate_logs_request | Check if export is possible |
yandex_metrica_create_logs_request | Create an async export request |
yandex_metrica_list_logs_requests | List all requests for a counter |
yandex_metrica_get_logs_request | Poll status of a request |
yandex_metrica_download_logs_part | Download a processed part (TSV) |
yandex_metrica_cancel_logs_request | Cancel a pending request |
yandex_metrica_clean_logs_request | Clean processed files to free quota |
evaluate → create → [poll get until status=processed] → download parts → clean
The Logs API is asynchronous. After creating a request, poll yandex_metrica_get_logs_request until status = "processed", then download each part listed in log_request.parts (by its part_number).
Raw log parts can be hundreds of MB. By default yandex_metrica_download_logs_part returns:
{
"mode": "preview",
"truncated": true,
"original_byte_size": 52428800,
"preview_byte_size": 49980,
"content": "ym:s:visitID\tym:s:date\t...\n..."
}
Set mode: "full" to get the entire content — only do this for small parts.
metrika:read scopemetrika:read<ClientID> with yours):
https://oauth.yandex.com/authorize?response_type=token&client_id=<ClientID>
access_token from the URL fragment (#access_token=...)The counter ID is the numeric ID of your Yandex Metrica tag (счётчик):
metrika.yandex.ru/dashboard?id=**12345678**yandex_metrica_list_counters — it returns all counters with their IDs
YANDEX_METRICA_COUNTER_IDis only needed for live tests (npm run test:live), not for normal server operation.
docker run -i --rm -e YANDEX_METRICA_TOKEN ghcr.io/stufently/yandex-metrica-mcp:latest
One path that works today: Docker. Nothing to clone, no Node.js. Every MCP client below starts the server with this same command.
-e YANDEX_METRICA_TOKEN without a value forwards the variable from the client's
environment into the container, so the token lives in the client's env block and never
appears in the docker command line or ps output. The client pulls the image on
first start; docker pull ghcr.io/stufently/yandex-metrica-mcp:latest up front just
makes that first start faster.
Smoke test without a token or network — the server must answer initialize and list
13 tools. The image ships a placeholder YANDEX_METRICA_TOKEN so it starts for
introspection; tool calls with it return a "YANDEX_METRICA_TOKEN is not set" error
instead of reaching Yandex:
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
| docker run -i --rm --network none ghcr.io/stufently/yandex-metrica-mcp:latest
Image tags on GHCR: latest and main (every push to main), sha-<short>, and
X.Y.Z / X.Y / X on version tags. Pin a version tag (:0.2.3) for reproducible setups.
The package is scoped — both unscoped names (yandex-metrica-mcp and the project's
former name mcp-yandex-metrica) belong to unrelated projects on npm — so it ships as
@stufently/yandex-metrica-mcp (command yandex-metrica-mcp). The first npm release
has not been cut, so npx -y @stufently/yandex-metrica-mcp does not work today. Use
Docker.
git clone https://github.com/stufently/yandex-metrica-mcp.git
cd yandex-metrica-mcp
npm install && npm run build
See Running from a local build for the client config.
Copy .env.example to .env and set your token:
cp .env.example .env
| Variable | Required | Default | Description |
|---|---|---|---|
YANDEX_METRICA_TOKEN | Yes | — | OAuth token with metrika:read |
YANDEX_METRICA_TIMEOUT_MS | No | 30000 | Request timeout in ms |
LOG_LEVEL | No | info | Log level: debug, info, warn, error, silent |
YANDEX_METRICA_USER_AGENT | No | yandex-metrica-mcp/0.2.3 | Custom User-Agent |
YANDEX_METRICA_BASE_URL | No | https://api-metrika.yandex.net | API base URL (tests only) |
# Development with hot reload
YANDEX_METRICA_TOKEN=your_token npm run dev
# Build
npm run build
# Run production build
YANDEX_METRICA_TOKEN=your_token npm start
# Lint
npm run lint
# Type check
npm run typecheck
# Tests (unit + mock integration, no live API calls)
npm test
# Live tests (requires real token and counter ID)
LIVE_TESTS=1 YANDEX_METRICA_TOKEN=your_token YANDEX_METRICA_COUNTER_ID=12345678 npm run test:live
# Format
npm run format
# Use pre-built image from GHCR (updated on every push to main)
docker run -i --rm \
-e YANDEX_METRICA_TOKEN=your_token \
ghcr.io/stufently/yandex-metrica-mcp:latest
# Or build locally
docker build -t yandex-metrica-mcp:local .
docker run -i --rm \
-e YANDEX_METRICA_TOKEN=your_token \
yandex-metrica-mcp:local
# Create .env with your token first
cp .env.example .env
# Run
docker-compose run --rm yandex-metrica-mcp
Only what has actually been run is listed as verified. Everything else in Client Configuration is a documented config that nobody has checked end to end.
| Client / runtime | OS | How it runs | Status | Evidence |
|---|---|---|---|---|
| Claude Code 2.1 | Ubuntu 26.04 LTS, x86_64 | Docker image built locally from this repo, stdio | Verified | Daily use on the maintainer's host (counters, reports, goals) |
| Node.js 24 | Ubuntu (ubuntu-latest) | npm ci, lint, typecheck, unit + mock integration tests, build | Verified in CI | ci.yml |
| Docker image | Ubuntu (ubuntu-latest) | Image build on every pull request and push to main | Built in CI, not started there | docker.yml |
Claude Desktop (.mcpb) | macOS, Windows | Desktop Extension | Not verified | Bundle is built in CI, never installed in a real Desktop |
| Cursor, Windsurf, Codex CLI, Zed | any | Configs below | Not verified | Documented only |
| macOS, Windows | — | Any client | Not verified | No CI runner on these systems |
All configs below are copy-paste ready and use the Docker command from
Installation. Replace your_oauth_token_here with your Yandex OAuth
token and nothing else.
Project file: .mcp.json in the project root.
claude mcp add yandex-metrica \
-e YANDEX_METRICA_TOKEN=your_oauth_token_here \
-- docker run -i --rm -e YANDEX_METRICA_TOKEN ghcr.io/stufently/yandex-metrica-mcp:latest
Add --scope user to make it available in every project, or --scope project to write
.mcp.json. Check with claude mcp list / claude mcp get yandex-metrica.
The same server as JSON in .mcp.json:
{
"mcpServers": {
"yandex-metrica": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"YANDEX_METRICA_TOKEN",
"ghcr.io/stufently/yandex-metrica-mcp:latest"
],
"env": {
"YANDEX_METRICA_TOKEN": "your_oauth_token_here"
}
}
}
}
Config file claude_desktop_config.json: macOS
~/Library/Application Support/Claude/, Windows %APPDATA%\Claude\, Linux
~/.config/Claude/. Restart the app after saving.
{
"mcpServers": {
"yandex-metrica": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"YANDEX_METRICA_TOKEN",
"ghcr.io/stufently/yandex-metrica-mcp:latest"
],
"env": {
"YANDEX_METRICA_TOKEN": "your_oauth_token_here"
}
}
}
}
Claude Desktop can also install this server in one click from a .mcpb file. Releases
up to v0.2.0 do not include one yet; the bundle is attached starting with the next
tagged release at https://github.com/stufently/yandex-metrica-mcp/releases/latest.
Until then, build it locally with bash scripts/build-mcpb.sh (needs Docker) and open
dist-mcpb/yandex-metrica-mcp-<version>.mcpb.
Releases include checksums.txt with the SHA256 checksum of each .mcpb bundle.
Download it alongside the bundle and verify before installing:
sha256sum -c --ignore-missing checksums.txt # run next to the downloaded .mcpb
Releases from the next tag on also carry a GitHub build provenance attestation for each
.mcpb, signed in the release workflow. Check that a bundle was built by this
repository's workflow and not swapped afterwards (needs the GitHub CLI):
gh attestation verify <bundle>.mcpb --repo stufently/yandex-metrica-mcp
~/.cursor/mcp.json for every project, or .cursor/mcp.json for one project.
{
"mcpServers": {
"yandex-metrica": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"YANDEX_METRICA_TOKEN",
"ghcr.io/stufently/yandex-metrica-mcp:latest"
],
"env": {
"YANDEX_METRICA_TOKEN": "your_oauth_token_here"
}
}
}
}
File mcp_config.json. On macOS and Linux:
~/.config/devin/mcp_config.json (or $XDG_CONFIG_HOME/devin/mcp_config.json). On
Windows: %APPDATA%\devin\mcp_config.json. Older builds used
~/.codeium/windsurf/mcp_config.json.
{
"mcpServers": {
"yandex-metrica": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"YANDEX_METRICA_TOKEN",
"ghcr.io/stufently/yandex-metrica-mcp:latest"
],
"env": {
"YANDEX_METRICA_TOKEN": "your_oauth_token_here"
}
}
}
}
codex mcp add yandex-metrica \
--env YANDEX_METRICA_TOKEN=your_oauth_token_here \
-- docker run -i --rm -e YANDEX_METRICA_TOKEN ghcr.io/stufently/yandex-metrica-mcp:latest
Or by hand in ~/.codex/config.toml (shared by the Codex CLI, IDE extension and desktop app):
[mcp_servers.yandex-metrica]
command = "docker"
args = ["run", "-i", "--rm", "-e", "YANDEX_METRICA_TOKEN", "ghcr.io/stufently/yandex-metrica-mcp:latest"]
env = { YANDEX_METRICA_TOKEN = "your_oauth_token_here" }
Zed's settings.json (zed: open settings file), under context_servers:
{
"context_servers": {
"yandex-metrica": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"YANDEX_METRICA_TOKEN",
"ghcr.io/stufently/yandex-metrica-mcp:latest"
],
"env": {
"YANDEX_METRICA_TOKEN": "your_oauth_token_here"
}
}
}
}
Works in any client above — swap command/args for:
{
"mcpServers": {
"yandex-metrica": {
"command": "node",
"args": ["/absolute/path/to/yandex-metrica-mcp/dist/index.js"],
"env": {
"YANDEX_METRICA_TOKEN": "your_oauth_token_here"
}
}
}
}
In Claude Code the same thing via CLI:
claude mcp add yandex-metrica \
-e YANDEX_METRICA_TOKEN=your_oauth_token_here \
-- node /absolute/path/to/yandex-metrica-mcp/dist/index.js
Once the server is registered, ask in plain language — the client picks the tool.
List what you have access to → yandex_metrica_list_counters
List all my Yandex Metrica counters with their IDs and site names.
Traffic report over a period → yandex_metrica_get_report
Show visits, users and bounce rate for counter 12345678 for the last 7 days,
broken down by date.
Top traffic sources → yandex_metrica_get_report
What were the top 10 traffic sources for counter 12345678 last month,
by visits and conversion rate?
Compare two periods → yandex_metrica_get_report with date1_b/date2_b
Compare visits and average session duration for counter 12345678
between this month and the same month last year.
Goal conversions → yandex_metrica_list_goals + yandex_metrica_get_report
List the goals configured on counter 12345678, then show conversions
for each of them over the last 30 days.
Raw event export → the Logs API chain (evaluate → create → get → download_part → clean)
Export raw visits for counter 12345678 from 2024-01-01 to 2024-01-07 with fields
visitID, date, clientID, startURL, trafficSource. Poll until it is ready,
then show me a preview of the first part.
src/
index.ts Entry point, loads config, connects stdio transport
config/env.ts Zod-based environment config validation
server/
createServer.ts Creates MCP Server instance
registerTools.ts Registers all tools with the server
tools/ One file per MCP tool
client/
http.ts Fetch-based HTTP client with auth, timeout, error handling
management.ts Counters and goals endpoints
reporting.ts Reporting API (/stat/v1/data)
logs.ts Logs API lifecycle endpoints
schemas/ Zod schemas for tool input validation
errors/ YandexApiError + error mapping
types/api.ts TypeScript types for Yandex API responses
utils/
arrays.ts Array → comma-separated conversion
text.ts Text preview/truncation for large downloads
yandex_metrica_get_report with date1_b/date2_b paramsmode: "full" carefully; defaults to 50KB preview# Unit + mock integration (CI-safe, no real API calls)
npm test
# Live tests (hit real Yandex API)
LIVE_TESTS=1 \
YANDEX_METRICA_TOKEN=your_token \
YANDEX_METRICA_COUNTER_ID=12345678 \
npm run test:live
GitHub Actions workflows are in .github/workflows/:
ci.yml — lint, typecheck, test, build on every push/PRdocker.yml — build Docker image; push to GHCR on pushes to main and version tags;
on a vX.Y.Z tag, also publish server.json to the
official MCP Registry as
io.github.stufently/yandex-metrica-mcp (GitHub OIDC, no stored secret)mcpb.yml — on a vX.Y.Z tag, build the .mcpb Desktop extension and attach it
to that GitHub Release. It does not publish to GHCR, npm, PyPI, or the MCP registry.Image tags produced by docker.yml:
| Tag | When |
|---|---|
latest | every push to main |
main | every push to main |
sha-<short> | every push to main and every version tag |
X.Y.Z, X.Y, X | pushing a vX.Y.Z git tag |
REGISTRY and IMAGE_NAME default to ghcr.io and ${{ github.repository }}.
metrika:write scope; all other tools use read-only accessnode user)MIT — see LICENSE