Skip to main content
Glama
mlenkov

APIForge MCP Server

by mlenkov
README.md
# APIForge MCP Server

MCP-сервер для интеграции API-сервисов с Hermes Agent и другими MCP-клиентами.

## Зачем это нужно

Hermes Agent — это AI-агент, который работает с инструментами через MCP (Model Context Protocol). Но для работы с реальными API (Яндекс Метрика, Search Console и др.) нужен прослойка, который:

1. **Генерирует инструменты автоматически** из JSON-конфигов API
2. **Управляет аутентификацией** (API Key, OAuth 2.0)
3. **Контролирует доступ** — какие инструменты доступны агенту

## Архитектура

```
Hermes Agent (MCP Client)
        │
   MCP Server (Python SDK)
   ┌────┴────┐
   │ Tools   │ ← генерируются из JSON-конфигов
   │ Auth    │ ← API Key / OAuth 2.0
   │ Access  │ ← allow/deny по инструментам
   └────┬────┘
        │
   HTTP (httpx)
        │
   ┌────┴────┐
   │ Yandex  │
   │ Google  │
   │ Custom  │
   └─────────┘
```

## Быстрый старт

```bash
# Установка
cd mcp-server
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

# Запуск (STDIO — для Hermes)
python -m apiforge_mcp.server

# Запуск (HTTP/SSE — удалённый доступ)
APIFORGE_TRANSPORT=sse python -m apiforge_mcp.server
```

## Конфигурация

### Конфиги API

Файлы в `configs/` определяют доступные API и их параметры:

```json
// configs/yandex_metrika.json
{
  "base_url": "https://api-metrika.yandex.net",
  "auth": { "type": "oauth" },
  "resources": {
    "counters_list": {
      "path": "/management/v1/counters",
      "method": "GET",
      "description": "List all counters"
    },
    "counter_stat": {
      "path": "/stat/v1/data",
      "method": "GET",
      "description": "Get statistics",
      "parameters": {
        "id": { "type": "integer", "required": true, "description": "Counter ID" },
        "metrics": { "type": "string", "required": true, "description": "Metrics" }
      }
    }
  }
}
```

**Добавление нового API:** просто кладёте JSON-файл в `configs/`. Инструменты генерируются автоматически.

### Контроль доступа

```json
// configs/access.json
{
  "default_role": "readonly",
  "tools": {
    "allow": ["*"],
    "deny": ["secret_*"]
  },
  "service_tools": {
    "yandex_metrika": {
      "allow": ["yandex_metrika_*"],
      "deny": []
    }
  }
}
```

**Уровни контроля:**
- **Global** — правила для всех инструментов
- **Service** — правила для конкретного API
- **Tool** — конкретный инструмент

**Приоритет:** Tool > Service > Global. Deny всегда побеждает Allow.

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

```bash
# Аутентификация
YANDEX_METRIKA_API_KEY=your_api_key
YANDEX_METRIKA_AUTH_PROVIDER=api_key  # или oauth

# Контроль доступа
APIFORGE_DEFAULT_ROLE=readonly        # readonly | readwrite | admin
YANDEX_METRIKA_ROLE=readwrite         # роль для конкретного сервиса

# Сервер
APIFORGE_TRANSPORT=stdio              # stdio | sse
APIFORGE_HOST=127.0.0.1              # для SSE
APIFORGE_PORT=8080                   # для SSE
APIFORGE_CONFIGS_DIR=./configs       # путь к конфигам
```

## Интеграция с Hermes Agent

### STDIO (локальный запуск)

```yaml
# ~/.hermes/config.yaml
mcp_servers:
  apiforge:
    command: python
    args: ["-m", "apiforge_mcp.server"]
    env:
      YANDEX_METRIKA_API_KEY: ${YANDEX_METRIKA_API_KEY}
      APIFORGE_DEFAULT_ROLE: readonly
```

### HTTP/SSE (удалённый доступ)

```yaml
# ~/.hermes/config.yaml
mcp_servers:
  apiforge:
    url: http://your-server:8080/sse
    headers:
      Authorization: Bearer ${MCP_TOKEN}
```

