yandex-mcp
by webkoth
README.md
# yandex-mcp
An [MCP](https://modelcontextprotocol.io) server that exposes the **Yandex Webmaster**, **Yandex Direct** and **Yandex Metrika** APIs as tools for AI assistants (Claude Desktop, Claude Code, Cursor, etc.).
It lets an assistant work with your Yandex SEO, advertising and analytics data in natural language — inspect search queries, manage indexing and sitemaps, request recrawls, run diagnostics, manage Direct campaigns with write-safety guards, and pull traffic/conversion/ad statistics — without you logging into the Yandex web UI.
- **125 tools** total: 52 for Webmaster, 46 for Direct, 25 for Metrika, 2 for project management.
- **6 MCP prompts** — ready-made workflows (campaign audit, weekly report, campaign launch, budget scaling, SEO audit, learning check) built on the autostrategies playbook, which is also exposed as the `yandex://playbook` MCP resource.
- Single server, multi-project: several Yandex accounts/tokens in one stdio process.
- TypeScript / Node ≥ 22, built on `@modelcontextprotocol/sdk` and `zod`.
## How it works
`src/index.ts` boots one `McpServer` and registers every tool group from `src/webmaster/` and `src/direct/`. All requests go through `src/client.ts`, a per-project HTTP client that:
- attaches the `Authorization: OAuth <token>` header (`Bearer` for Direct),
- routes Webmaster calls to `api.webmaster.yandex.net` and Direct calls to `api.direct.yandex.com/json/v5` (or the Direct Sandbox when `direct.sandbox` is enabled),
- resolves and caches the Webmaster `user_id` and injects `host_id` into paths,
- retries on network errors / `429` with exponential backoff and handles `204 No Content`,
- surfaces Direct in-body `{"error": {...}}` responses and tracks the `Units` quota header.
## Prerequisites
- Node.js ≥ 22.
- A Yandex OAuth token with access to the Webmaster and/or Metrika APIs.
### Getting an OAuth token
1. Register an application in the [Yandex OAuth console](https://oauth.yandex.com/) and grant it the Webmaster (`webmaster:hostinfo`, `webmaster:verify`) and/or Metrika (`metrika:read` / `metrika:write`) scopes.
2. Obtain a token for your account via the [OAuth flow](https://yandex.com/dev/id/doc/en/).
Notes:
- **Direct requires its own application scope and an approved access request** (заявка) submitted from the Direct account after registering the app — existing Webmaster/Metrika tokens will not work for Direct without re-issuing. Until access is approved, use the [Direct Sandbox](https://yandex.com/dev/direct/doc/dg/concepts/sandbox.html) (`direct.sandbox: true` in the project config).
- Webmaster OAuth tokens expire after **6 months** and must be re-issued.
## Setup
```bash
npm install
cp .env.example .env # then put your token in .env
npm run build
```
`.env`:
```
YANDEX_OAUTH_TOKEN=your_oauth_token_here
```
## Run
```bash
npm start # runs dist/index.js (requires build)
npm run dev # tsx watch mode against src/index.ts
```
The server speaks MCP over **stdio**, so it's normally launched by an MCP client rather than by hand.
## Multi-project configuration
The server can serve several projects, each with its own Yandex login/token.
Copy `projects.example.json` to `projects.json` (gitignored) and fill it in, or
point `YANDEX_PROJECTS_CONFIG` at another path. If no config file exists but
`YANDEX_OAUTH_TOKEN` is set, a single project `default` is used.
Switch the active project with `yandex_set_active_project`, inspect with
`yandex_projects_list`, or pass `project` to any Direct or Metrika tool.
Metrika tools also honor the project's `default_counter`.
Per-project Direct settings: `sandbox` (route to the Direct Sandbox),
`client_login` (agency accounts), and `limits` — maximum allowed budget/bid
change in percent, enforced by the write tools.
## Connecting to an MCP client
The token is read from the `YANDEX_OAUTH_TOKEN` environment variable.
### Claude Desktop / Cursor
Add to the MCP servers config (`claude_desktop_config.json` or equivalent):
```json
{
"mcpServers": {
"yandex": {
"command": "node",
"args": ["/absolute/path/to/yandex/dist/index.js"],
"env": {
"YANDEX_OAUTH_TOKEN": "your_oauth_token_here"
}
}
}
}
```
### Claude Code
```bash
claude mcp add yandex --env YANDEX_OAUTH_TOKEN=your_token -- node /absolute/path/to/yandex/dist/index.js
```
## Tools
### Webmaster (52)
| Group | Tools |
|---|---|
| User | `user_get` |
| Hosts | `hosts_list`, `hosts_get`, `hosts_add`, `hosts_delete` |
| Verification | `verification_start`, `verification_status`, `verification_owners` |
| Summary | `summary_get`, `summary_sqi_history` |
| Search queries | `search_queries_popular`, `search_queries_all_history`, `search_queries_history`, `query_analytics` |
| Indexing | `indexing_history`, `indexing_samples`, `indexing_archive_create`, `indexing_archive_status` |
| URLs in search | `search_urls_in_search_history`, `search_urls_in_search_samples`, `search_urls_events_history`, `search_urls_events_samples` |
| Important URLs | `important_urls_list`, `important_urls_history` |
| Sitemaps | `sitemaps_list`, `sitemaps_get`, `sitemaps_user_list`, `sitemaps_user_get`, `sitemaps_add`, `sitemaps_delete` |
| Recrawl | `recrawl_submit`, `recrawl_status`, `recrawl_list`, `recrawl_quota`, `recrawl_sitemap_quota`, `recrawl_sitemap_submit` |
| Diagnostics | `diagnostics_get` |
| Links | `links_external_samples`, `links_external_history`, `links_internal_samples`, `links_internal_history` |
| Pro export | `pro_regions`, `pro_limits`, `pro_dates`, `pro_export_start`, `pro_export_status` |
| Feeds | `feeds_add`, `feeds_add_status`, `feeds_batch_add`, `feeds_list`, `feeds_batch_delete`, `feeds_change_regions` |
All names are prefixed `yandex_webmaster_`.
### Direct (43)
| Group | Tools |
|---|---|
| Read | `campaigns_get`, `adgroups_get`, `ads_get`, `keywords_get`, `bids_get`, `bidmodifiers_get`, `sitelinks_get`, `adextensions_get`, `adimages_get`, `retargetinglists_get`, `audiencetargets_get`, `feeds_get`, `creatives_get`, `smartadtargets_get`, `dynamictextadtargets_get`, `negativekeywordsharedsets_get`, `vcards_get`, `leads_get`, `turbopages_get`, `businesses_get`, `agencyclients_get`, `advideos_get`, `dictionaries_get` (24h cache), `clients_get`, `changes_check`, `units` |
| Write (guarded) | `campaigns_manage`, `adgroups_manage`, `ads_manage`, `keywords_manage`, `bids_set`, `bidmodifiers_manage`, `sitelinks_manage`, `adextensions_manage`, `adimages_manage`, `retargetinglists_manage`, `audiencetargets_manage`, `feeds_manage`, `smartadtargets_manage`, `dynamictextadtargets_manage`, `negativekeywordsharedsets_manage`, `vcards_manage`, `advideos_manage`, `clients_manage` |
| Research | `keywords_research` |
| Reports | `report` |
All names are prefixed `yandex_direct_`. Write tools preview a diff unless
`confirm: true`, and enforce per-project budget/bid change limits (override with
`force: true`). Set `direct.sandbox: true` in the project to route calls to the
Direct Sandbox. Write results include a per-item summary — Direct reports
partial failures inside a successful HTTP response, so check `partial_failure`.
### Project management (2)
`yandex_projects_list`, `yandex_set_active_project` — see
[Multi-project configuration](#multi-project-configuration).
### Metrika (22)
| Group | Tools |
|---|---|
| Management | `counters_list`, `counter_get`, `goals_list`, `segments_list`, `filters_list` |
| Goals (guarded write) | `goal_add`, `goal_update`, `goal_delete` |
| Offline conversions | `offline_conversions_upload` (guarded), `offline_conversions_uploadings` |
| Expenses import | `expenses_upload` (guarded; non-Yandex ad costs), `expenses_uploadings` |
| CRM import | `crm_orders_upload` (guarded; orders/revenue via CDP), `calls_upload` (guarded), `calls_uploadings` |
| Logs API (raw data) | `logs_evaluate`, `logs_request_create`, `logs_requests`, `logs_download` (truncated TSV), `logs_clean` |
| Reporting (Stat) | `stat_data`, `stat_bytime`, `stat_drilldown`, `stat_comparison`, `stat_comparison_drilldown` |
All names are prefixed `yandex_metrika_`. The stat tools accept `direct_client_logins` for advertising reports (`ym:ad:` metrics — Direct costs joined with on-site behavior) and `extra_params` for any other query parameter.
The reporting tools mirror the Metrika [Reporting API](https://yandex.com/dev/metrika/doc/api2/api_v1/intro.html). Metrics and dimensions use the `ym:s:` (visits) / `ym:pv:` (pageviews) namespaces — e.g. `metrics: "ym:s:visits,ym:s:users,ym:s:bounceRate"`, `dimensions: "ym:s:date,ym:s:lastTrafficSource"`. Dates accept `YYYY-MM-DD` or relative keywords (`today`, `yesterday`, `7daysAgo`). Counter-scoped tools default to the project's `default_counter` when `counter_id`/`ids` is omitted.
## Project layout
```
src/
index.ts # entry point: boots the MCP server, registers all tools
client.ts # per-project HTTP client (auth schemes, base URLs, retries, Direct transport)
projects.ts # project registry: per-project tokens, Direct config, limits
server-tools.ts # project management tools (list / set active)
webmaster/ # 14 modules, 51 Webmaster tools
metrika/ # management + Reporting API — 10 Metrika tools
direct/ # read, guarded write, reports — 14 Direct tools
```
## Scripts
| Command | Description |
|---|---|
| `npm run build` | Compile TypeScript to `dist/` |
| `npm run dev` | Run from source with `tsx` watch |
| `npm test` | Run the unit test suite (`tsx --test`) |
| `npm start` | Run the built server |
| `npm run clean` | Remove `dist/` |
## License
MIT © Minas Sarkisyan
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues