Skip to main content
Glama
list91
by list91
README.md
# MCP CopyQ Server

MCP-сервер для интеграции CopyQ (менеджер буфера обмена) с LLM-агентами.

## Концепция

### Структура данных в CopyQ

```
mcp/
├── info/        # 🔒 только элементы (без подвкладок)
├── заметки/     # 🔒 только элементы (без подвкладок)
└── workspace/   # ✅ элементы + подвкладки
```

### Элемент (Item)

Каждый элемент содержит:
- **text** — основной текст
- **tags** — метки (массив строк)
- **note** — заметка к тексту

---

## Инструменты (3 шт.)

### 1. `mcp_read`

Универсальное чтение данных.

#### Параметры

| Параметр | Тип | Default | Описание |
|----------|-----|---------|----------|
| `mode` | `"tree"` / `"list"` / `"item"` / `"search"` | — | **обязательный** |
| `tab` | string | `""` | Путь: `"info"`, `"workspace/proj1"` |
| `index` | number | — | Для mode=item |
| `query` | string | — | Для mode=search (regex) |
| `search_in` | `"text"` / `"note"` / `"tags"` / `"all"` | `"all"` | Где искать |
| `max_depth` | number | 2 | Для tree — макс. глубина |
| `max_items` | number | 20 | Лимит элементов |
| `skip` | number | 0 | Пагинация — пропустить N |
| `include_text` | bool | true | Включить текст/превью |
| `include_tags` | bool | true | Включить метки |
| `include_note` | bool | false | Включить заметку |

#### Режимы (mode)

**`tree`** — структура вкладок с метаданными
```
mcp/info [5]
  0: "Инструкция по API..." [api,docs]
  1: "Конфиг сервера..." [config]
mcp/workspace [3]
  └─ mcp/workspace/проект1 [12]
```

**`list`** — элементы конкретной вкладки
```
mode:list|tab:info|total:47|showing:0-19
0|"Инструкция по API..."|[api,docs]|+note
1|"Конфиг сервера..."|[config]|
```

**`item`** — один элемент полностью

**`search`** — поиск по содержимому

#### Возможные ошибки

| Код | Описание |
|-----|----------|
| `TAB_NOT_FOUND` | Вкладка не существует |
| `INDEX_OUT_OF_BOUNDS` | Индекс за пределами |
| `INVALID_MODE` | Неизвестный mode |

#### Под капотом (CopyQ CLI)

```bash
# tree
copyq tab | grep "^mcp/"
copyq tab "mcp/..." count
copyq tab "mcp/..." read 0 | head -c 50

# list
copyq tab "mcp/${tab}" count
copyq tab "mcp/${tab}" read $i
copyq tab "mcp/${tab}" read "application/x-copyq-tags" $i

# item
copyq tab "mcp/${tab}" read ${index}
copyq tab "mcp/${tab}" read "application/x-copyq-tags" ${index}
copyq tab "mcp/${tab}" read "application/x-copyq-item-notes" ${index}

# search
copyq eval "/* JS: grep по tabs */"
```

---

### 2. `mcp_write`

Универсальная запись данных.

#### Параметры

| Параметр | Тип | Default | Описание |
|----------|-----|---------|----------|
| `mode` | string | — | **обязательный** (см. ниже) |
| `tab` | string | — | Путь вкладки |
| `index` | number | — | Для item-операций |
| `text` | string | — | Текст (для add/update) |
| `tags` | string[] | — | Метки |
| `note` | string | — | Заметка |
| `field` | `"text"` / `"note"` / `"tags"` | — | Для update — что менять |
| `edit_mode` | `"replace"` / `"append"` / `"prepend"` / `"substitute"` | `"replace"` | Как менять |
| `match` | string | — | Для substitute — что заменить |
| `to_tab` | string | — | Для move — куда переместить |
| `path` | string | — | Для tab_create/tab_delete |
| `intent` | `"execute"` / `"preview"` | `"execute"` | Выполнить или показать эффект |

#### Режимы (mode)

