screencast
screencast-desktop
Плагин Claude Code, который позволяет агенту управлять приложением Windows и превращать этот сеанс в готовое демонстрационное видео — где камера начинает приближаться к каждому клику за полсекунды до того, как клик произойдёт.
Управляйте рабочим столом с визуальной обратной связью. Каждое действие возвращает свежий скриншот в том же ответе, поэтому агент работает по схеме «смотри → действуй → смотри», а не пишет сценарий вслепую. Элементы управления находятся по имени через Windows UI Automation; приложения Electron, не предоставляющие дерева элементов, используют скриншоты и координаты (или их DOM через CDP, если открыт порт отладки).
Записывайте окно, а не экран. Захват выполняется через Windows Graphics Capture, привязанный к дескриптору окна, поэтому рабочий стол за приложением никогда не попадает в кадр, и не важно, на каком мониторе или GPU находится окно.
Видео строится из журнала событий, а не из видеозаписи. Каждый клик, каждая введённая строка и полный путь курсора фиксируются с временными метками по мере их возникновения. Движения камеры вычисляются на основе этого журнала.
Отделка уровня Screen Studio, создаваемая автоматически: плавные наезды и панорамирования камеры, нарисованный курсор с мягкой тенью, круги от кликов, размытие движения, скруглённые углы на градиентном фоне, виньетка и зерно — плюс удаление мёртвого воздуха, которое сокращает время размышлений агента.
Озвучка, попадающая в такт. Необязательный голос ElevenLabs, генерируемый до запуска, чтобы клик попадал внутрь предложения, которое его описывает.
Более полный слой монтажа — в одном скрипте. Титульные и финальные карточки, субтитры и полный цикл звукового дизайна — дорожка кликов, свист камеры, удары при приземлении, финальный подъём, приглушённый музыкальный фон, нормализация громкости — находятся в
cinematic.py,sfx.pyиsfx_bank.py. Они управляются черезserver/make_showcase.py, а не через инструментdesktop_render; см. Известные ограничения.Бесплатный повторный рендер. Рендеринг никогда не касается приложения: измените предел масштабирования, озвучку или эффекты и пересобирайте тот же дубль сколько угодно раз.
Почему это отличается

Каждый рекордер экрана, который делает «авто-зум» — Screen Studio и его имитаторы на Windows — работает одинаково: сначала записывает, затем возвращается через перехват мыши или саму запись, чтобы угадать, где были интересные моменты. Такой порядок имеет жёсткое следствие, которое никто не может обойти: зум не может начаться до клика, потому что в момент клика рекордер только что узнал, что клик приближается. Максимум, что он может сделать, — начать движение в момент клика и прибыть чуть позже. Человеческие редакторы делают наоборот — они ведут зрителя, чтобы глаз уже был на кнопке, когда она нажата.
Здесь агент генерирует действия, поэтому координаты и тайминги известны до того, как будет скомпонован хотя бы один кадр. Камере можно задать упреждение (LEAD_IN = 0.55 s в server/camera.py), так что к моменту нажатия кнопки кадр уже прибыл и устоялся. То же предвидение даёт ещё три вещи, которых не может быть у инструмента, работающего постфактум:
Без пульсации. Последовательные клики в одной области объединяются в один устойчивый кадр, а не камера приближается и отдаляется на каждом элементе списка.
Озвучка, которая подходит. Речь генерируется до запуска (
voice.plan()), её реальная длительность измеряется с помощьюffprobe, а паузы агента устанавливаются на основе этих чисел — поэтому клик попадает внутрь предложения, которое его описывает, без ручной подстройки. Запись сначала и озвучка после всегда заканчиваются тем, что голос говорит «Я нажимаю Сохранить» через секунду после того, как Сохранить уже было нажато.Машиночитаемая запись произошедшего.
desktop_describe_takeчитает дубль как нумерованную процедуру («3. [12.4s] нажмите Умножить на») — лучший артефакт, чем куча скриншотов, и достаточный для создания переиспользуемого навыка.
Где это находится среди соседей

