MCP CopyQ Server
MCP-сервер для интеграции CopyQ (менеджер буфера обмена) с LLM-агентами.
Концепция
Структура данных в CopyQ
mcp/
├── info/ # 🔒 только элементы (без подвкладок)
├── заметки/ # 🔒 только элементы (без подвкладок)
└── workspace/ # ✅ элементы + подвкладки
Элемент (Item)
Каждый элемент содержит:
Инструменты (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)
# 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)
# 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 | ❌ | ❌ | ✅ |
Установка
# Требования
# - 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
{
"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/архив")
Принципы дизайна
Минимум инструментов — 3 вместо 10+
Stateless — каждый вызов независим
Компактные ответы — pipe-separated, без лишних полей
Пагинация — skip/max_items для больших данных
Явные параметры — include_text вместо fields: "minimal"
Preview mode — intent="preview" для опасных операций
Чёткие ошибки — коды + описания
Структура проекта
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