droid-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +124 -0
- package/EXAMPLES.md +471 -0
- package/LICENSE +21 -0
- package/README.md +354 -0
- package/dist/adb.d.ts +110 -0
- package/dist/adb.d.ts.map +1 -0
- package/dist/adb.js +579 -0
- package/dist/adb.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +366 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +54 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +34 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -0
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Проект
|
|
6
|
+
|
|
7
|
+
Droid MCP — это минимальный MCP (Model Context Protocol) сервер для взаимодействия с Android устройствами через ADB. Сервер позволяет AI-ассистентам получать логи logcat, захватывать логи в реальном времени и получать иерархию View из Android приложений.
|
|
8
|
+
|
|
9
|
+
## Технологический стек
|
|
10
|
+
|
|
11
|
+
- Node.js 18+ с ES2022 модулями
|
|
12
|
+
- TypeScript 5+ со строгой типизацией
|
|
13
|
+
- Официальный `@modelcontextprotocol/sdk` v1.24.3 для MCP протокола
|
|
14
|
+
- Zod v4 для валидации параметров инструментов
|
|
15
|
+
- Cross-platform поддержка (Windows, Linux, macOS)
|
|
16
|
+
|
|
17
|
+
## Команды для разработки
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install # Установка зависимостей
|
|
21
|
+
npm run build # Компиляция TypeScript в dist/
|
|
22
|
+
npm start # Запуск скомпилированного сервера
|
|
23
|
+
npm test # Сборка и запуск интеграционных тестов
|
|
24
|
+
npm run test:old # Запуск устаревшего набора тестов
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Отладка
|
|
28
|
+
|
|
29
|
+
Режим отладки включается через переменную окружения:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Windows PowerShell
|
|
33
|
+
$env:DROID_MCP_DEBUG="true"; npm start
|
|
34
|
+
|
|
35
|
+
# Linux/Mac
|
|
36
|
+
DROID_MCP_DEBUG=true npm start
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Также можно использовать VS Code debugger с конфигурацией из `.vscode/launch.json`.
|
|
40
|
+
|
|
41
|
+
## Архитектура
|
|
42
|
+
|
|
43
|
+
### Структура исходного кода
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
src/
|
|
47
|
+
├── index.ts # MCP сервер: регистрация инструментов, обработка запросов
|
|
48
|
+
├── adb.ts # ADB абстракция: выполнение команд, работа с процессами
|
|
49
|
+
└── types.ts # Zod схемы для валидации параметров инструментов
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Слой MCP сервера (`src/index.ts`)
|
|
53
|
+
|
|
54
|
+
Основной файл, который:
|
|
55
|
+
- Создаёт MCP сервер через `@modelcontextprotocol/sdk`
|
|
56
|
+
- Регистрирует инструменты через `server.registerTool()`
|
|
57
|
+
- Обрабатывает переменную окружения `ANDROID_APP_IDS` для глобальной фильтрации по PID
|
|
58
|
+
- Предоставляет debug-логирование через `debugLog()`
|
|
59
|
+
|
|
60
|
+
### Слой ADB абстракции (`src/adb.ts`)
|
|
61
|
+
|
|
62
|
+
Содержит всю логику взаимодействия с ADB:
|
|
63
|
+
- `execAdb()` — выполнение ADB команд с промисами
|
|
64
|
+
- `captureLogcatUntil()` — захват логов в реальном времени с остановкой по паттерну
|
|
65
|
+
- `getPidForPackage()` / `getPidsForPackages()` — получение PID процессов по package ID
|
|
66
|
+
- `listThirdPartyPackages()` — список установленных сторонних приложений
|
|
67
|
+
- `scanGradleForPackageId()` — поиск applicationId в build.gradle файлах
|
|
68
|
+
|
|
69
|
+
Кастомный класс `AdbError` расширяет Error и содержит `code` и `stderr`.
|
|
70
|
+
|
|
71
|
+
### Слой типизации (`src/types.ts`)
|
|
72
|
+
|
|
73
|
+
Zod схемы для валидации параметров всех инструментов:
|
|
74
|
+
- `GetLogcatSchema` — параметры для `get_logcat`
|
|
75
|
+
- `CaptureSessionSchema` — параметры для `capture_session`
|
|
76
|
+
- `InspectAppSchema` — параметры для `inspect_app_identity` (пустой объект)
|
|
77
|
+
|
|
78
|
+
Типы параметров inference'ся из схем через `z.infer<>`.
|
|
79
|
+
|
|
80
|
+
## Доступные MCP инструменты
|
|
81
|
+
|
|
82
|
+
### `get_logcat`
|
|
83
|
+
Получает историю логов logcat. Поддерживает фильтрацию по tag и количеству строк. Автоматически фильтрует по PID если установлена `ANDROID_APP_IDS`.
|
|
84
|
+
|
|
85
|
+
### `capture_session`
|
|
86
|
+
Захватывает логи в реальном времени до появления стоп-паттерна (regex) или истечения таймаута. Поддерживает фильтрацию по tag, priority, buffer и PID.
|
|
87
|
+
|
|
88
|
+
### `inspect_app_identity`
|
|
89
|
+
Сканирует проект и устройство для определения package ID. Ищет applicationId в build.gradle и показывает установленные приложения.
|
|
90
|
+
|
|
91
|
+
## Глобальная фильтрация по Package ID
|
|
92
|
+
|
|
93
|
+
Переменная окружения `ANDROID_APP_IDS` содержит список package ID через запятую или пробел:
|
|
94
|
+
```bash
|
|
95
|
+
export ANDROID_APP_IDS="com.example.app1,com.example.app2"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Когда установлена, все инструменты автоматически фильтруют логи по PID указанных приложений. Это значительно уменьшает объём данных, получаемых LLM.
|
|
99
|
+
|
|
100
|
+
## Конвенции и паттерны
|
|
101
|
+
|
|
102
|
+
1. **Debug-логирование**: Используйте `debugLog(message, data)` для отладочного вывода в stderr. Включается через `DROID_MCP_DEBUG`.
|
|
103
|
+
|
|
104
|
+
2. **Обработка ошибок**: Все ADB ошибки должны быть типа `AdbError` с полями `code` и `stderr`. В工具 handlers оборачивайте ошибки и пробрасывайте с описательным сообщением.
|
|
105
|
+
|
|
106
|
+
3. **Валидация**: Параметры всех инструментов валидируются через Zod схемы. Добавляйте новые схемы в `types.ts`.
|
|
107
|
+
|
|
108
|
+
4. **PID-фильтрация**: При работе с логами всегда применяйте глобальную фильтрацию через `getPidsForPackages(globalPackageIds)`.
|
|
109
|
+
|
|
110
|
+
5. **Process management**: В `captureLogcatUntil` используется `spawn()` для реального времени. Не забывайте про cleanup и timeout.
|
|
111
|
+
|
|
112
|
+
6. **Таймауты**: Устанавливайте разумные лимиты для всех операций с ADB (logcat capture, view hierarchy dump).
|
|
113
|
+
|
|
114
|
+
## Тестирование
|
|
115
|
+
|
|
116
|
+
Тесты находятся в `tests/integration.test.js` и используют официальный MCP Client SDK. Тесты:
|
|
117
|
+
- Не требуют подключенного Android устройства
|
|
118
|
+
- Проверяют MCP протокол и валидацию параметров
|
|
119
|
+
- Обрабатывают отсутствие ADB gracefully
|
|
120
|
+
|
|
121
|
+
Для добавления нового инструмента:
|
|
122
|
+
1. Добавьте Zod схему в `src/types.ts`
|
|
123
|
+
2. Зарегистрируйте инструмент в `src/index.ts` через `server.registerTool()`
|
|
124
|
+
3. Добавьте тесты в `tests/integration.test.js`
|
package/EXAMPLES.md
ADDED
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
# Примеры использования droid-mcp
|
|
2
|
+
|
|
3
|
+
Этот документ содержит практические примеры использования инструментов `get_logcat` и `capture_session` для отладки Android приложений через Cursor/Windsurf.
|
|
4
|
+
|
|
5
|
+
## Содержание
|
|
6
|
+
|
|
7
|
+
- [Настройка MCP сервера в Cursor](#настройка-mcp-сервера-в-cursor)
|
|
8
|
+
- [Сценарий 1: Отладка краша при авторизации](#сценарий-1-отладка-краша-при-авторизации)
|
|
9
|
+
- [Сценарий 2: Отслеживание успешного сценария](#сценарий-2-отслеживание-успешного-сценария)
|
|
10
|
+
- [Сценарий 3: Поиск проблемы с производительностью](#сценарий-3-поиск-проблемы-с-производительностью)
|
|
11
|
+
- [Сценарий 4: Универсальный отладчик](#сценарий-4-универсальный-отладчик)
|
|
12
|
+
- [Сценарий 5: Анализ сетевых запросов](#сценарий-5-анализ-сетевых-запросов)
|
|
13
|
+
- [Сценарий 6: Отладка ANR (Application Not Responding)](#сценарий-6-отладка-anr-application-not-responding)
|
|
14
|
+
- [Сценарий 7: Инспекция иерархии View](#сценарий-7-инспекция-иерархии-view)
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Настройка MCP сервера в Cursor
|
|
19
|
+
|
|
20
|
+
### Шаг 1: Сборка проекта
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
cd e:\droid-mcp
|
|
24
|
+
npm install
|
|
25
|
+
npm run build
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Шаг 2: Добавление в конфигурацию Cursor
|
|
29
|
+
|
|
30
|
+
Найдите файл конфигурации MCP в Cursor (обычно `~/.cursor/mcp.json` или через настройки Cursor) и добавьте:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"mcpServers": {
|
|
35
|
+
"droid-mcp": {
|
|
36
|
+
"command": "node",
|
|
37
|
+
"args": ["E:/droid-mcp/dist/index.js"],
|
|
38
|
+
"env": {}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Важно:** Замените путь `E:/droid-mcp/dist/index.js` на абсолютный путь к вашему проекту.
|
|
45
|
+
|
|
46
|
+
### Шаг 3: Перезапуск Cursor
|
|
47
|
+
|
|
48
|
+
Перезапустите Cursor, чтобы подхватить новый MCP сервер.
|
|
49
|
+
|
|
50
|
+
### Шаг 4: Проверка подключения
|
|
51
|
+
|
|
52
|
+
В Cursor должны быть доступны инструменты:
|
|
53
|
+
- `get_logcat` - получение истории логов
|
|
54
|
+
- `capture_session` - запись логов в реальном времени
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Сценарий 1: Отладка краша при авторизации
|
|
59
|
+
|
|
60
|
+
**Проблема:** Приложение падает при попытке входа пользователя.
|
|
61
|
+
|
|
62
|
+
**Промпт для Cursor:**
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
Я хочу отладить проблему с крашем приложения при авторизации.
|
|
66
|
+
|
|
67
|
+
Используй инструмент capture_session из droid-mcp для записи логов в реальном времени.
|
|
68
|
+
|
|
69
|
+
Параметры:
|
|
70
|
+
- Очисти буфер перед началом (clear_buffer: true), чтобы получить чистую сессию
|
|
71
|
+
- Фильтруй логи по tag моего приложения (замени "MyApp" на реальный tag, если знаешь)
|
|
72
|
+
- Остановись при появлении "FATAL", "Exception", "AndroidRuntime" или "crash"
|
|
73
|
+
- Таймаут: 60 секунд
|
|
74
|
+
- Приоритет: только ошибки и выше (priority: "E")
|
|
75
|
+
|
|
76
|
+
После того как я скажу "готово", я воспроизведу проблему на устройстве - попытаюсь войти в приложение. Как только увидишь краш в логах, проанализируй стек трейс и предложи решение.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Что происходит:**
|
|
80
|
+
1. Cursor запускает `capture_session` с указанными параметрами
|
|
81
|
+
2. Вы воспроизводите проблему на устройстве (пытаетесь войти)
|
|
82
|
+
3. При появлении краша запись останавливается
|
|
83
|
+
4. Cursor анализирует логи и предлагает решение
|
|
84
|
+
|
|
85
|
+
**Пример результата:**
|
|
86
|
+
```
|
|
87
|
+
[Анализ логов]
|
|
88
|
+
Найдена ошибка в строке 42 файла LoginActivity.kt:
|
|
89
|
+
NullPointerException при обращении к userRepository
|
|
90
|
+
|
|
91
|
+
Рекомендация: Добавить проверку на null перед вызовом userRepository.getUser()
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Сценарий 2: Отслеживание успешного сценария
|
|
97
|
+
|
|
98
|
+
**Задача:** Проверить, что определенный флоу работает корректно и зафиксировать все логи этого процесса.
|
|
99
|
+
|
|
100
|
+
**Промпт для Cursor:**
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
Мне нужно протестировать сценарий "добавление товара в корзину".
|
|
104
|
+
|
|
105
|
+
Используй capture_session для записи логов этого процесса:
|
|
106
|
+
- Очисти буфер (clear_buffer: true)
|
|
107
|
+
- Фильтруй по tag "MyApp" (или другому, если знаешь)
|
|
108
|
+
- Остановись при появлении "CHECKOUT_COMPLETE" или "SCENARIO_FINISHED" (я добавлю этот лог в код)
|
|
109
|
+
- Таймаут: 120 секунд
|
|
110
|
+
- Приоритет: все логи (не фильтровать по priority)
|
|
111
|
+
|
|
112
|
+
Я скажу "начали", когда буду готов. После завершения сценария я добавлю в код Log.i("MyApp", "SCENARIO_FINISHED"), и запись остановится. Затем проанализируй логи и скажи, есть ли проблемы или всё работает корректно.
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Подготовка кода:**
|
|
116
|
+
|
|
117
|
+
Перед началом добавьте в код точку завершения:
|
|
118
|
+
|
|
119
|
+
```kotlin
|
|
120
|
+
// В конце успешного выполнения сценария
|
|
121
|
+
Log.i("MyApp", "SCENARIO_FINISHED")
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Что происходит:**
|
|
125
|
+
1. Cursor начинает запись логов
|
|
126
|
+
2. Вы выполняете сценарий (добавляете товар в корзину)
|
|
127
|
+
3. При появлении лога "SCENARIO_FINISHED" запись останавливается
|
|
128
|
+
4. Cursor анализирует весь флоу и сообщает о проблемах
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Сценарий 3: Поиск проблемы с производительностью
|
|
133
|
+
|
|
134
|
+
**Проблема:** Приложение тормозит при открытии галереи изображений.
|
|
135
|
+
|
|
136
|
+
**Промпт для Cursor:**
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
Приложение тормозит при открытии галереи изображений. Нужно найти причину.
|
|
140
|
+
|
|
141
|
+
Используй capture_session:
|
|
142
|
+
- Очисти буфер (clear_buffer: true)
|
|
143
|
+
- Фильтруй по tag "MyApp" и "ImageLoader" (если есть)
|
|
144
|
+
- Остановись при появлении "GALLERY_LOADED" или таймауте 90 секунд
|
|
145
|
+
- Приоритет: все логи (verbose и выше)
|
|
146
|
+
|
|
147
|
+
Я скажу "старт", открою галерею, и когда она загрузится, добавлю лог "GALLERY_LOADED". Проанализируй логи на предмет:
|
|
148
|
+
1. Медленных операций (большие задержки между логами)
|
|
149
|
+
2. Повторяющихся операций (возможные утечки или неоптимальные циклы)
|
|
150
|
+
3. Ошибок или предупреждений
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Подготовка кода:**
|
|
154
|
+
|
|
155
|
+
```kotlin
|
|
156
|
+
// В методе, который вызывается после загрузки галереи
|
|
157
|
+
Log.d("MyApp", "GALLERY_LOADED")
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Что происходит:**
|
|
161
|
+
1. Cursor записывает все логи процесса загрузки
|
|
162
|
+
2. Вы открываете галерею
|
|
163
|
+
3. При появлении "GALLERY_LOADED" запись останавливается
|
|
164
|
+
4. Cursor анализирует временные метки и находит узкие места
|
|
165
|
+
|
|
166
|
+
**Пример результата:**
|
|
167
|
+
```
|
|
168
|
+
[Анализ производительности]
|
|
169
|
+
Найдена проблема: между логами "Loading images" и "Images loaded" прошло 3.2 секунды.
|
|
170
|
+
|
|
171
|
+
Анализ показал:
|
|
172
|
+
- 500+ запросов к базе данных в цикле (должно быть батчинг)
|
|
173
|
+
- Отсутствие кеширования изображений
|
|
174
|
+
- Синхронная загрузка вместо асинхронной
|
|
175
|
+
|
|
176
|
+
Рекомендации:
|
|
177
|
+
1. Использовать batch запросы к БД
|
|
178
|
+
2. Добавить кеш для изображений
|
|
179
|
+
3. Перевести загрузку на корутины
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Сценарий 4: Универсальный отладчик
|
|
185
|
+
|
|
186
|
+
**Задача:** Быстрое тестирование любого сценария без специфических настроек.
|
|
187
|
+
|
|
188
|
+
**Промпт для Cursor:**
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
Я хочу записать сессию logcat для отладки. Используй capture_session со следующими параметрами:
|
|
192
|
+
|
|
193
|
+
- stop_pattern: "DEBUG_SESSION_END" (я добавлю этот лог в код когда закончу)
|
|
194
|
+
- timeout_seconds: 180
|
|
195
|
+
- clear_buffer: true
|
|
196
|
+
- priority: "D" (debug и выше, чтобы видеть достаточно информации)
|
|
197
|
+
|
|
198
|
+
Я скажу "запись начата", когда буду готов воспроизвести проблему. После того как закончу, добавлю Log.d("MyApp", "DEBUG_SESSION_END") в код, и запись остановится. Затем проанализируй логи и помоги найти проблему.
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Подготовка кода:**
|
|
202
|
+
|
|
203
|
+
```kotlin
|
|
204
|
+
// В любом месте кода, когда закончите тестирование
|
|
205
|
+
Log.d("MyApp", "DEBUG_SESSION_END")
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Преимущества:**
|
|
209
|
+
- Универсальный подход для любой задачи
|
|
210
|
+
- Гибкий таймаут (3 минуты)
|
|
211
|
+
- Достаточно детальные логи (debug уровень)
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Сценарий 5: Анализ сетевых запросов
|
|
216
|
+
|
|
217
|
+
**Проблема:** Нужно отследить все сетевые запросы и ответы при определенном действии.
|
|
218
|
+
|
|
219
|
+
**Промпт для Cursor:**
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
Мне нужно проанализировать сетевые запросы при синхронизации данных.
|
|
223
|
+
|
|
224
|
+
Используй capture_session:
|
|
225
|
+
- clear_buffer: true
|
|
226
|
+
- tag: "OkHttp" или "Retrofit" (в зависимости от библиотеки)
|
|
227
|
+
- stop_pattern: "SYNC_COMPLETE"
|
|
228
|
+
- timeout_seconds: 120
|
|
229
|
+
- priority: "I" (info и выше)
|
|
230
|
+
|
|
231
|
+
Я скажу "начали синхронизацию", запущу синхронизацию в приложении, и когда она завершится, добавлю лог "SYNC_COMPLETE". Проанализируй все HTTP запросы, ответы, ошибки и тайминги.
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**Подготовка кода:**
|
|
235
|
+
|
|
236
|
+
```kotlin
|
|
237
|
+
// После завершения синхронизации
|
|
238
|
+
Log.i("MyApp", "SYNC_COMPLETE")
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Что происходит:**
|
|
242
|
+
1. Cursor записывает все сетевые логи
|
|
243
|
+
2. Вы запускаете синхронизацию
|
|
244
|
+
3. При завершении запись останавливается
|
|
245
|
+
4. Cursor анализирует запросы и находит проблемы
|
|
246
|
+
|
|
247
|
+
**Пример результата:**
|
|
248
|
+
```
|
|
249
|
+
[Анализ сетевых запросов]
|
|
250
|
+
Найдено 15 HTTP запросов за 8 секунд.
|
|
251
|
+
|
|
252
|
+
Проблемы:
|
|
253
|
+
- 3 запроса возвращают 500 ошибку (серверная проблема)
|
|
254
|
+
- 2 запроса занимают >2 секунды (медленный ответ)
|
|
255
|
+
- Повторяющиеся запросы к одному endpoint (отсутствие кеширования)
|
|
256
|
+
|
|
257
|
+
Рекомендации:
|
|
258
|
+
1. Добавить retry логику для 500 ошибок
|
|
259
|
+
2. Увеличить таймауты или оптимизировать запросы
|
|
260
|
+
3. Реализовать кеширование для повторяющихся запросов
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Сценарий 6: Отладка ANR (Application Not Responding)
|
|
266
|
+
|
|
267
|
+
**Проблема:** Приложение зависает и показывает "Приложение не отвечает".
|
|
268
|
+
|
|
269
|
+
**Промпт для Cursor:**
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
Приложение зависает при выполнении определенного действия. Нужно найти причину ANR.
|
|
273
|
+
|
|
274
|
+
Используй capture_session:
|
|
275
|
+
- clear_buffer: true
|
|
276
|
+
- buffer: "events" (буфер событий системы)
|
|
277
|
+
- stop_pattern: "ANR|Application Not Responding|FATAL"
|
|
278
|
+
- timeout_seconds: 60
|
|
279
|
+
- priority: "E" (только ошибки)
|
|
280
|
+
|
|
281
|
+
Я скажу "начали", воспроизведу проблему, и когда появится ANR, запись остановится. Проанализируй логи и найди, какой процесс блокирует главный поток.
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
**Что происходит:**
|
|
285
|
+
1. Cursor записывает системные события
|
|
286
|
+
2. Вы воспроизводите проблему
|
|
287
|
+
3. При появлении ANR запись останавливается
|
|
288
|
+
4. Cursor анализирует системные логи и находит блокирующий процесс
|
|
289
|
+
|
|
290
|
+
**Пример результата:**
|
|
291
|
+
```
|
|
292
|
+
[Анализ ANR]
|
|
293
|
+
Найдена причина: главный поток заблокирован операцией чтения из базы данных.
|
|
294
|
+
|
|
295
|
+
Детали:
|
|
296
|
+
- Операция выполняется синхронно на главном потоке
|
|
297
|
+
- Запрос к БД занимает 8+ секунд
|
|
298
|
+
- Блокировка происходит в методе UserRepository.getUser()
|
|
299
|
+
|
|
300
|
+
Рекомендация: Перевести операцию на фоновый поток (coroutine или AsyncTask)
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## Сценарий 7: Инспекция иерархии View
|
|
306
|
+
|
|
307
|
+
**Задача:** Получить полную структуру UI компонентов для анализа layout или поиска проблем с отображением.
|
|
308
|
+
|
|
309
|
+
**Промпт для Cursor:**
|
|
310
|
+
|
|
311
|
+
```
|
|
312
|
+
Мне нужно получить иерархию View текущего экрана приложения. Используй инструмент get_view_hierarchy из droid-mcp.
|
|
313
|
+
|
|
314
|
+
Параметры:
|
|
315
|
+
- package_id: "com.example.app" (или используй автоопределение)
|
|
316
|
+
- timeout_ms: 5000
|
|
317
|
+
|
|
318
|
+
После получения JSON проанализируй структуру и скажи:
|
|
319
|
+
1. Какие основные компоненты есть на экране
|
|
320
|
+
2. Есть ли вложенные ViewGroup, которые можно оптимизировать
|
|
321
|
+
3. Какие View имеют одинаковые ID (если есть)
|
|
322
|
+
4. Предложи улучшения структуры, если видишь проблемы
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Что происходит:**
|
|
326
|
+
1. Cursor вызывает `get_view_hierarchy` и получает JSON с полной иерархией View
|
|
327
|
+
2. Анализирует структуру и предоставляет рекомендации
|
|
328
|
+
|
|
329
|
+
**Пример результата:**
|
|
330
|
+
```
|
|
331
|
+
[Анализ иерархии View]
|
|
332
|
+
Найдено 45 View элементов на экране.
|
|
333
|
+
|
|
334
|
+
Структура:
|
|
335
|
+
- Root: FrameLayout
|
|
336
|
+
- LinearLayout (main_container)
|
|
337
|
+
- RecyclerView (list_items) - 20 элементов
|
|
338
|
+
- Button (action_button)
|
|
339
|
+
- FloatingActionButton
|
|
340
|
+
|
|
341
|
+
Проблемы:
|
|
342
|
+
- Глубокая вложенность: 6 уровней (можно оптимизировать до 4)
|
|
343
|
+
- Дублирование ID: "item_view" используется 20 раз (нормально для RecyclerView)
|
|
344
|
+
|
|
345
|
+
Рекомендации:
|
|
346
|
+
1. Рассмотреть ConstraintLayout вместо вложенных LinearLayout
|
|
347
|
+
2. Проверить производительность RecyclerView (возможно нужен ViewPool)
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Получить иерархию конкретного View
|
|
351
|
+
|
|
352
|
+
**Промпт:**
|
|
353
|
+
```
|
|
354
|
+
Получи иерархию только для View с ID "com.example:id/main_container" используя get_view_hierarchy.
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**Пример:**
|
|
358
|
+
```json
|
|
359
|
+
{
|
|
360
|
+
"name": "get_view_hierarchy",
|
|
361
|
+
"arguments": {
|
|
362
|
+
"view_id": "com.example:id/main_container"
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### Получить иерархию конкретного Fragment
|
|
368
|
+
|
|
369
|
+
**Промпт:**
|
|
370
|
+
```
|
|
371
|
+
Получи иерархию View для Fragment "ProductDetailFragment" используя get_view_hierarchy.
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
**Пример:**
|
|
375
|
+
```json
|
|
376
|
+
{
|
|
377
|
+
"name": "get_view_hierarchy",
|
|
378
|
+
"arguments": {
|
|
379
|
+
"fragment_class": "ProductDetailFragment"
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
**Примечание:** Для работы `get_view_hierarchy` необходимо реализовать BroadcastReceiver в вашем Android приложении. См. пример в `docs/android_view_dump_receiver_example.kt`.
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## Быстрые команды для get_logcat
|
|
389
|
+
|
|
390
|
+
### Получить последние ошибки
|
|
391
|
+
|
|
392
|
+
**Промпт:**
|
|
393
|
+
```
|
|
394
|
+
Получи последние 500 строк логов с приоритетом Error и выше, используя get_logcat.
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### Получить логи конкретного тега
|
|
398
|
+
|
|
399
|
+
**Промпт:**
|
|
400
|
+
```
|
|
401
|
+
Получи последние 1000 строк логов с тегом "MyApp" используя get_logcat.
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Получить логи за последние минуты
|
|
405
|
+
|
|
406
|
+
**Промпт:**
|
|
407
|
+
```
|
|
408
|
+
Получи максимальное количество логов (2000 строк) используя get_logcat, чтобы увидеть что происходило в последнее время.
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
## Советы и рекомендации
|
|
414
|
+
|
|
415
|
+
### Перед началом сессии
|
|
416
|
+
|
|
417
|
+
1. **Проверьте подключение устройства:**
|
|
418
|
+
```bash
|
|
419
|
+
adb devices
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
2. **Узнайте tag вашего приложения:**
|
|
423
|
+
- Посмотрите в `AndroidManifest.xml`
|
|
424
|
+
- Или используйте `get_logcat` без фильтров и найдите свой tag
|
|
425
|
+
|
|
426
|
+
3. **Очистите старые логи (опционально):**
|
|
427
|
+
```bash
|
|
428
|
+
adb logcat -c
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Во время сессии
|
|
432
|
+
|
|
433
|
+
1. **Не закрывайте Cursor** во время записи
|
|
434
|
+
2. **Добавьте стоп-слово в код** заранее, если используете кастомное
|
|
435
|
+
3. **Следите за таймаутом** - если сессия долгая, увеличьте `timeout_seconds`
|
|
436
|
+
|
|
437
|
+
### После получения логов
|
|
438
|
+
|
|
439
|
+
1. **Задавайте уточняющие вопросы** о конкретных строках
|
|
440
|
+
2. **Просите объяснить стек трейсы** если видите ошибки
|
|
441
|
+
3. **Спрашивайте рекомендации** по оптимизации
|
|
442
|
+
|
|
443
|
+
### Оптимизация производительности
|
|
444
|
+
|
|
445
|
+
- Используйте фильтры (`tag`, `priority`) чтобы уменьшить объем логов
|
|
446
|
+
- Очищайте буфер (`clear_buffer: true`) для "чистых" сессий
|
|
447
|
+
- Выбирайте правильный буфер (`buffer`) в зависимости от задачи:
|
|
448
|
+
- `main` - логи приложений
|
|
449
|
+
- `system` - системные логи
|
|
450
|
+
- `crash` - краши
|
|
451
|
+
- `events` - системные события (для ANR)
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## Часто задаваемые вопросы
|
|
456
|
+
|
|
457
|
+
**Q: Как узнать tag моего приложения?**
|
|
458
|
+
A: Используйте `get_logcat` без фильтров, запустите приложение и найдите строки с вашим package name или классом.
|
|
459
|
+
|
|
460
|
+
**Q: Что делать если запись не останавливается?**
|
|
461
|
+
A: Проверьте, что стоп-слово действительно появляется в логах. Можно использовать более общий паттерн или увеличить таймаут.
|
|
462
|
+
|
|
463
|
+
**Q: Можно ли использовать несколько стоп-слов?**
|
|
464
|
+
A: Да, используйте regex: `"FATAL|Exception|ERROR"` - запись остановится при появлении любого из них.
|
|
465
|
+
|
|
466
|
+
**Q: Как записать логи из конкретного буфера?**
|
|
467
|
+
A: Используйте параметр `buffer`: `"crash"` для крашей, `"events"` для системных событий, `"radio"` для сетевых логов.
|
|
468
|
+
|
|
469
|
+
**Q: Что делать если логи слишком большие?**
|
|
470
|
+
A: Используйте фильтры (`tag`, `priority`) или уменьшите таймаут. Также можно использовать `get_logcat` с ограничением по строкам для предварительного анализа.
|
|
471
|
+
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 droid-mcp contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|