Skip to main content
Glama
lrvchgost

simple-mcp-example

by lrvchgost

simple-mcp-example

MCP-сервер для работы с заметками. Позволяет создавать, просматривать и искать заметки, которые хранятся в локальных .md-файлах. Построен на @modelcontextprotocol/sdk и работает через транспорт stdio.

Описание сервера

Сервер управляет заметками, сохранёнными в виде Markdown-файлов в папке notes. Папка создаётся автоматически в текущем каталоге запуска (cwd). Каждая заметка — это отдельный .md-файл.

Структура заметки (каждая строка отдельно):

Автор: <$USER>
Дата: dd.mm.yyyy HH:mm

<текст заметки>
  • Автор — берётся из переменной окружения $USER.

  • Дата — дата и время создания.

  • Текст — произвольное содержимое заметки.

Все пути к файлам защищены от path traversal (../, абсолютные пути).

Related MCP server: mcp-lab-01-notes-server

Структура кода

Сервер поднимается и инструменты регистрируются в файле src/index.ts:10–28:

  • создание экземпляра McpServer и инициализация логгера;

  • регистрация всех тулов (add_note, get_all_notes, view_note_content, search_notes, search_in_files);

  • запуск транспорта stdio в функции main().

Реализация каждого тула лежит в отдельной папке src/tools/<name>/index.ts.

Логирование (debug)

Логи во все тулы добавляются через логгер из src/lib/logger.ts:17–25 (createMcpLogger, вызывает server.sendLoggingMessage). В логах MCP-клиента записи отображаются как message="MCP server log".

add_note

  • Файл и реализация: src/tools/add_note/index.ts (обработчик addNoteHandler — строки 13–19; регистрация — 21–39).

  • Логирование: строки 29 (add_note: start), 32 (add_note: success), 35 (add_note: error).

  • Пример вывода:

    ... level=INFO ... message="MCP server log" ... data.message="add_note: start" data.note_name=встреча

get_all_notes

  • Файл и реализация: src/tools/get_all_notes/index.ts (обработчик getAllNotesHandler — строки 5–12; регистрация — 14–32).

  • Логирование: строки 22 (get_all_notes: start), 25 (get_all_notes: success), 28 (get_all_notes: error).

  • Пример вывода:

    ... level=INFO ... message="MCP server log" ... data.message="get_all_notes: start"

view_note_content

  • Файл и реализация: src/tools/view_note_content/index.ts (обработчик viewNoteContentHandler — строки 12–18; регистрация — 20–38).

  • Логирование: строки 28 (view_note_content: start), 31 (view_note_content: success), 34 (view_note_content: error).

  • Пример вывода:

    ... level=INFO ... message="MCP server log" ... data.message="view_note_content: start" data.note_name=встреча

search_notes

  • Файл и реализация: src/tools/search_notes/index.ts (обработчик searchNotesHandler — строки 12–20; регистрация — 22–40).

  • Логирование: строки 30 (search_notes: start), 33 (search_notes: success), 36 (search_notes: error).

  • Пример вывода:

    ... level=INFO ... message="MCP server log" ... data.message="search_notes: start" data.pattern=встре

search_in_files

  • Файл и реализация: src/tools/search_in_files/index.ts (обработчик searchInFilesHandler — строки 63–86; регистрация — 88–107).

  • Логирование: строки 97 (search_in_files: start), 100 (search_in_files: success), 103 (search_in_files: error).

  • Пример вывода:

    timestamp=2026-09-06T12:56:31.417Z level=INFO run=a5cd661a message="MCP server log" server=my-simple-notes level=info data.message="search_in_files: start" data.pattern=хлеб

Контракт результата

Формат вывода каждого тула зафиксирован в этом же README.md в разделе «## Тулы», в блоке «Пример результата»:

  • Формат файла заметки (структура .md) — раздел «## Описание сервера» → «Структура заметки» (README.md:9–16).

  • Формат вывода view_note_content — раздел «## Тулы» → «### view_note_content» → «Пример результата» (README.md:128–134).

  • Формат вывода search_in_files — раздел «## Тулы» → «### search_in_files» → «Пример результата» (README.md:164–171).

Строгие требования к формату (без сокращений и перефразирования) дополнительно зафиксированы в AGENTS.md.

