REFERENCE.md•39.3 kB
# MCP CopyQ — Полное справочное руководство
> Версия: 0.1.0
> Это исчерпывающая документация для проектирования агентов, работающих с MCP CopyQ.
---
## Оглавление
1. [Архитектура и концепции](#1-архитектура-и-концепции)
2. [Структура данных](#2-структура-данных)
3. [Инструмент mcp_read](#3-инструмент-mcp_read)
4. [Инструмент mcp_write](#4-инструмент-mcp_write)
5. [Инструмент mcp_validate](#5-инструмент-mcp_validate)
6. [Работа с метками (tags)](#6-работа-с-метками-tags)
7. [Работа с заметками (notes)](#7-работа-с-заметками-notes)
8. [Read-only доступ к внешним вкладкам](#8-read-only-доступ-к-внешним-вкладкам)
9. [Формат ответов](#9-формат-ответов)
10. [Коды ошибок](#10-коды-ошибок)
11. [Паттерны использования](#11-паттерны-использования)
12. [Ограничения и нюансы](#12-ограничения-и-нюансы)
---
## 1. Архитектура и концепции
### 1.1 Что такое MCP CopyQ
MCP CopyQ — это MCP-сервер (Model Context Protocol), предоставляющий агентам структурированный доступ к менеджеру буфера обмена CopyQ. Сервер позволяет:
- **Читать** данные из любых вкладок CopyQ
- **Записывать** данные только в защищённую область `mcp/*`
- **Организовывать** информацию с помощью вкладок, меток и заметок
### 1.2 Принцип изоляции
```
CopyQ (весь буфер обмена)
├── mcp/ ← УПРАВЛЯЕМАЯ ОБЛАСТЬ (read/write)
│ ├── info/ ← Общая информация
│ ├── заметки/ ← Заметки
│ └── workspace/ ← Проекты (+ подвкладки)
│ ├── project1/
│ └── project2/
├── &буфер обмена ← ВНЕШНЯЯ ОБЛАСТЬ (read-only)
├── архив ← ВНЕШНЯЯ ОБЛАСТЬ (read-only)
├── личные_вкладки/ ← ВНЕШНЯЯ ОБЛАСТЬ (read-only)
└── ...
```
### 1.3 Три инструмента
| Инструмент | Назначение |
|------------|------------|
| `mcp_read` | Чтение данных (tree, list, item, search) |
| `mcp_write` | Запись данных (add, update, delete, move, tab_create, tab_delete) |
| `mcp_validate` | Проверка параметров перед выполнением |
---
## 2. Структура данных
### 2.1 Иерархия
```
Вкладка (Tab)
└── Элемент (Item) [index: 0, 1, 2, ...]
├── text — основной текст (обязательно)
├── tags — список меток (опционально)
└── note — заметка/комментарий (опционально)
```
### 2.2 Управляемые вкладки (mcp/*)
| Вкладка | Относительный путь | Полный путь в CopyQ | Подвкладки |
|---------|-------------------|---------------------|------------|
| Информация | `info` | `mcp/info` | ❌ Нет |
| Заметки | `заметки` | `mcp/заметки` | ❌ Нет |
| Рабочая область | `workspace` | `mcp/workspace` | ✅ Да |
### 2.3 Индексация элементов
- Индексы начинаются с **0**
- Новые элементы добавляются в **начало** (index=0)
- После добавления/удаления индексы **сдвигаются**
```
До добавления: После добавления "C":
[0] "A" [0] "C" ← новый
[1] "B" [1] "A" ← был 0
[2] "B" ← был 1
```
### 2.4 Пути вкладок
**Для mcp/* вкладок** — используй относительный путь:
```
tab="info" → mcp/info
tab="workspace" → mcp/workspace
tab="workspace/myproject" → mcp/workspace/myproject
```
**Для внешних вкладок** — используй полный путь + scope:
```
tab="&буфер обмена", scope="external"
tab="архив", scope="external"
tab="copostly/команды", scope="external"
```
---
## 3. Инструмент mcp_read
### 3.1 Общие параметры
| Параметр | Тип | По умолчанию | Описание |
|----------|-----|--------------|----------|
| `mode` | string | **required** | Режим: `tree`, `list`, `item`, `search` |
| `scope` | string | `"mcp"` | Область: `mcp`, `all`, `external` |
| `max_items` | int | 20 | Макс. элементов (1-100) |
| `skip` | int | 0 | Пропустить N элементов (пагинация) |
| `include_text` | bool | true | Включить текст/превью |
| `include_tags` | bool | true | Включить метки |
| `include_note` | bool | false | Включить заметки |
### 3.2 Режим tree — Дерево вкладок
**Назначение:** Получить структуру вкладок с превью элементов.
**Параметры:**
| Параметр | Тип | По умолчанию | Описание |
|----------|-----|--------------|----------|
| `max_depth` | int | 2 | Глубина обхода (1-10) |
**Примеры:**
```python
# Дерево только mcp/* вкладок
mcp_read(mode="tree")
# Дерево ВСЕХ вкладок CopyQ
mcp_read(mode="tree", scope="all", max_depth=5)
# Только внешние вкладки
mcp_read(mode="tree", scope="external")
# Без текста, только структура
mcp_read(mode="tree", scope="all", include_text=False, max_items=0)
```
**Формат ответа:**
```
info [47]
0:|"Текст первого элемента..."|[tag1,tag2]|+note
1:|"Текст второго элемента..."|[tag3]
workspace [3]
0:|"Проект Alpha"|[project,active]
workspace/project1 [12]
0:|"Описание проекта..."|[doc]
&буфер обмена [8240] [external]
0:|"Скопированный текст..."|[]
```
**Маркеры:**
- `[N]` — количество элементов
- `[external]` — внешняя вкладка (read-only)
- `+note` — элемент имеет заметку
- `[tag1,tag2]` — метки элемента
### 3.3 Режим list — Список элементов
**Назначение:** Получить список элементов из конкретной вкладки.
**Параметры:**
| Параметр | Тип | По умолчанию | Описание |
|----------|-----|--------------|----------|
| `tab` | string | **required** | Путь вкладки |
**Примеры:**
```python
# Список из mcp/info
mcp_read(mode="list", tab="info")
# С пагинацией
mcp_read(mode="list", tab="info", skip=20, max_items=10)
# С заметками
mcp_read(mode="list", tab="workspace/project1", include_note=True)
# Внешняя вкладка
mcp_read(mode="list", tab="&буфер обмена", scope="external", max_items=5)
```
**Формат ответа:**
```
mode:list|tab:info|full_path:mcp/info|total:47|showing:0-19
0|"Текст элемента 0..."|[tag1,tag2]|+note
1|"Текст элемента 1..."|[tag3]
2|"Текст элемента 2..."|[]
...
```
**Для внешних вкладок:**
```
mode:list|tab:&буфер обмена|scope:external|total:8240|showing:0-4
0|"Скопированный текст..."|[]
1|"Другой текст..."|[метка]
```
### 3.4 Режим item — Полный элемент
**Назначение:** Получить один элемент со всеми данными.
**Параметры:**
| Параметр | Тип | По умолчанию | Описание |
|----------|-----|--------------|----------|
| `tab` | string | **required** | Путь вкладки |
| `index` | int | **required** | Индекс элемента |
**Примеры:**
```python
# Полный элемент из mcp/info
mcp_read(mode="item", tab="info", index=0, include_note=True)
# Из внешней вкладки
mcp_read(mode="item", tab="архив", index=5, scope="external", include_note=True)
```
**Формат ответа:**
```
mode:item|tab:info|full_path:mcp/info|index:0
text:Полный текст элемента без обрезки...
tags:[tag1,tag2,tag3]
note:Заметка к элементу
```
**Для внешних:**
```
mode:item|tab:архив|scope:external|index:5
text:Полный текст...
tags:[метка]
note:
```
### 3.5 Режим search — Поиск
**Назначение:** Поиск по регулярному выражению.
**Параметры:**
| Параметр | Тип | По умолчанию | Описание |
|----------|-----|--------------|----------|
| `query` | string | **required** | Regex-паттерн (регистронезависимый) |
| `search_in` | string | `"all"` | Где искать: `text`, `note`, `tags`, `all` |
**Примеры:**
```python
# Поиск в mcp/*
mcp_read(mode="search", query="TODO")
# Поиск везде
mcp_read(mode="search", query="важно", scope="all")
# Только в метках
mcp_read(mode="search", query="project", search_in="tags")
# Regex
mcp_read(mode="search", query="error|warning", scope="all")
```
**Формат ответа:**
```
mode:search|query:TODO|scope:mcp|results:3
info[2]|"Нужно сделать TODO..."|[task]|match:text
workspace/project1[0]|"TODO: исправить баг"|[bug,todo]|match:text,tags
заметки[5]|"Заметка с TODO"|[]|match:text
```
**С внешними:**
```
mode:search|query:важно|scope:all|results:5
info[0]|"Важная информация"|[важно]|match:text,tags
&буфер обмена[15]|"Очень важно!"|[]|match:text|external
архив[3]|"Важный документ"|[]|match:text|external
```
---
## 4. Инструмент mcp_write
### 4.1 Общие параметры
| Параметр | Тип | По умолчанию | Описание |
|----------|-----|--------------|----------|
| `mode` | string | **required** | Режим операции |
| `intent` | string | `"execute"` | `execute` или `preview` |
### 4.2 Режим add — Добавление
**Назначение:** Добавить новый элемент в начало вкладки.
**Параметры:**
| Параметр | Тип | Обязательный | Описание |
|----------|-----|--------------|----------|
| `tab` | string | ✅ | Путь вкладки |
| `text` | string | ✅ | Текст элемента |
| `tags` | array | ❌ | Список меток |
| `note` | string | ❌ | Заметка |
**Примеры:**
```python
# Простое добавление
mcp_write(mode="add", tab="info", text="Новая запись")
# С метками и заметкой
mcp_write(
mode="add",
tab="workspace/project1",
text="Описание задачи",
tags=["task", "high-priority"],
note="Срок: до конца недели"
)
# Предпросмотр перед добавлением
mcp_write(mode="add", tab="info", text="Тест", intent="preview")
```
**Ответ (execute):**
```
ok|mode:add|tab:info|full_path:mcp/info|index:0|text_len:156|tags:2|note:True
```
**Ответ (preview):**
```
preview|mode:add
tab:info
will_add:
text:"Описание задачи..."
tags:[task,high-priority]
note:"Срок: до конца недели"
```
### 4.3 Режим update — Обновление
**Назначение:** Изменить конкретное поле существующего элемента.
**Параметры:**
| Параметр | Тип | Обязательный | Описание |
|----------|-----|--------------|----------|
| `tab` | string | ✅ | Путь вкладки |
| `index` | int | ✅ | Индекс элемента |
| `field` | string | ✅ | Поле: `text`, `tags`, `note` |
| `edit_mode` | string | ❌ | Способ редактирования |
| `text` | string | * | Новый текст (если field=text) |
| `tags` | array | * | Новые метки (если field=tags) |
| `note` | string | * | Новая заметка (если field=note) |
| `match` | string | * | Строка для замены (если edit_mode=substitute) |
**Режимы редактирования (edit_mode):**
| edit_mode | text | tags | note | Описание |
|-----------|------|------|------|----------|
| `replace` | ✅ | ✅ | ✅ | Полная замена (по умолчанию) |
| `append` | ✅ | ✅ | ✅ | Добавить в конец |
| `prepend` | ✅ | ❌ | ✅ | Добавить в начало |
| `substitute` | ✅ | ❌ | ✅ | Заменить подстроку |
| `remove` | ❌ | ✅ | ❌ | Удалить метки |
**Примеры:**
```python
# Полная замена текста
mcp_write(mode="update", tab="info", index=0, field="text", text="Новый текст")
# Добавить текст в конец
mcp_write(mode="update", tab="info", index=0, field="text", text="\n\nДополнение", edit_mode="append")
# Замена подстроки
mcp_write(mode="update", tab="info", index=0, field="text", text="DONE", match="TODO", edit_mode="substitute")
# Добавить метки к существующим
mcp_write(mode="update", tab="info", index=0, field="tags", tags=["new-tag"], edit_mode="append")
# Удалить конкретные метки
mcp_write(mode="update", tab="info", index=0, field="tags", tags=["old-tag"], edit_mode="remove")
# Заменить заметку
mcp_write(mode="update", tab="info", index=0, field="note", note="Новая заметка")
```
**Ответ:**
```
ok|mode:update|tab:info|full_path:mcp/info|index:0|field:text
```
### 4.4 Режим delete — Удаление
**Назначение:** Удалить элемент по индексу.
**Параметры:**
| Параметр | Тип | Обязательный |
|----------|-----|--------------|
| `tab` | string | ✅ |
| `index` | int | ✅ |
**Примеры:**
```python
# Предпросмотр удаления
mcp_write(mode="delete", tab="info", index=5, intent="preview")
# Удаление
mcp_write(mode="delete", tab="info", index=5)
```
**Ответ (preview):**
```
preview|mode:delete
tab:info|index:5
will_delete:
text:"Текст удаляемого элемента..."
tags:[tag1,tag2] +note
```
**Ответ (execute):**
```
ok|mode:delete|tab:info|full_path:mcp/info|index:5
```
### 4.5 Режим move — Перемещение
**Назначение:** Переместить элемент в другую вкладку.
**Параметры:**
| Параметр | Тип | Обязательный | Описание |
|----------|-----|--------------|----------|
| `tab` | string | ✅ | Исходная вкладка |
| `index` | int | ✅ | Индекс элемента |
| `to_tab` | string | ✅ | Целевая вкладка |
**Примеры:**
```python
# Переместить из info в workspace
mcp_write(mode="move", tab="info", index=0, to_tab="workspace/project1")
# Предпросмотр
mcp_write(mode="move", tab="info", index=0, to_tab="заметки", intent="preview")
```
**Ответ:**
```
ok|mode:move|from:mcp/info|to:mcp/workspace/project1|new_index:0
```
### 4.6 Режим tab_create — Создание вкладки
**Назначение:** Создать новую подвкладку в workspace.
**Ограничение:** Только внутри `workspace/*`
**Параметры:**
| Параметр | Тип | Обязательный |
|----------|-----|--------------|
| `path` | string | ✅ |
**Примеры:**
```python
# Создать подвкладку
mcp_write(mode="tab_create", path="workspace/new-project")
# Вложенная структура
mcp_write(mode="tab_create", path="workspace/project1/subtask")
```
**Ответ:**
```
ok|mode:tab_create|path:workspace/new-project|full_path:mcp/workspace/new-project|status:created
```
**Если уже существует:**
```
ok|mode:tab_create|path:workspace/new-project|full_path:mcp/workspace/new-project|status:already_exists
```
### 4.7 Режим tab_delete — Удаление вкладки
**Назначение:** Удалить подвкладку из workspace.
**Ограничение:** Только внутри `workspace/*`
**Параметры:**
| Параметр | Тип | Обязательный |
|----------|-----|--------------|
| `path` | string | ✅ |
**Примеры:**
```python
# Предпросмотр
mcp_write(mode="tab_delete", path="workspace/old-project", intent="preview")
# Удаление
mcp_write(mode="tab_delete", path="workspace/old-project")
```
**Ответ (preview):**
```
preview|mode:tab_delete
will_delete:mcp/workspace/old-project
items_count:15
```
**Ответ (execute):**
```
ok|mode:tab_delete|path:workspace/old-project|full_path:mcp/workspace/old-project|items_removed:15
```
---
## 5. Инструмент mcp_validate
### 5.1 Назначение
Проверить параметры вызова **до** выполнения. Полезно для:
- Проверки существования вкладки
- Проверки границ индекса
- Оценки размера ответа
### 5.2 Параметры
| Параметр | Тип | Описание |
|----------|-----|----------|
| `tool` | string | `"read"` или `"write"` |
| `params` | object | Параметры для проверки |
### 5.3 Примеры
```python
# Проверить read
mcp_validate(
tool="read",
params={"mode": "list", "tab": "info", "max_items": 50}
)
# Проверить write
mcp_validate(
tool="write",
params={"mode": "add", "tab": "workspace/project1", "text": "Тест"}
)
```
### 5.4 Формат ответа
**Успех:**
```
valid:true|warnings:0|estimated_tokens:450
```
**С предупреждениями:**
```
valid:true|warnings:1
warning|LARGE_RESPONSE|max_items=100 may return large response
estimated_tokens:2500
```
**Ошибка:**
```
valid:false|errors:1
error|TAB_NOT_FOUND|Tab not found: nonexistent
```
---
## 6. Работа с метками (tags)
### 6.1 Что такое метки
Метки — это список строк, присвоенных элементу для категоризации:
```
text: "Важная задача"
tags: ["task", "high-priority", "deadline:2024-01"]
note: "Комментарий"
```
### 6.2 Добавление меток при создании
```python
mcp_write(
mode="add",
tab="info",
text="Новый элемент",
tags=["category1", "category2"]
)
```
### 6.3 Операции с метками существующего элемента
**Полная замена меток:**
```python
mcp_write(
mode="update", tab="info", index=0,
field="tags",
tags=["new-tag1", "new-tag2"],
edit_mode="replace"
)
```
**Добавить новые метки:**
```python
mcp_write(
mode="update", tab="info", index=0,
field="tags",
tags=["additional-tag"],
edit_mode="append"
)
# Результат: существующие метки + additional-tag (без дубликатов)
```
**Удалить конкретные метки:**
```python
mcp_write(
mode="update", tab="info", index=0,
field="tags",
tags=["tag-to-remove"],
edit_mode="remove"
)
```
### 6.4 Поиск по меткам
```python
# Найти все элементы с меткой "important"
mcp_read(mode="search", query="important", search_in="tags")
# Regex для нескольких меток
mcp_read(mode="search", query="task|todo|bug", search_in="tags")
```
### 6.5 Соглашения по именованию меток
Рекомендуемые паттерны:
| Паттерн | Пример | Описание |
|---------|--------|----------|
| Простые | `important`, `draft` | Категории |
| С префиксом | `type:task`, `status:done` | Типизированные |
| С датой | `deadline:2024-01-15` | Временные метки |
| Иерархические | `project/frontend/react` | Вложенные категории |
---
## 7. Работа с заметками (notes)
### 7.1 Что такое заметка
Заметка — это дополнительное текстовое поле элемента, отделённое от основного текста:
```
text: "Ссылка на документацию: https://..."
tags: ["doc", "api"]
note: "Актуально для версии 2.0. Проверить после обновления."
```
### 7.2 Когда использовать заметки
- Метаинформация, не являющаяся частью основного контента
- Комментарии к элементу
- Инструкции по использованию
- История изменений
### 7.3 Добавление заметки
**При создании:**
```python
mcp_write(
mode="add",
tab="info",
text="Основной текст",
note="Это заметка к тексту"
)
```
**К существующему элементу:**
```python
mcp_write(
mode="update", tab="info", index=0,
field="note",
note="Новая заметка"
)
```
### 7.4 Редактирование заметки
```python
# Дополнить заметку
mcp_write(
mode="update", tab="info", index=0,
field="note",
note="\n---\nДобавлено: новая информация",
edit_mode="append"
)
# Заменить часть заметки
mcp_write(
mode="update", tab="info", index=0,
field="note",
note="ПРОВЕРЕНО",
match="TODO",
edit_mode="substitute"
)
```
### 7.5 Чтение заметок
**По умолчанию заметки НЕ включаются** (экономия токенов):
```python
# Без заметок (по умолчанию)
mcp_read(mode="list", tab="info")
# Результат: 0|"Текст..."|[tags]|+note ← только маркер +note
# С заметками
mcp_read(mode="list", tab="info", include_note=True)
# Результат: 0|"Текст..."|[tags]|note:Текст заметки...
# Полный элемент с заметкой
mcp_read(mode="item", tab="info", index=0, include_note=True)
```
---
## 8. Read-only доступ к внешним вкладкам
### 8.1 Параметр scope
| Значение | Описание | Чтение | Запись |
|----------|----------|--------|--------|
| `mcp` | Только mcp/* вкладки (по умолчанию) | ✅ | ✅ |
| `all` | Все вкладки CopyQ | ✅ | ❌ для внешних |
| `external` | Только НЕ-mcp вкладки | ✅ | ❌ |
### 8.2 Идентификация внешних вкладок
В ответах внешние вкладки маркируются:
**В tree:**
```
&буфер обмена [8240] [external]
архив [150] [external]
info [47] ← без маркера = mcp
```
**В list:**
```
mode:list|tab:&буфер обмена|scope:external|total:8240|showing:0-19
```
**В search:**
```
&буфер обмена[5]|"Текст..."|[метка]|match:text|external
info[2]|"Текст..."|[tag]|match:text ← без external = mcp
```
### 8.3 Примеры чтения внешних вкладок
```python
# Получить дерево всех вкладок
mcp_read(mode="tree", scope="all", max_depth=3)
# Список элементов из буфера обмена
mcp_read(mode="list", tab="&буфер обмена", scope="external")
# Конкретный элемент из архива
mcp_read(mode="item", tab="архив", index=10, scope="external")
# Поиск во всех вкладках
mcp_read(mode="search", query="password", scope="all")
# Только во внешних
mcp_read(mode="search", query="код", scope="external")
```
### 8.4 Путь к внешним вкладкам
Внешние вкладки указываются **полным именем**, как они отображаются в CopyQ:
```python
tab="&буфер обмена" # системный буфер
tab="архив" # простая вкладка
tab="copostly/команды" # вложенная вкладка
tab="личное/проекты/web" # глубоко вложенная
```
### 8.5 Поиск глубоко вложенных вкладок
Чтобы найти самую глубокую вкладку:
```python
# Шаг 1: Получить полное дерево
mcp_read(mode="tree", scope="all", max_depth=10, max_items=0, include_text=False)
# Шаг 2: Найти путь с максимальным количеством "/"
# Например: "copostly/прочее/тесты/промпты/многоэтапная генерация поста/готовые"
# Шаг 3: Прочитать содержимое
mcp_read(
mode="list",
tab="copostly/прочее/тесты/промпты/многоэтапная генерация поста/готовые",
scope="external",
include_note=True
)
```
---
## 9. Формат ответов
### 9.1 Принципы
- **Pipe-separated** — поля разделены `|`
- **Компактность** — минимум лишних символов
- **Самодокументируемость** — ключи в формате `key:value`
### 9.2 Превью текста
- Максимум **80 символов**
- Переносы строк заменяются на пробелы
- Обрезанный текст заканчивается на `...`
```
"Это длинный текст который будет обрезан до 80 символов и в конце будет много..."
```
### 9.3 Структура ответов по типам
**Успешная операция записи:**
```
ok|mode:add|tab:info|full_path:mcp/info|index:0|text_len:156|tags:2|note:True
```
**Успешное чтение (list):**
```
mode:list|tab:info|full_path:mcp/info|total:47|showing:0-19
0|"Текст..."|[tag1,tag2]|+note
1|"Текст..."|[]
```
**Ошибка:**
```
error|TAB_NOT_FOUND|Tab not found: nonexistent
```
**Preview операции:**
```
preview|mode:delete
tab:info|index:5
will_delete:
text:"Текст..."
tags:[tag1] +note
```
---
## 10. Коды ошибок
### 10.1 Полный список
| Код | Описание | Когда возникает |
|-----|----------|-----------------|
| `TAB_NOT_FOUND` | Вкладка не найдена | Указан несуществующий путь |
| `INDEX_OUT_OF_BOUNDS` | Индекс вне границ | index >= count или index < 0 |
| `INVALID_MODE` | Неверный режим | mode не из списка допустимых |
| `INVALID_PARAM` | Неверный параметр | Невалидное значение параметра |
| `PERMISSION_DENIED` | Доступ запрещён | tab_create/tab_delete не в workspace |
| `MISSING_PARAM` | Отсутствует параметр | Не передан обязательный параметр |
| `MATCH_NOT_FOUND` | Подстрока не найдена | edit_mode=substitute, но match не найден |
| `COPYQ_ERROR` | Ошибка CopyQ | Проблема с CopyQ CLI |
### 10.2 Формат ошибки
```
error|ERROR_CODE|Human-readable message
```
### 10.3 Примеры ошибок
```
error|TAB_NOT_FOUND|Tab not found: nonexistent
error|INDEX_OUT_OF_BOUNDS|Index 100 out of bounds (count: 47)
error|PERMISSION_DENIED|Operation 'tab_create' not allowed on 'info/subtab'
error|MISSING_PARAM|Parameter 'tab' required for mode 'list'
error|MATCH_NOT_FOUND|Match string not found: 'old text'
```
---
## 11. Паттерны использования
### 11.1 Первое знакомство с данными
```python
# 1. Посмотреть структуру mcp/*
mcp_read(mode="tree")
# 2. Посмотреть ВСЕ вкладки CopyQ
mcp_read(mode="tree", scope="all", max_depth=5)
```
### 11.2 Создание проекта в workspace
```python
# 1. Создать вкладку проекта
mcp_write(mode="tab_create", path="workspace/my-project")
# 2. Добавить описание проекта
mcp_write(
mode="add",
tab="workspace/my-project",
text="# Проект: My Project\n\nОписание проекта...",
tags=["project", "active"],
note="Создано: 2024-01-15"
)
# 3. Добавить задачи
mcp_write(
mode="add",
tab="workspace/my-project",
text="Реализовать фичу X",
tags=["task", "todo"]
)
```
### 11.3 Поиск и организация
```python
# 1. Найти все TODO
results = mcp_read(mode="search", query="TODO", scope="all")
# 2. Переместить найденное в workspace
mcp_write(mode="move", tab="info", index=2, to_tab="workspace/tasks")
# 3. Обновить статус
mcp_write(
mode="update", tab="workspace/tasks", index=0,
field="tags",
tags=["in-progress"],
edit_mode="append"
)
```
### 11.4 Работа с внешними данными
```python
# 1. Изучить внешнюю вкладку
mcp_read(mode="list", tab="архив", scope="external", max_items=10)
# 2. Прочитать интересный элемент полностью
mcp_read(mode="item", tab="архив", index=5, scope="external", include_note=True)
# 3. Скопировать в mcp/* (ручной процесс)
# Сначала прочитать данные, затем записать в mcp/*
item = mcp_read(mode="item", tab="архив", index=5, scope="external", include_note=True)
# Извлечь text, tags, note из ответа
mcp_write(mode="add", tab="info", text="...", tags=[...], note="...")
```
### 11.5 Preview перед опасными операциями
```python
# Всегда preview перед delete
preview = mcp_write(mode="delete", tab="info", index=0, intent="preview")
# Проверить что удаляется
# Затем выполнить
mcp_write(mode="delete", tab="info", index=0)
# Preview перед удалением вкладки
mcp_write(mode="tab_delete", path="workspace/old-project", intent="preview")
```
### 11.6 Пагинация больших списков
```python
# Первые 20 элементов
page1 = mcp_read(mode="list", tab="info", skip=0, max_items=20)
# Следующие 20
page2 = mcp_read(mode="list", tab="info", skip=20, max_items=20)
# И так далее
page3 = mcp_read(mode="list", tab="info", skip=40, max_items=20)
```
---
## 12. Ограничения и нюансы
### 12.1 Запись только в mcp/*
Запись возможна **ТОЛЬКО** в вкладки под `mcp/`:
- `mcp/info` ✅
- `mcp/заметки` ✅
- `mcp/workspace/*` ✅
- `&буфер обмена` ❌ (read-only)
- `архив` ❌ (read-only)
### 12.2 Создание подвкладок только в workspace
```python
mcp_write(mode="tab_create", path="workspace/new") # ✅ OK
mcp_write(mode="tab_create", path="info/sub") # ❌ PERMISSION_DENIED
mcp_write(mode="tab_create", path="заметки/sub") # ❌ PERMISSION_DENIED
```
### 12.3 Автосоздание вкладок
При `mode="add"` вкладка создаётся автоматически, если:
- Это подвкладка разрешённого корня (`info`, `заметки`, `workspace`)
- Вкладка ещё не существует
```python
# Создаст mcp/workspace/new-project если не существует
mcp_write(mode="add", tab="workspace/new-project", text="Первый элемент")
```
### 12.4 Сдвиг индексов
После `add` или `delete` индексы **сдвигаются**:
```python
# Было: [0]="A", [1]="B", [2]="C"
mcp_write(mode="delete", tab="info", index=1) # Удалили "B"
# Стало: [0]="A", [1]="C" ← индексы сдвинулись!
mcp_write(mode="add", tab="info", text="D")
# Стало: [0]="D", [1]="A", [2]="C" ← всё сдвинулось
```
### 12.5 Кодировка
- Все данные в UTF-8
- Кириллица полностью поддерживается
- Специальные символы (`|`, `\n`) в тексте сохраняются корректно
### 12.6 Лимиты
| Параметр | Минимум | Максимум | По умолчанию |
|----------|---------|----------|--------------|
| `max_items` | 1 | 100 | 20 |
| `max_depth` | 1 | 10 | 2 |
| `skip` | 0 | ∞ | 0 |
| Длина превью | - | 80 символов | - |
### 12.7 Регистронезависимый поиск
Поиск **всегда** регистронезависимый:
```python
mcp_read(mode="search", query="TODO") # Найдёт TODO, todo, Todo, tOdO
```
### 12.8 Уникальность меток
При `edit_mode="append"` для tags дубликаты **автоматически удаляются**:
```python
# Было: tags=["a", "b"]
mcp_write(mode="update", tab="info", index=0, field="tags", tags=["b", "c"], edit_mode="append")
# Стало: tags=["a", "b", "c"] ← "b" не дублируется
```
### 12.9 Пустые значения
- `tags=[]` — допустимо (элемент без меток)
- `note=""` — допустимо (пустая заметка)
- `text=""` — **недопустимо** при `mode="add"`
### 12.10 Специальные имена вкладок
Некоторые вкладки CopyQ имеют специальные имена:
- `&буфер обмена` — системный буфер (с &)
- Вкладки с `/` — иерархические
При чтении внешних вкладок используйте **точное имя**:
```python
tab="&буфер обмена" # Правильно
tab="буфер обмена" # Неправильно — не найдёт
```
---
## Приложение A: Быстрая справка по параметрам
### mcp_read
```
mode: "tree" | "list" | "item" | "search" [required]
scope: "mcp" | "all" | "external" [default: "mcp"]
tab: string [required for list/item]
index: int [required for item]
query: string [required for search]
search_in: "text" | "note" | "tags" | "all" [default: "all"]
max_depth: 1-10 [default: 2]
max_items: 1-100 [default: 20]
skip: 0+ [default: 0]
include_text: bool [default: true]
include_tags: bool [default: true]
include_note: bool [default: false]
```
### mcp_write
```
mode: "add" | "update" | "delete" | "move" | "tab_create" | "tab_delete" [required]
intent: "execute" | "preview" [default: "execute"]
tab: string [required for add/update/delete/move]
index: int [required for update/delete/move]
text: string [required for add, update field=text]
tags: array<string> [optional for add, required for update field=tags]
note: string [optional for add, required for update field=note]
field: "text" | "note" | "tags" [required for update]
edit_mode: "replace" | "append" | "prepend" | "substitute" | "remove" [default: "replace"]
match: string [required for edit_mode=substitute]
to_tab: string [required for move]
path: string [required for tab_create/tab_delete]
```
### mcp_validate
```
tool: "read" | "write" [required]
params: object [required]
```
---
## Приложение B: Примеры ответов
### Успешный tree (scope=all)
```
info [47]
0:|"Первый элемент текст..."|[important,task]|+note
1:|"Второй элемент..."|[archive]
workspace [3]
0:|"Проект Alpha описание..."|[project]
workspace/project1 [12]
0:|"Задача 1"|[task,todo]
заметки [5]
0:|"Заметка о встрече..."|[]|+note
&буфер обмена [8240] [external]
0:|"Скопированный текст..."|[]
архив [150] [external]
0:|"Старые данные..."|[2023]
```
### Успешный list
```
mode:list|tab:info|full_path:mcp/info|total:47|showing:0-19
0|"Первый элемент текст..."|[important,task]|+note
1|"Второй элемент..."|[archive]
2|"Третий элемент..."|[]
...
19|"Двадцатый элемент..."|[tag]
```
### Успешный item
```
mode:item|tab:info|full_path:mcp/info|index:0
text:Полный текст элемента без обрезки. Может быть очень длинным и содержать переносы строк.
Многострочный контент поддерживается.
tags:[important,task,deadline:2024-01]
note:Это заметка к элементу. Тоже может быть многострочной.
```
### Успешный search
```
mode:search|query:TODO|scope:all|results:5
info[2]|"TODO: сделать это"|[task,todo]|match:text,tags
workspace/project1[0]|"Реализовать TODO"|[feature]|match:text
&буфер обмена[15]|"TODO заметка"|[]|match:text|external
```
### Ошибки
```
error|TAB_NOT_FOUND|Tab not found: nonexistent_tab
error|INDEX_OUT_OF_BOUNDS|Index 100 out of bounds (count: 47)
error|PERMISSION_DENIED|Operation 'tab_create' not allowed on 'info'
error|MISSING_PARAM|Parameter 'query' required for mode 'search'
```