## MCP Примитивы

### Tools (инструменты)

Инструменты генерируются автоматически из конфигов:

| Инструмент | Описание | Метод |
|------------|----------|-------|
| `yandex_metrika_counters_list` | Список счетчиков | GET |
| `yandex_metrika_counter_stat` | Статистика | GET |
| `yandex_metrika_goals` | Цели | GET |
| `yandex_search_console_hosts` | Хосты | GET |
| `yandex_search_console_search_queries` | Запросы | GET |
| `get_audit_log` | Лог аудита | - |
| `list_services` | Список сервисов | - |

### Resources (документация для ИИ)

| Ресурс | Описание |
|--------|----------|
| `docs://guide` | Полное руководство по использованию |
| `docs://tools/{service}` | Документация по конкретному сервису |
| `docs://access` | Документация по контролю доступа |
| `docs://auth` | Документация по аутентификации |

**ИИ может читать эти ресурсы** через `resources/read` для получения контекста.

### Prompts (шаблоны для ИИ)

| Промпт | Когда использовать |
|--------|-------------------|
| `analytics_query` | Запрос аналитических данных |
| `api_exploration` | Изучение доступных API |
| `troubleshooting` | Диагностика проблем |

**ИИ может загружать эти промпты** через `prompts/get` для получения инструкций.

## Тестирование

```bash
# Все тесты
pytest tests/ -v

# Линтер
ruff check src/ tests/
```

## Структура проекта

```
mcp-server/
├── configs/
│   ├── access.json              # Правила доступа
│   ├── yandex_metrika.json      # API Яндекс Метрики
│   └── yandex_search_console.json
├── src/apiforge_mcp/
│   ├── server.py                # MCP сервер + динамическая генерация
│   ├── auth/
│   │   ├── manager.py           # Менеджер аутентификации
│   │   ├── api_key.py           # API Key провайдер
│   │   └── oauth.py             # OAuth 2.0 провайдер
│   ├── access/
│   │   └── policy.py            # Контроль доступа (roles + tools)
│   └── tools/
│       └── registry.py          # Реестр инструментов
├── tests/
│   └── test_server.py           # 32 теста
├── docs/
│   ├── adr/                     # Architecture Decision Records
│   └── AI_REFERENCE.md          # Справочник для ИИ
├── README.md                    # Основная документация
├── ARCHITECTURE.md              # Архитектурные решения
├── CHANGELOG.md                 # История изменений
├── CONTRIBUTING.md              # Как вносить вклад
├── SECURITY.md                  # Политика безопасности
├── RUNBOOK.md                   # Операционные процедуры
└── pyproject.toml
```

## Ключевые решения

1. **Динамическая генерация** — инструменты создаются из JSON, не хардкодятся
2. **APIForge как transport core** — HTTP-запросы через httpx с retry
3. **Многоуровневый контроль доступа** — glob-паттерны на 3 уровнях
4. **Асинхронность** — все запросы async/await для производительности
5. **Аудит** — логирование всех вызовов и отказов

TDQS

C2.9/5.0

Scored across 7 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: audit log, service listing, Yandex Metrika operations (list counters, get stats, list goals), and Yandex Webmaster operations (list hosts, get search queries). No overlapping functionality.

Naming Consistency2/5

Naming conventions are inconsistent. Generic tools use verb_noun (get_audit_log, list_services) but Yandex tools use a reversed pattern (yandex_metrika_counters_list, yandex_metrika_counter_stat) with mixed singular/plural forms. Two distinct styles coexist.

Tool Count4/5

With 7 tools, the count is appropriate for a focused server that combines generic API management with specific Yandex services. It's slightly limited but not excessive.

Completeness2/5

The tool surface is incomplete for the stated domain. Generic tools only provide audit and listing, missing CRUD operations. Yandex Metrika and Webmaster tools offer read-only operations (list, get stats, list goals) but lack create, update, delete, and other management actions.

Maintenance

ActivityInactive
ResponsivenessNo issues