Тулы

Тулами являются вспомогательные функции для управления заметками

add_note

Создаёт новую заметку (или перезаписывает существующую).

Параметры:

  • note_name (строка, required) — имя файла заметки; расширение .md добавляется автоматически.

  • text (строка, required) — текст заметки. Можно передать явно или попросить модель сделать саммари/выжимку.

Пример вызова:

{
  "name": "add_note",
  "arguments": {
    "note_name": "встреча",
    "text": "Обсудили план на неделю и договорились о демо в пятницу."
  }
}

Результат: создаётся файл notes/встреча.md.

get_all_notes

Возвращает список имён всех заметок, отсортированных по дате (mtime файла) от старых к новым.

Параметры: нет.

Пример вызова:

{ "name": "get_all_notes" }

Пример результата:

встреча.md
идеи.md
рецепт.md

view_note_content

Возвращает полный текст заметки.

Параметры:

  • note_name (строка, required) — имя заметки.

Пример вызова:

{
  "name": "view_note_content",
  "arguments": { "note_name": "встреча" }
}

Пример результата:

Автор: roman
Дата: 06.09.2026 14:30

Обсудили план на неделю и договорились о демо в пятницу.

search_notes

Ищет заметки по имени файла. Поиск регистронезависимый.

Параметры:

  • pattern (строка, required) — паттерн для поиска в названиях файлов.

Пример вызова:

{
  "name": "search_notes",
  "arguments": { "pattern": "встре" }
}

Пример результата: встреча.md

search_in_files

Ищет паттерн в содержимом файлов. Поиск регистронезависимый. Для каждого совпадения выводит автора, дату и найденную строку с контекстом ±2 строки.

Параметры:

  • pattern (строка, required) — паттерн для поиска в содержимом файлов.

Пример вызова:

{
  "name": "search_in_files",
  "arguments": { "pattern": "демо" }
}

Пример результата:

Файл: встреча.md
Автор: roman
Дата: 06.09.2026 14:30

Обсудили план на неделю и договорились о **демо** в пятницу.

Установка

Требования: Node.js (последняя стабильная версия).

npm install
npm run build

После сборки готовый к запуску файл — build/index.js.

Подключение к MCP-клиенту

Сервер работает через stdio. Пример конфигурации для MCP-клиента (например, Claude Desktop): MCP сервер подключается через скачивание пакета и указания команды и пути до файла index.js

{
  "mcpServers": {
    "my-simple-notes": {
      "command": "node",
      "args": ["/absolute/path/to/simple-mcp-example/build/index.js"]
    }
  }
}

Пошаговое подключение в opencode

  1. Соберите сервер:

    npm install
    npm run build

    После сборки готовый к запуску файл — build/index.js.

  2. Создайте (или откройте) файл конфигурации opencode — opencode.json в корне проекта (либо глобально в ~/.config/opencode/opencode.json).

  3. Добавьте сервер в секцию mcp:

    {
      "$schema": "https://opencode.ai/config.json",
      "mcp": {
        "my-simple-notes": {
          "type": "local",
          "command": ["node", "./path-to-your-package-instalation/build/index.js"],
          "cwd": ".",
          "enabled": true
        }
      }
    }

    Параметры:

    • type — "local", сервер запускается локально через stdio.

    • command — команда и аргументы запуска (node build/index.js).

    • cwd — рабочая папка сервера; относительно неё создаётся папка notes с заметками.

    • enabled — true, чтобы сервер был включён при старте.

  4. Перезапустите opencode. Инструменты сервера станут доступны с префиксом имени сервера: my-simple-notes_add_note, my-simple-notes_get_all_notes, my-simple-notes_view_note_content, my-simple-notes_search_notes, my-simple-notes_search_in_files.

  5. Проверьте подключение — например, попросите в чате: «выведи список всех заметок».

Сервер можно отключить, не удаляя из конфигурации, поставив "enabled": false.

Запуск для разработки

npm install        # установка зависимостей
npm run build      # сборка
npx tsc --noEmit   # проверка типов
npm run lint       # линтер (ESLint)
npm test           # тесты (jest)

Для ручного запуска сервера через stdio:

node build/index.js

Related MCP Connectors

Related MCP Servers