Идея не нова — просто её трудно реализовать на Windows. Четыре браузерных проекта, реализующих «редактирование из журнала действий», появились в течение двух недель марта 2026 года (argo, testreel, pagecast, playwright-recast), потому что Playwright даёт журнал бесплатно. На Windows журнал нужно строить вместе с драйвером ввода, и за те же пять месяцев ничего не появилось: рекордеры не имеют агента, а агенты не создают кадры.
Related MCP server: windows-gui-mcp
Требования
OS | Windows 11 (разработано и протестировано там). Windows 10 2004+ имеет две функции ОС, на которые опирается плагин — Windows Graphics Capture и встроенный WinRT OCR — но не тестировалось. |
Python | 3.10 или новее (требуется для |
ffmpeg | Полная сборка, в |
GPU | Видеокарта NVIDIA с NVENC. И модуль записи захвата, и композитор в настоящее время по умолчанию запрашивают |
Claude Code | Любая последняя версия с поддержкой плагинов. |
ElevenLabs API key | Необязательно. Без него всё работает, видео просто без звука. |
Пакеты Python
Взято из импортов каждого модуля в server/:
pip install mcp pillow opencv-python numpy windows-capture uiautomationPackage | Used by | Needed for |
|
| сам MCP-сервер (FastMCP) |
|
| скриншоты, титульные карточки и субтитры (текст Unicode — |
|
| компоновка кадров, деформация камеры, размытие движения |
| композитор, | буферы кадров и аудио |
|
| привязки Windows Graphics Capture |
|
| дерево элементов |
|
| необязательно — только для |
Для проверки конфиденциальности не нужен ни один пакет: она читает экран с помощью OCR, встроенного в Windows, через PowerShell.
Установка
1. Получите плагин
git clone https://github.com/JHamidun/screencast-desktop.git2. Зарегистрируйте его в Claude Code
Репозиторий является собственным маркетплейсом (.claude-plugin/marketplace.json), поэтому укажите Claude Code на клон и установите оттуда:
/plugin marketplace add <path-to-clone>
/plugin install screencast-desktop.mcp.json регистрирует оба сервера с путями относительно ${CLAUDE_PLUGIN_ROOT}, поэтому ничего не требует глобальной установки, и клон может находиться где угодно.
3. Запустите настройку
/screencast-desktop:setupЭто запускает server/doctor.py, который проверяет вещи, которые ломаются молча:
Осведомлённость о DPI — процессу, который не заявил о своей DPI-осведомлённости, сообщается, что экран 2560×1440, когда на самом деле 3840×2160, и каждый клик промахивается на коэффициент масштабирования.
Раскладка мониторов — координаты общие для всех экранов и становятся отрицательными на вторичных мониторах.
ffmpeg и доступные кодеки.
Захват окна, по-настоящему — он захватывает ~25 кадров и проверяет, что они не все одинаковые.
Озвучка — есть ли ключ и существует ли настроенный идентификатор голоса на аккаунте (иначе удалённый голос приводит к ошибке 404).
Он записывает machine.json с тем, что нашёл.
4. Загрузите бинарный файл UI Automation
Сервер windows-ui — это внешний бинарный файл — sbroenne/mcp-windows (MIT). Он намеренно не включён в этот репозиторий: он весит ~60 МБ, это чужой проект, и фиксация копии здесь привела бы к устаревшей версии. Скачайте его по требованию:
python server/fetch_ui_binary.py # --force to re-downloadСкрипт определяет последний релиз GitHub, проверяет архив по опубликованному SHA256SUMS.txt и отказывается устанавливать что-либо при несовпадении. Он попадает в bin/, где его ожидает .mcp.json.
5. Убедитесь, что оба сервера работают
claude mcp list # expect: screencast, windows-uiБыстрый старт
Запишите демо калькулятора Windows. Команда /screencast-desktop:record проведёт агента через это, но вот что она делает на самом деле, с реальными именами инструментов.
1 — Разместите окно. Поместите его на вторичный монитор, если он есть, чтобы оно не перекрывало вашу работу:
desktop_monitors()
desktop_place_window(window="Calculator", monitor=1, fit=0.7)Прочитайте ответ. Приложения не обязаны принимать запрошенный размер — окно UWP, которому здесь было задано 2380×1490, вернулось как 3967×2426 и вышло за пределы экрана. desktop_place_window измеряет результат, исправляет его и прямо сообщает, помещается ли окно.
2 — Проверьте кадр на наличие конфиденциальной информации.
desktop_screenshot(window="Calculator")
desktop_privacy_check(window="Calculator")Проверка сообщает, но не блокирует: она распознаёт текст на кадре и помечает номера карт, ключи API, адреса электронной почты, номера телефонов и личные имена. Включите режим «Не беспокоить» перед записью.
3 — Репетиция. Пройдите маршрут с реальными инструментами и убедитесь по возвращённым скриншотам, что вы попадаете туда, куда думаете. Пока ничего не записывается:
ui_snapshot(windowHandle=…) # windows-ui: controls by name — try this first
desktop_snapshot(window="Calculator")# or the built-in UIA walk, which returns e1, e2, … refs
desktop_click(ref="e7")4 — Сбросьте приложение. Оставленное открытым поле поиска с репетиции попадёт в дубль.
5 — Запишите настоящий дубль.
desktop_record_start(window="Calculator")
desktop_click(ref="e12") # every click from here is logged for the camera
desktop_type("128")
desktop_click(ref="e19")
desktop_record_stop()desktop_record_stop сообщает длительность, количество кадров и сколько кликов попало в журнал, затем указывает out_dir для рендеринга.
6 — Отрендерите, затем посмотрите.
desktop_render(out_dir="%USERPROFILE%/screencasts/take-143502", max_zoom=2.0)
desktop_render_status(out_dir="…") # rendering runs in a child processОткройте файл и проверьте глазами: попала ли камера туда, куда нужно, нет ли чёрных полос по краям, виден ли курсор. Неверная координата даёт технически корректный файл, в котором камера смотрит в никуда. Если что-то не так, запустите desktop_render повторно с другими настройками — приложение заново не запускается и экран не записывается повторно.
Справочник по инструментам
сервер screencast — desktop_monitors, desktop_windows, desktop_screenshot,
desktop_snapshot, desktop_dom, desktop_dom_launch, desktop_click, desktop_type,
desktop_key, desktop_move_mouse, desktop_scroll, desktop_focus, desktop_launch,
desktop_place_window, desktop_privacy_check, desktop_record_start, desktop_record_stop,
desktop_render, desktop_render_status, desktop_describe_take.
desktop_click, desktop_type, desktop_key, desktop_scroll, desktop_focus и
desktop_launch принимают see="shot" (по умолчанию) или see="none" — второй вариант экономит контекст, когда вы уже знаете, как выглядит экран.
сервер windows-ui (доступное подмножество) — ui_snapshot, ui_find, ui_click, ui_type,
ui_select, ui_read, ui_wait, window_management, app.
Как это работает

То же самое текстом, для тех, кто читает это в терминале:
AGENT server/
───── ───────
desktop_click / desktop_type / … desktop_server.py
│ (MCP, FastMCP)
├──► real SendInput: cursor eased to the target, driver.py
│ clicked, keys sent ── moves + clicks
│ the real desktop
│
├──► EVENT LOG t, kind, x, y, label, dur driver.py → events.json
│ + the sampled cursor path (track) ◄── the ground truth
│
└──► screenshot back to the agent in the same reply
desktop_record_start recorder_proc.py (child process)
└──► Windows Graphics Capture, bound to the HWND wgc.py
├─ frames arrive only when the picture ── writer thread re-sends
│ changes … the last frame on a
└─ … so a writer thread feeds ffmpeg at a fixed clock
constant rate, logging the true
wall-clock time of every frame
→ raw.mp4 + frame_times.json
desktop_render render_proc.py (child process)
│
├─ 1. TIMELINE collapse the dead air timeline.py
│ keep 1.1 s before and 1.5 s after every
│ action, squeeze the gaps to 0.55 s
│
├─ 2. CAMERA event log → keyframes camera.py
│ lead-in 0.55 s BEFORE each click,
│ nearby clicks merged into one shot,
│ pan instead of pumping in and out
│
├─ 3. COMPOSITOR one affine matrix per frame composer.py
│ recording on a gradient backdrop, rounded + cinematic.py
│ corners, drop shadow, drawn cursor, click (vignette, grain;
│ ripples, motion blur, breathing idle, title cards and
│ vignette, grain captions available)
│ → silent.mp4
│
└─ 4. SOUND optional narration voice.py
ElevenLabs TTS mixed onto the cut → demo.mp4
make_showcase.py — the fuller montage, run as a script rather than a tool:
the same four stages plus title/outro cards, captions, and the whole
sound design pass (clicks, whooshes, impacts, riser, ducked music bed,
loudness normalisation) sfx.py + sfx_bank.pyДва проектных решения объясняют большую часть структуры файлов:
Запись и рендеринг выполняются в дочерних процессах. Импорт библиотеки захвата или OpenCV внутри процесса MCP-сервера подвешивает его, а рендер занимает минуты — ни один вызов инструмента не должен держать его открытым. recorder_proc.py и render_proc.py существуют только ради этого. Они общаются через файлы (started.json, stop, render.log), и оба запускаются с stdin=DEVNULL — дочерний процесс, унаследовавший stdin сервера, начинает поглощать JSON-RPC запросы, предназначенные серверу.
Кадры сопоставляются по времени, а не по индексу. Если машина не успевает, исходный кадр N находится не на позиции N/fps. frame_times.json хранит реальное время захвата каждого кадра, и компоновщик ищет кадры через него — именно поэтому камера остаётся на кликах, когда машина притормаживает.
Конфигурация
Рендеринг
desktop_render(out_dir, name="demo.mp4", max_zoom=2.0, narration="") — narration принимает JSON-список вида {"text": …, "at": seconds}.
Всё остальное — константы модуля, которые правятся на месте:
Константа | Файл | По умолчанию | Что делает |
|
|
| секунды до события, в течение которых камера начинает движение |
|
|
| диапазон масштабирования; при 2× и выше исходник 4K начинает апскейлиться |
|
|
| длительности наезда и отъезда камеры |
|
|
| минимальное удержание плана, несущего информацию |
|
|
| насколько агрессивно близкие клики объединяются в один план |
|
|
| секунды, показываемые на полной скорости вокруг каждого действия |
|
|
| до какого значения ужимается сжатая пауза |
|
|
| разрешение на выходе |
|
|
| доля кадра, заполняемая записью без зума |
|
|
| скруглённые углы, высота курсора, смещение тени (в пикселях на выходе) |
|
|
| размытие движения; 360 = затвор открыт весь кадр |
|
|
| эффект киноплёнки |
|
|
| субпиксельный сдвиг на длинных статичных планах, чтобы удержанные кадры не выглядели застывшими |
desktop_record_start(window, out_dir="", fps=30) по умолчанию использует каталог ~/screencasts/take-HHMMSS.
Если max_zoom не задан, camera.build() сам выбирает предел, чтобы в кадре оставалось не менее 70 % высоты окна — высокое узкое окно, вписанное в кадр 16:9, и так уже невелико, а принудительный зум 2× там обрезает часть, которая придаёт действию смысл. (На Калькуляторе он отрезал дисплей с результатом.)
Озвучка
Задайте ELEVENLABS_API_KEY в переменных окружения или в файле .env в корне плагина (KEY=value, по одному на строку — файл игнорируется git). При желании можно закрепить голос через ELEVENLABS_VOICE_ID; если ничего не задано, используется первый голос в аккаунте. Модель: eleven_multilingual_v2. Укажите SCREENCAST_ENV_FILE в другом месте, если храните ключи где-то ещё.
voice.resolve_voice() проверяет настроенные идентификаторы по фактическому списку голосов аккаунта, прежде чем использовать голос, потому что иначе удалённый голос вызывает необъяснимую ошибку 404.
Без ключа ничего не ломается. doctor.py сообщает об этом как о предупреждении, а не об ошибке, и desktop_render создаёт видео без звука — ровно то же самое происходит с ключом, когда аргумент narration не передан.
Слой звукового оформления деградирует, а не умирает без ключа: sfx_bank.build() требует ElevenLabs для генерации палитры, но sfx_bank.build_synthetic() синтезирует те же семейства офлайн с помощью numpy (файлы *_syn1.wav / *_syn2.wav), а sfx.click_samples() в качестве запасного варианта использует synth_click(), когда семплы не найдены. Поэтому офлайн-машина по-прежнему получает клики, свисты и удары — теряется только голос.
Известные ограничения
Честный список. Это реальные, актуальные на текущий момент ограничения, по большей части — то, с чем мы столкнулись в ходе разработки. Что планируется с ними делать, в порядке приоритета и с измерениями по каждому пункту, описано в ROADMAP.md.
Инструмент
desktop_renderрендерит меньше, чем умеет кодовая база. Он вызываетcomposer.compose()безintro,outroилиcaptionsи микширует только озвучку — ни дорожки кликов, ни свистов, ни музыкальной подложки. Всё остальное реализовано и работает, но сейчас доступно только черезserver/make_showcase.py— скрипт с собственным жёстко заданным путём к тейку и списком битов. Прокинуть эти параметры в инструмент — самая очевидная открытая задача в этом репозитории.Нет перетаскивания. Инструмента для перетаскивания или drag-and-drop не существует. Нажатие и отпускание мыши всегда происходят в одной и той же позиции, поэтому всё, что требует жеста «нажать — переместить — отпустить» — слайдеры, изменение порядка, рисование на холсте, изменение размера за ручку — недоступно.
Нажатия клавиш не записываются в журнал событий.
desktop_keyотправляет нажатие, но не логирует его, поэтому камера никогда не реагирует на шаги, выполняемые только клавиатурой, и они не появляются вdesktop_describe_take. Клики и вводимый текст (desktop_type) логируются; отдельные нажатия клавиш — нет.К окнам UWP нужно обращаться через их оконную рамку. Windows Graphics Capture принимает дескриптор окна верхнего уровня. Для приложения UWP/Store это видимое
ApplicationFrameWindow— внутреннееCoreWindowне является подходящей целью захвата. На практике: находите приложение по видимому заголовку окна (именно так и поступают инструменты) и не пытайтесь проникнуть за него.desktop_screenshot— это вырезка экрана, а не захват окна. Он захватывает область экрана, которую занимает окно. Всё, что перекрывает окно — другое окно, всплывающее уведомление, подсказка — попадает в скриншот. (У записи такой проблемы нет: WGC захватывает само окно.) Убедитесь, что целевое окно находится поверх остальных, прежде чем доверять скриншоту.Приложения Electron почти ничего не открывают для UI Automation. По замерам на Windows 11: типичное приложение Electron возвращает от 2 до 6 именованных элементов — обёртки окон, а не интерфейсы. Придётся использовать скриншоты и координаты или
desktop_dom, когда доступен порт отладки.desktop_dom_launchоткрывает вторую копию приложения с отдельным профилем, в котором не выполнен вход.NVENC фактически обязателен. И
wgc.WindowRecorder, иcomposer.compose()по умолчанию используютh264_nvenc. Варианты сlibx264реализованы, иdoctor.pyопределяет подходящий кодировщик вmachine.json, но автоматически этот выбор пока нигде не подхватывается. На машине без NVENC кодировщик придётся передавать самостоятельно.Большие файлы. Зерно плёнки применяется к каждому кадру, что сводит на нет межкадровое сжатие — короткий демо-ролик весит больше, чем тот же материал без зерна. Задайте
grain_amount=0, если размер важнее внешнего вида.Длительность тейка ограничена 15 минутами.
recorder_proc.pyостанавливается сам, поэтому забытая запись не может идти бесконечно.Только Windows, и только интерактивный рабочий стол. SendInput, UI Automation, WGC и WinRT OCR — всё это Windows API; ничего из этого не работает в сеансе без пользователя, в службе или на заблокированном экране.
Окно — это живое приложение. Состояние сохраняется между тейками — оставленное открытым с репетиции поле поиска превратило введённое слово в «githubgithub». Сбросьте приложение перед чистовым тейком.
Проверка конфиденциальности сообщает, но не блокирует. Сопоставление буквальное: имя в меню — не утечка, а OCR что-то пропускает. Посмотрите на кадр сами, прежде чем публиковать.
Благодарности и лицензии
sbroenne/mcp-windows (MIT) — MCP-сервер
windows-ui, который занимается UI Automation. Сюда не включён; загружается по требованию скриптомserver/fetch_ui_binary.pyи сверяется сSHA256SUMS.txtиз самого релиза.ffmpeg — кодирование захваченного видео, микширование звука и измерение длительности через
ffprobe. Вызывается как внешний бинарник; в комплект не входит. Лицензирование зависит от установленной сборки (LGPL или GPL).Звуковой банк. Файлы
.wavвserver/sfx_bank/генерируются, а не сэмплируются:server/sfx_bank.pyсоздаёт их один раз из рецептов-промптов через API генерации звука ElevenLabs и кэширует, а каждый кандидат проверяется измерениями («клик», пик которого приходится на 200 мс, отклоняется, как бы хорошо он ни звучал). Второе семейство файлов —*_syn1.wav,*_syn2.wav— синтезируется полностью офлайн вsfx_bank.build_synthetic()с помощью numpy, поэтому машина без API-ключа всё равно получает звуковое оформление. Никакая сторонняя библиотека сэмплов здесь не распространяется. УкажитеSCREENCAST_SFX_DIRна свою папку с сэмплами — иsfx.pyбудет предпочитать эти клики и музыкальные подложки встроенному банку; если ничего не задано, используетсяserver/sfx_bank/, а если ничего не найдено, выполняется синтез. Жёсткой зависимости нет ни в ту, ни в другую сторону.ElevenLabs — опционально, для озвучки и создания звукового банка. Приносите свой ключ; плагин не содержит аудио, сгенерированного из чьего-либо голоса.
Шрифты — в заголовках и подписях используется Segoe UI, который поставляется с Windows, с Arial в качестве запасного. Никакие файлы шрифтов не распространяются.
Model Context Protocol Python SDK (MIT) — серверный фреймворк.
Собственный код плагина распространяется под лицензией MIT. См. LICENSE.
Участие в разработке
Приветствуются issues и pull requests. Несколько вещей, которые ускоряют ревью:
Только Windows. Тестируйте на реальном десктопе; нет такого CI, который мог бы кликать по кнопкам за вас.
Сначала запустите doctor (
python server/doctor.py) и вставьте его вывод в баг-репорт — большинство проблем здесь связано с окружением (масштабирование DPI, расположение мониторов, отсутствие энкодера), и doctor называет их напрямую.Если что-то сломалось молча, напишите об этом в комментарии. В этой кодовой базе полно заметок, объясняющих, почему строка такая, какая она есть, потому что почти каждая такая строка — это сбой, который выглядел как успех: идентичные кадры, которые можно принять за запись, камера, уплывающая за край, пустой журнал событий, из-за которого видео получается вообще без зума. Эти заметки оставлены намеренно.
Изменения констант камеры или таймлайна требуют клипа до/после. Это вопрос субъективного суждения о том, как результат выглядит, и ни один тест его не решит.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables comprehensive Windows desktop automation including screen capture, OCR text extraction, mouse/keyboard control, window management, process control, and clipboard operations through 25+ tools for AI agents.4MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI coding agents to automate Windows desktop applications through semantic UI Automation instead of brittle coordinate clicks, with tools for discovering windows, finding controls by stable identifiers, and verifying actions.1MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to control Windows GUI applications like a human using screen capture, OCR, mouse and keyboard input, and window management, with safety levels and memory.
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to interact with the Windows operating system, performing tasks such as file navigation, application control, UI interaction, and QA testing.MIT
Related MCP Connectors
AI-powered browser automation — navigate, click, fill forms, and extract data from any website.
Eyes and hands on real Windows PCs — observe, click, type via Glasswarp API.
Turns any agent into a full agentic application — branded, interactive screens generated at runtime.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/JHamidun/screencast-desktop'
If you have feedback or need assistance with the MCP directory API, please join our Discord server