| mode | Уровень | Описание | Обязательные параметры |
|------|---------|----------|------------------------|
| `add` | item | Добавить элемент в начало | tab, text |
| `update` | item | Изменить элемент | tab, index, field, (text/tags/note) |
| `delete` | item | Удалить элемент | tab, index |
| `move` | item | Переместить в другую вкладку | tab, index, to_tab |
| `tab_create` | collection | Создать подвкладку | path (только workspace/*) |
| `tab_delete` | collection | Удалить подвкладку | path (только workspace/*) |

#### edit_mode для update

| field | edit_mode | Действие |
|-------|-----------|----------|
| text/note | `replace` | Полная замена |
| text/note | `append` | Дописать в конец |
| text/note | `prepend` | Дописать в начало |
| text/note | `substitute` | Заменить `match` → `text`/`note` |
| tags | `replace` | Заменить все метки |
| tags | `append` | Добавить метки (сохранив старые) |
| tags | `remove` | Удалить указанные метки |

#### intent: preview

При `intent="preview"` — не выполняет действие, а возвращает что произойдёт:
```
action: delete
target: mcp/info[3]
will_remove: "Текст который удалится..." | [метки] | +note
```

#### Возможные ошибки

| Код | Описание |
|-----|----------|
| `TAB_NOT_FOUND` | Вкладка не существует |
| `INDEX_OUT_OF_BOUNDS` | Индекс за пределами |
| `PERMISSION_DENIED` | tab_create/tab_delete вне workspace |
| `INVALID_MODE` | Неизвестный mode |
| `MISSING_PARAM` | Не хватает обязательного параметра |
| `MATCH_NOT_FOUND` | substitute: match не найден в тексте |

#### Формат ответа

```
ok|mode:add|tab:info|index:0|text_len:156|tags:2
```

#### Под капотом (CopyQ CLI)

```bash
# add
copyq tab "mcp/${tab}" write 0 \
  "text/plain" "${text}" \
  "application/x-copyq-tags" "${tags}" \
  "application/x-copyq-item-notes" "${note}"

# update (substitute)
OLD=$(copyq tab "mcp/${tab}" read ${index})
NEW=$(echo "$OLD" | sed "s/${match}/${value}/g")
TAGS=$(copyq tab "mcp/${tab}" read "application/x-copyq-tags" ${index})
NOTE=$(copyq tab "mcp/${tab}" read "application/x-copyq-item-notes" ${index})
copyq tab "mcp/${tab}" write ${index} \
  "text/plain" "$NEW" \
  "application/x-copyq-tags" "$TAGS" \
  "application/x-copyq-item-notes" "$NOTE"

# delete
copyq tab "mcp/${tab}" remove ${index}

# move
# read all → write to to_tab → remove from tab

# tab_create
copyq tab "mcp/${path}"

# tab_delete
copyq removeTab "mcp/${path}"
```

---

### 3. `mcp_validate`

Проверить корректность вызова без выполнения.

#### Параметры

| Параметр | Тип | Описание |
|----------|-----|----------|
| `tool` | `"read"` / `"write"` | Какой инструмент проверить |
| `params` | object | Параметры вызова |

#### Формат ответа

Успех:
```
valid: true | warnings: [] | estimated_tokens: 340
```

Ошибка:
```
valid: false | errors: ["TAB_NOT_FOUND: workspace/xxx"]
```

---

## Права доступа

| Операция | info | заметки | workspace |
|----------|:----:|:-------:|:---------:|
| read (все режимы) | ✅ | ✅ | ✅ |
| add | ✅ | ✅ | ✅ |
| update | ✅ | ✅ | ✅ |
| delete | ✅ | ✅ | ✅ |
| move | ✅ | ✅ | ✅ |
| tab_create | ❌ | ❌ | ✅ |
| tab_delete | ❌ | ❌ | ✅ |

---

## Установка

```bash
# Требования
# - Python 3.11+
# - CopyQ установлен и запущен
# - Путь к CopyQ: C:\Program Files\CopyQ\copyq.exe

# Установка
cd C:\sts\projects\mcp-copyq
uv venv
uv pip install -e .

# Запуск
uv run mcp-copyq
```

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

```json
{
  "mcpServers": {
    "copyq": {
      "command": "uv",
      "args": ["--directory", "C:\\sts\\projects\\mcp-copyq", "run", "mcp-copyq"]
    }
  }
}
```

---

## Примеры использования

### Получить структуру
```
mcp_read(mode="tree", max_depth=2, max_items=5)
```

### Список элементов вкладки
```
mcp_read(mode="list", tab="info", max_items=10, include_note=true)
```

### Прочитать элемент
```
mcp_read(mode="item", tab="info", index=0)
```

### Поиск
```
mcp_read(mode="search", query="API", search_in="all", max_items=10)
```

### Добавить элемент
```
mcp_write(mode="add", tab="info", text="Новая запись", tags=["important"])
```

### Изменить текст (дописать в конец)
```
mcp_write(mode="update", tab="info", index=0, field="text", edit_mode="append", text="\n\nДополнение")
```

### Заменить фрагмент
```
mcp_write(mode="update", tab="info", index=0, field="text", edit_mode="substitute", match="старое", text="новое")
```

### Добавить метку (сохранив существующие)
```
mcp_write(mode="update", tab="info", index=0, field="tags", edit_mode="append", tags=["urgent"])
```

### Удалить с превью
```
mcp_write(mode="delete", tab="info", index=0, intent="preview")
mcp_write(mode="delete", tab="info", index=0, intent="execute")
```

### Создать подвкладку
```
mcp_write(mode="tab_create", path="workspace/новый_проект")
```

### Переместить элемент
```
mcp_write(mode="move", tab="info", index=0, to_tab="workspace/архив")
```

---

## Принципы дизайна

1. **Минимум инструментов** — 3 вместо 10+
2. **Stateless** — каждый вызов независим
3. **Компактные ответы** — pipe-separated, без лишних полей
4. **Пагинация** — skip/max_items для больших данных
5. **Явные параметры** — `include_text` вместо `fields: "minimal"`
6. **Preview mode** — intent="preview" для опасных операций
7. **Чёткие ошибки** — коды + описания

---

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

```
mcp-copyq/
├── README.md
├── pyproject.toml
├── src/
│   └── mcp_copyq/
│       ├── __init__.py
│       ├── server.py          # MCP server
│       ├── copyq_client.py    # CopyQ CLI wrapper
│       ├── tools/
│       │   ├── __init__.py
│       │   ├── read.py        # mcp_read
│       │   ├── write.py       # mcp_write
│       │   └── validate.py    # mcp_validate
│       ├── models.py          # Pydantic models
│       └── errors.py          # Error codes
└── tests/
    ├── __init__.py
    ├── test_read.py
    ├── test_write.py
    ├── test_validate.py
    └── test_integration.py
```

---

## Лицензия

MIT

TDQS

A4.5/5.0

Scored across 3 tools

Disambiguation5/5

The three tools have clearly distinct purposes: mcp_read is for reading data from the clipboard manager, mcp_write is for writing data to it, and mcp_validate is for validating parameters before operations. There is no overlap in functionality, making it easy for an agent to select the correct tool.

Naming Consistency5/5

All tool names follow a consistent 'mcp_' prefix with a descriptive verb (read, write, validate), using snake_case uniformly. This predictable pattern enhances readability and reduces confusion.

Tool Count4/5

With three tools, the count is appropriate for the server's purpose of clipboard management, covering read, write, and validation operations. It is well-scoped, though a slightly larger set might offer more granularity, but this is reasonable.

Completeness5/5

The tool set provides complete CRUD and lifecycle coverage for clipboard data management: mcp_read handles retrieval (including search and listing), mcp_write supports creation, updates, deletion, and movement, and mcp_validate ensures parameter integrity. No obvious gaps exist for the domain.

Maintenance

ActivityInactive
ResponsivenessNo issues