Skip to main content
Glama
sape-mcp
by sshra
README.md
# sape-mcp

MCP-сервер ([Model Context Protocol](https://modelcontextprotocol.io)) для работы с [sape.ru](https://www.sape.ru) через XML-RPC API. Позволяет любому MCP-совместимому LLM-боту (Claude Desktop, Hermes, Cursor и др.) читать список проектов, смотреть ссылки и бюджеты, искать площадки по заданию и докупать ссылки.

## Возможности

- чтение баланса, информации об аккаунте и расходах;
- список проектов и параметров каждого проекта;
- URL-ы проектов, анкоры, размещённые ссылки и их статусы;
- поиск страниц площадок по фильтрам (тема, цена, тИЦ/PR и др.) — «задание» на покупку;
- покупка ссылки (одиночная и пакетная) с ограничением максимальной цены;
- универсальный вызов любого метода [XML-RPC API sape.ru](https://api.sape.ru/xmlrpc/) (`sape_call`).

Встроен rate-limiter: не более 115 запросов/мин (лимит sape.ru — 120), автоматическая авторизация по токену и повторный login при разрыве сессии.

## Установка

```bash
pip install .
```

## Получение токена

1. Зайдите на https://passport.sape.ru/security/token/ под своим аккаунтом.
2. Сгенерируйте API-токен.

Примечание: для авторизации API используется логин аккаунта (то, чем вы входите в интерфейс sape.ru). E-mail и user_id не подходят — API принимает только пару логин + токен; активен ровно один токен на аккаунт (перегенерация в Паспорте).

## Конфигурация (переменные окружения)

| Переменная | Обязательна | По умолчанию | Описание |
|---|---|---|---|
| `SAPE_LOGIN` | да | — | логин входа в sape.ru (**именно логин, не e-mail и не user_id** — API принимает только логин; ID пользователя возвращается как результат `sape.login`, а не передаётся) |
| `SAPE_TOKEN` | да | — | API-токен |
| `SAPE_API_URL` | нет | `https://api.sape.ru/xmlrpc/` | адрес API |
| `SAPE_MAX_CALLS_PER_MINUTE` | нет | `115` | троттлинг запросов |

## Подключение к агенту

Два способа — выберите один.

### Вариант A: удалённый MCP-сервер (рекомендуется, сервер живёт в Docker)

Поднимите контейнер (см. раздел «Запуск в Docker» ниже), затем подключите endpoint `http://<host>:8080/mcp`.

Клиенты с поддержкой удалённых MCP (Claude Desktop «Add custom connector», Cursor, Cline и др.):

```json
{
  "mcpServers": {
    "sape": {
      "url": "http://localhost:8080/mcp"
    }
  }
}
```

Плюсы: один постоянный процесс, одна cookie-сессия к API, честный rate-limit, обновление сервера без правки конфигов агентов.

### Вариант B: локальный stdio (сервер запускается клиентом)

Требуется установленный пакет: `pip install sape-mcp` (после публикации на PyPI) или `pip install git+https://github.com/sshra/sape-mcp.git`.

Универсальный формат (Claude Desktop, Cursor, Cline, большинство MCP-клиентов):

```json
{
  "mcpServers": {
    "sape": {
      "command": "sape-mcp",
      "env": {
        "SAPE_LOGIN": "ваш_логин",
        "SAPE_TOKEN": "ваш_токен"
      }
    }
  }
}
```

Если `sape-mcp` не в PATH — укажите полный путь (`C:\\Python313\\Scripts\\sape-mcp.exe`) или запускайте через Python:

```json
{
  "mcpServers": {
    "sape": {
      "command": "python",
      "args": ["-m", "sape_mcp"],
      "env": { "SAPE_LOGIN": "...", "SAPE_TOKEN": "..." }
    }
  }
}
```

Для stdio-клиентов доступен и гибрид: клиент сам поднимает контейнер на сессию:

```json
{
  "mcpServers": {
    "sape": {
      "command": "docker",
      "args": ["run", "--rm", "-i", "--env-file", "/абсолютный/путь/.env", "sape-mcp"],
      "env": { "SAPE_TRANSPORT": "stdio" }
    }
  }
}
```

(образ собирается один раз: `docker build -t sape-mcp https://github.com/sshra/sape-mcp.git#master:docker`)

### Переменные окружения

| Переменная | Обязательна | По умолчанию | Описание |
|---|---|---|---|
| `SAPE_LOGIN` | да | — | логин входа в sape.ru (**именно логин, не e-mail и не user_id** — API принимает только логин; ID пользователя возвращается как результат `sape.login`, а не передаётся) |
| `SAPE_TOKEN` | да | — | API-токен с https://passport.sape.ru/security/token/ (активен один на аккаунт) |
| `SAPE_API_URL` | нет | `https://api.sape.ru/xmlrpc/` | адрес API |
| `SAPE_MAX_CALLS_PER_MINUTE` | нет | `115` | троттлинг запросов (лимит sape.ru — 120) |
| `SAPE_TRANSPORT` | нет | `stdio` | `stdio` или `streamable-http` (режим Docker) |
| `SAPE_HOST` / `SAPE_PORT` | нет | `0.0.0.0` / `8000` | адрес HTTP-сервера в Docker-режиме |

### Hermes Agent

```yaml
mcp_servers:
  sape:
    url: http://localhost:8080/mcp   # вариант A
    # либо вариант B:
    # command: sape-mcp
    # env: { SAPE_LOGIN: "...", SAPE_TOKEN: "..." }
```

## Инструменты

| Инструмент | Назначение |
|---|---|
| `get_balance` | баланс (полный и доступный) |
| `get_user` | аккаунт, расходы за сутки/неделю, бюджет |
| `list_projects` | список проектов с числом урлов/ссылок |
| `get_project` | параметры проекта и расходы |
| `list_urls` | URL-ы проекта |
| `get_url_anchors` | анкоры URL-а и лимиты использования |
| `get_project_links` | все ссылки проекта со статусами |
| `get_url_links` | ссылки конкретного URL-а |
| `search_pages` | поиск площадок/страниц по фильтрам (задание на покупку) |
| `create_placement` | покупка ссылки (⚠️ тратит деньги; есть max_price) |
| `create_placements` | пакетная покупка (до 200 за вызов) |
| `sape_call` | универсальный вызов любого метода API |

## Пример сценария для бота

> «Покажи мои проекты. Для проекта X найди до 20 площадок по теме "ремонт" не дороже 50 руб. и докупи по 1 ссылке, но не трать больше 500 руб. за всё»

Бот: `list_projects` → `list_urls` → `search_pages` (фильтр по теме/цене) → `create_placements` с `max_price`.

## Безопасность

- Токен хранится только в переменных окружения вашего MCP-клиента, не пишется в логи.
- Покупка ссылок расходует реальные средства: используйте `max_price` для ограничения цены, а бюджет — инструмент `get_balance`.
- API sape.ru ограничен 120 запросами/мин на аккаунт; сервер троттлит на 115.

## Запуск в Docker (независимый контейнер)

Docker-файлы живут в папке [docker/](docker/) и собирают образ **из этого репозитория** — локальные исходники не нужны.

Вариант 1 — одной командой (контекст сборки — git-репозиторий):

```bash
docker build -t sape-mcp https://github.com/sshra/sape-mcp.git#master:docker
```

Вариант 2 — через compose (нужен только .env рядом с папкой docker):

```bash
git clone https://github.com/sshra/sape-mcp.git && cd sape-mcp
cp .env.example .env    # заполнить SAPE_LOGIN и SAPE_TOKEN
docker compose -f docker/docker-compose.yml up -d
```

Сервер поднимется в режиме streamable-http, MCP-endpoint: `http://localhost:8080/mcp`.

Подключение клиентов, поддерживающих удалённые MCP-серверы:

```json
{
  "mcpServers": {
    "sape": {
      "url": "http://localhost:8080/mcp"
    }
  }
}
```

Для клиентов, которые умеют только stdio, контейнер можно использовать без compose-сети:

```json
{
  "mcpServers": {
    "sape": {
      "command": "docker",
      "args": ["run", "--rm", "-i", "--env-file", "/путь/к/.env", "sape-mcp"],
      "env": { "SAPE_TRANSPORT": "stdio" }
    }
  }
}
```

(образ собирается один раз: `docker build -t sape-mcp .` — либо вариант 1 выше: сборка напрямую из GitHub)

Логи: `docker compose logs -f sape-mcp`.

## Разработка

```bash
pip install -e .[dev]
pytest
```

## Лицензия

MIT

TDQS

B3.2/5.0

Scored across 12 tools

Disambiguation4/5

Most tools have clearly distinct scopes: account, projects, URLs, anchors, page search, and placement creation. Minor overlap exists between get_balance and get_user, and between get_project_links and get_url_links, but descriptions clarify project-level versus URL-level scope. sape_call overlaps by design as a fallback but is explicitly framed that way.

Naming Consistency4/5

The set mostly follows a predictable snake_case verb_noun convention: get_*, list_*, search_pages, create_placement, create_placements. The main deviations are the generic sape_call and the singular/plural pair create_placement/create_placements, which is readable but slightly easy to confuse.

Tool Count5/5

Twelve tools is well within the appropriate range for a focused Sape integration. The set covers reads, search, single and batch purchases, plus a generic fallback without becoming bloated.

Completeness4/5

Core workflows are covered: account balance, user info, projects, URLs, anchors, existing links, page search, and link purchase. Dedicated update/delete operations for placements and project/URL lifecycle management are missing, but sape_call provides a generic escape hatch for unsupported API methods.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues