4.8 KiB
Проект: /root/WORK/memo (Kotlin/JVM). Заказ по MCP-серверу.
Создать: memo-mcp/build.gradle.kts (kotlin("jvm") + application + зависимости на :memo-core и kotlinx-serialization-json) memo-mcp/src/main/kotlin/memo/mcp/McpServer.kt memo-mcp/src/test/kotlin/memo/mcp/McpProtocolTest.kt
Зависимости модуля memo-mcp
plugins { kotlin("jvm") application; kotlin("plugin.serialization") version "2.4.10" } application { mainClass.set("memo.mcp.McpServerKt") } dependencies { implementation(project(":memo-core")) implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3") }
McpServer.kt — протокол
fun main(args: Array) — читает stdin построчно, отвечает в stdout ОДНОЙ строкой JSON-RPC 2.0 на запрос. НИЧЕГО кроме JSON-RPC в stdout не печатать (диагностика — только в stderr). Поддерживаемые методы:
initialize→ result: {"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"memo","version":"0.1.0"}}notifications/initialized→ уведомление, ответ не отправлятьtools/list→ result: {"tools":[ ... ]} с тремя инструментами:- memo_search: {"path":string,"query":string,"k":integer(по умолч. 8),"mode":string("hybrid"|"lex"|"vec")} обязательные: path, query
- memo_status: {"path":string} — обязательный: path
- memo_reindex: {"path":string} — обязательный: path
tools/callс params {"name":..., "arguments":{...}} → result: {"content":[{"type":"text","text":"<строка>"}],"isError":} Ошибка (нет обязательного аргумента, неизвестный инструмент, исключение) → result с "isError":true и текстом ошибки, а НЕ JSON-RPC error.- неизвестный метод → {"jsonrpc":"2.0","id":,"error":{"code":-32601,"message":"Method not found"}}
Реализацию инструментов вынести в функции, тестируемые без процесса: fun toolSearch(path: String, query: String, k: Int, mode: SearchMode): String fun toolStatus(path: String): String fun toolReindex(path: String): String fun handleRequest(line: String): String? // null для уведомлений
Поведение:
- Модель: MEMO_MODEL_DIR, иначе /root/WORK/memo/models/siglip2. Пути к БД — как в CLI (<коллекция>/.memo/index.db); определение коллекций: каталог с *.md на глубине до 2.
- toolSearch: поиск через Searcher с refresh-хуком (переиндексация перед поиском).
Текст ответа — человекочитаемый список:
<path>:<line> <heading>\n<text>\nдля каждого хита. Пустой результат → строка "ничего не найдено". - toolStatus: по коллекции —
файлов <N>, чанков <M>, индекс <ISO-дата>. - toolReindex: полная переиндексация: удалить каталог
<коллекция>/.memoи создать заново, затем indexTree. Вернутьпереиндексировано файлов: <N>. - memo_reindex через tools/call должен РАБОТАТЬ (не isError).
- Неизвестный инструмент → isError true с текстом "unknown tool: ".
McpProtocolTest.kt — ровно 5 тестов, имена ровно такие
initializeHandshake— handleRequest(строка JSON с initialize) → ответ содержит "2024-11-05" и "memo".toolsListHasThreeTools— ответ на tools/list содержит имена memo_search, memo_status, memo_reindex.unknownMethodReturns32601— ответ содержит "-32601".searchWithoutPathIsError— tools/call memo_search с пустыми arguments → в ответе "isError":true.notificationProducesNoResponse— handleRequest("{"jsonrpc":"2.0","method":"notifications/initialized"}") == null.
После: ./gradlew :memo-mcp:test --rerun-tasks — зелёные; ./gradlew :memo-mcp:installDist — собирается; бинарь: memo-mcp/build/install/memo-mcp/bin/memo-mcp Коммит: git add -A && git commit -m "mcp: сервер memo_search/memo_status/memo_reindex"
СТРОГИЕ ЗАПРЕТЫ:
- Не выводить план текстом; сразу создавай файлы.
- Не трогать memo-core, memo-cli, memo-watch.
- Ничего не печатать в stdout, кроме строк JSON-RPC.