Skip to main content
Glama
zai-one

arsenkin-mcp

by zai-one
README.md
🇬🇧 English · [🇷🇺 Русский](README.ru.md)

# Arsenkin MCP

**Run your SEO checks in batches from your AI assistant.**

> MCP server for Arsenkin Tools: paid SEO batch jobs (SERP, clustering, Wordstat frequency, indexation, LSI, meta tags, AI answers) with estimate → approve → submit, plus free saved Projects data.

Collect SERPs, check keyword frequency, cluster queries or inspect indexation through Arsenkin Tools. The MCP server gives your assistant a workflow for estimating requests, getting approval, tracking jobs and working with saved results.

[Quick start](#quick-start) · [Connect your assistant](#connect-your-assistant) · [Issues](https://github.com/zai-one/arsenkin-mcp/issues)

Try asking your assistant:

> Prepare a frequency-check batch for my keyword list. Show the request plan and estimated cost before submitting anything.

## What you can do

| Your task | What the MCP server provides |
|---|---|
| Research keywords | Keyword frequency, related phrases, demand trends, search suggestions and clustering. |
| Inspect search visibility | SERP, position, indexation and relevant-URL checks. |
| Manage a batch | Discover profiles, estimate, approve, submit, diagnose the worker and export saved results. |
| Read the result | URL/host occurrence tables and cluster records with source pointers, in JSON or CSV. |
| Review saved projects | `arsenkin_projects` reads your SEO projects through the [Projects API](https://help.arsenkin.ru/projects-api): regions, competitors, keywords, groups, saved positions and visibility/top/average/median charts. It never starts a position check. |
| Check remaining limits | `arsenkin_limits` returns the account's total and spent limits before you prepare paid tasks. |

[Saved-result examples and worker help](docs/RESULT_TABLES.md) show how to turn a completed SEO task into a useful table.

## Why this MCP

- Optional lazy tool loading: set `ARSENKIN_TOOL_LOADING=lazy` (or choose it in the setup wizard) to start with a small core and enable toolsets on demand; see [Lazy tool loading](#lazy-tool-loading).
- Every paid job is estimated first, budget-checked and submitted only after approval (exception: the opt-in projects `run_positions`, see below); `arsenkin_limits` shows remaining limits.
- Jobs run through a worker with tracked state; results are saved and exported as tables (JSON/CSV) with source pointers.
- 18 default tools (meta, jobs, results, projects) plus opt-in `projects_write`, 4 prompts, guide resources and skills.
- We found no other Arsenkin Tools MCP server on GitHub (search on 2026-10-13).

## Lazy tool loading

Optional lazy tool loading: `ARSENKIN_TOOL_LOADING=lazy` starts with a small core plus `arsenkin_enable_toolsets` and adds toolsets on demand (`tools/list_changed`). Startup cost (tools/list + instructions, ≈chars/4): eager ≈3678 tokens, lazy ≈1285 tokens (−65%). Default `eager` is unchanged; if your client ignores `tools/list_changed`, keep `eager` or reconnect after enabling. Scope: enablement is per MCP session (FastMCP session visibility), so one client's enabled toolsets never appear for another. The HTTP transport here is stateless (every request is its own session), so enabled toolsets do not persist there: for shared HTTP use `eager` or `ARSENKIN_TOOLSETS`.

Clients and `notifications/tools/list_changed` (verified against official docs, changelogs or maintainer statements, 2026-10):

| Client | `tools/list_changed` | Source |
|---|---|---|
| Claude Code | Supported (interactive: tools, prompts, resources; `-p`/Agent SDK: tools) | [docs: Dynamic tool updates](https://code.claude.com/docs/en/mcp) |
| VS Code (GitHub Copilot) | Supported (dynamic tool discovery); new tools may reach the agent only on the next turn | [docs](https://code.visualstudio.com/api/extension-guides/ai/mcp), [#303012](https://github.com/microsoft/vscode/issues/303012) |
| Gemini CLI | Supported (refreshes the tool registry) | [PR #14375](https://github.com/google-gemini/gemini-cli/pull/14375), [PR #21050](https://github.com/google-gemini/gemini-cli/pull/21050) |
| Cursor | Unreliable: staff confirm a regression in 3.12.x; restart Cursor after enabling | [forum](https://forum.cursor.com/t/mcp-server-regression-does-not-reload-tools-disconnect-does-nothing-ignores-mcp-json-changes-etc/166216) |
| Claude Desktop, Windsurf, Codex CLI, Cline, Zed, Continue | Unverified: no official statement found; use `eager` or reconnect after enabling | — |

## Maintained and up to date

- Actively maintained by ZAI.ONE: current version 0.6.0; release notes in [CHANGELOG.md](CHANGELOG.md) and [Releases](https://github.com/zai-one/arsenkin-mcp/releases).
- Built-in update check: ask the assistant to run `arsenkin_check_update` (public GitHub API, no credentials, cached; nothing is installed automatically; `ARSENKIN_DISABLE_UPDATE_CHECK=1` turns it off).
- Follows current MCP practice: tool annotations (read-only / destructive hints), toolsets and read-only mode, server `instructions`, prompts and resources, structured errors with recovery hints, secrets kept out of tool output, a token budget for tool descriptions enforced in tests.
- CI runs the test suite on Linux and Windows for every pull request.

## Quick start

Prefer a ready package? [Install the release and generate your client configuration](INSTALL.md#install-a-release-package). No source checkout is required.

Install **Python 3.12–3.14** and [uv](https://docs.astral.sh/uv/getting-started/installation/). Clone with Git or [download the ZIP](https://github.com/zai-one/arsenkin-mcp/archive/refs/heads/main.zip). With a ZIP, open the extracted directory and skip the first two commands.

Have your Arsenkin API token ready for the configuration wizard. Start with a local request estimate, as shown below; enable paid execution after reviewing the access and limits section.

```sh
git clone https://github.com/zai-one/arsenkin-mcp.git
cd arsenkin-mcp
uv sync --frozen --extra standalone
uv run --frozen --extra standalone python scripts/configure.py
uv run --frozen --extra standalone arsenkin-mcp --config mcp.local.json --check-config
```

The wizard creates a local configuration and stores secrets in private files. It refuses to overwrite an existing setup. `--check-config` validates local settings; use `arsenkin_status` separately to check account connectivity.

## Connect your assistant

Add this configuration to an MCP client that uses `mcpServers`, such as Claude Desktop or Cursor. Replace `/ABSOLUTE/PATH/` with your absolute path; Windows JSON paths can use forward slashes, such as `D:/Tools/`.

```json
{
  "mcpServers": {
    "arsenkin": {
      "command": "uv",
      "args": [
        "--directory",
        "/ABSOLUTE/PATH/arsenkin-mcp",
        "run",
        "--frozen",
        "--extra",
        "standalone",
        "arsenkin-mcp",
        "--config",
        "/ABSOLUTE/PATH/arsenkin-mcp/mcp.local.json"
      ]
    }
  }
}
```

The client starts the MCP server for you. Refresh its tool list, then make your first request. For clients with a different config format, reuse the same `command` and `args`; `uv` must be available to the client process.

### First request

> Prepare an estimate for a frequency-check request with one phrase. Ask me for the region and frequency type; do not submit a paid job.

An estimate validates the request locally and shows the server cost estimate without calling Arsenkin. Submitting a paid job is a separate step. Cost estimates use configured policy units, not a guaranteed invoice amount or a ruble quote.

If tools do not appear, check the absolute path, whether the client can find `uv`, and the `--check-config` result. For access errors, check account credentials and permissions. [Installation and troubleshooting](INSTALL.md).


<!-- agent-block:start -->
## Install in your agent

Run `arsenkin-mcp` straight from GitHub with [uv](https://docs.astral.sh/uv/). Pin a release tag (`@vX.Y.Z`) for
reproducible installs; placeholders below are examples, keep secrets in files outside the repo.

**Claude Code**

```bash
claude mcp add arsenkin --env ARSENKIN_TOKEN_FILE=/path/to/arsenkin.token --env ARSENKIN_STATE_PATH=/path/to/arsenkin.sqlite -- uvx --from git+https://github.com/zai-one/arsenkin-mcp@v0.6.0 arsenkin-mcp
```

Skills for Claude Code: copy `skills/*` into `~/.claude/skills/` (or install this repo as a plugin — it
ships `.claude-plugin/plugin.json` with the skills and the MCP server).

**Cursor** — `.cursor/mcp.json` ([one-click install](cursor://anysphere.cursor-deeplink/mcp/install?name=arsenkin&config=eyJjb21tYW5kIjogInV2eCIsICJhcmdzIjogWyItLWZyb20iLCAiZ2l0K2h0dHBzOi8vZ2l0aHViLmNvbS96YWktb25lL2Fyc2Vua2luLW1jcEB2MC42LjAiLCAiYXJzZW5raW4tbWNwIl0sICJlbnYiOiB7IkFSU0VOS0lOX1RPS0VOX0ZJTEUiOiAiL3BhdGgvdG8vYXJzZW5raW4udG9rZW4iLCAiQVJTRU5LSU5fU1RBVEVfUEFUSCI6ICIvcGF0aC90by9hcnNlbmtpbi5zcWxpdGUifX0=)):

```json
{
  "mcpServers": {
    "arsenkin": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/zai-one/arsenkin-mcp@v0.6.0",
        "arsenkin-mcp"
      ],
      "env": {
        "ARSENKIN_TOKEN_FILE": "/path/to/arsenkin.token",
        "ARSENKIN_STATE_PATH": "/path/to/arsenkin.sqlite"
      }
    }
  }
}
```

**Codex** — `~/.codex/config.toml` (skills: copy `skills/*` into `~/.codex/skills/`, or keep the
repo's `.agents/skills` link):

```toml
[mcp_servers.arsenkin]
command = "uvx"
args = ["--from", "git+https://github.com/zai-one/arsenkin-mcp@v0.6.0", "arsenkin-mcp"]
env = { ARSENKIN_TOKEN_FILE = "/path/to/arsenkin.token", ARSENKIN_STATE_PATH = "/path/to/arsenkin.sqlite" }
```

**Claude Desktop** — `claude_desktop_config.json`: the same `mcpServers` block as Cursor.

## Skills (agent playbooks)

Each skill is a self-contained folder `skills/<name>/` (`SKILL.md` + its own `references/`,
`templates/`); copy the folder and it works. Agents load the short `SKILL.md` only when the task matches
and open the other files on demand. Clients without skills get the same flows as MCP prompts and the
`arsenkin://playbook` / `arsenkin://guide/{topic}` resources.

| Skill | What it does |
|---|---|
| `arsenkin-serp-clustering` | Cluster keywords by SERP overlap: estimate, approval, submit, poll, clusters table. |
| `arsenkin-index-check` | Yandex/Google indexation of URLs with a non-indexed report. |
| `arsenkin-text-relevance` | LSI/highlights, Title/H1 of the TOP vs your page, optional copywriting brief. |
| `arsenkin-semantic-core` | Semantics -> clusters -> positions: Wordstat phrases/frequency, clustering, project groups and a position check. |

## Toolsets and read-only mode

Default: `meta`, `jobs`, `results`, `projects`. Opt-in `projects_write` (`arsenkin_projects_write`: create/update/delete
projects, groups and tags, add/delete regions, competitors and keywords, `restore_keywords`, tag/untag groups
and keywords, run a paid position check — the latter also needs the operator setting `ARSENKIN_PROJECTS_PAID=on`;
`run_positions` is **not** counted against the ARSENKIN monthly budgets or `ARSENKIN_MAX_COST_PER_APPROVAL` and has no
cost estimate: its only gates are that setting and the operator approval). Free preview until `confirm=true`; then every write returns an
`approval_id` and `operator_command`; the operator reviews the exact request with `arsenkin-projects-approval --path FILE --list`
and accepts it outside MCP with the returned `arsenkin-projects-approval --path FILE --approval-id ID --digest D --accept`
(single use, request-bound, bound to the preparing principal and account, 30 min; at most 10 waiting per principal) before the agent repeats the call with `approval_id`.
If a write was sent but its result is unknown (`code: outcome_unknown`), do not retry: check with `arsenkin_projects`,
then the operator runs `arsenkin-projects-approval --path FILE --approval-id ID --resolve applied|not_applied`. `ARSENKIN_TOOLSETS=default`, `all` or a comma list (see `arsenkin://toolsets`); `ARSENKIN_TOOLS=a,b` adds single tools,
`ARSENKIN_DISABLED_TOOLS=a,b` removes them, `ARSENKIN_READ_ONLY=1` removes every write/paid tool.

## Example requests

- Сколько лимитов Arsenkin осталось?
- Кластеризуй этот список запросов для Москвы — сначала покажи стоимость.
- Проверь индексацию этих URL в Яндексе и Google.
- Что ТОП ожидает в тексте по запросу «ремонт киа»?
- Покажи сохранённые позиции проекта за месяц.
- Выгрузи результат задачи в CSV.
<!-- agent-block:end -->

## Access and limits

For execution, configure paid-task limits and approval, then run the worker with the same config and SQLite state. Exported values keep their JSON paths; specialised SEO tables are not generated automatically. Cancelling a job does not guarantee a refund for work already submitted.

### Updates

`arsenkin_check_update` compares the installed version with the latest [GitHub release](https://github.com/zai-one/arsenkin-mcp/releases) and returns the release link and the matching `uv tool install --force ...` command. It never installs anything and spends no Arsenkin limits. The result is cached for 24 hours next to the state database; when a newer release is cached, the server instructions and `arsenkin_local_diagnostics` mention it. Set `ARSENKIN_DISABLE_UPDATE_CHECK=1` to turn off both the tool's network request and the startup refresh.

Authenticated HTTP is available for a server deployment. See [HTTP setup](INSTALL.md#http), [configuration and permissions](docs/RUNTIME.md) and [Python package integration](INSTALL.md#python-package-and-platform-integration).

<details>
<summary>For developers: project checks</summary>

```sh
uv sync --frozen --all-groups --extra standalone
uv run --frozen --extra standalone python scripts/verify.py
uv run --frozen --extra standalone python scripts/verify_install.py
```

Tests use synthetic fixtures. A passing test run does not establish live provider connectivity.

</details>

## Built by ZAI.ONE

[ZAI.ONE](https://zai.one) is a digital agency working on websites, SEO, advertising and analytics. We also build tools that connect AI assistants to everyday work. [Talk to us on Telegram](https://t.me/zai_one) about setup, automation or an integration for your team.

## License, use and contributing

- **Use:** you may install and use this MCP server freely for yourself and your organisation, including commercial work. If it helps, please consider giving the repository a ⭐ — appreciated, never required.
- **Contribute:** [issues](https://github.com/zai-one/arsenkin-mcp/issues/new/choose) and pull requests are welcome; see [CONTRIBUTING.md](CONTRIBUTING.md). Never post tokens, cookies, sessions or account data.
- **Not allowed without written permission from ZAI.ONE:** copying code into other projects, forking for redistribution, embedding the server in other products or offering it as a competing service.
- License: [LicenseRef-ZAI-ONE 2.0](LICENSE) (source-available, not open source). Third-party notices and license history: [NOTICE](NOTICE).

TDQS

A3.9/5.0

Scored across 18 tools

Disambiguation4/5

The single vs batch variants (estimate/batch_estimate, prepare/batch_prepare, submit/batch_submit) are clearly paired and differentiated by scope, and descriptions explicitly state 'which when' and ordering. arsenkin_status vs arsenkin_task_status and get_result vs result_table vs export_result could momentarily overlap, but descriptions clearly separate account health, job polling, raw results, compact tables, and file export.

Naming Consistency4/5

All names use the arsenkin_ prefix and snake_case throughout, with consistent verb_noun forms (get_result, batch_estimate, check_update, request_hash_lookup). There is minor variance between bare nouns (projects, limits, status) and verb-led names, but the pattern is predictable and readable.

Tool Count4/5

18 tools is slightly heavy but justified by the full paid-job lifecycle (discover, estimate, approve, submit, poll, fetch, export, cancel) with mirrored single/batch pairs. Each tool has a distinct stage or purpose, so few feel redundant.

Completeness4/5

The surface covers the lifecycle end-to-end: catalog, estimate, approval, submit, poll, result retrieval/table/export, limits, diagnostics, ledger lookup, and cancellation. Minor gaps like listing all prior jobs or re-running a saved job are largely workable via task_status and projects.

Maintenance

ActivityMaintained
ResponsivenessNo issues