yoru-studio-mcp
Yoru Studio
Самостоятельно размещаемая студия для работы одного творца.
Читать на упрощённом китайском.
Yoru Studio — это рабочее пространство одного человека для превращения идей в готовые творческие работы: поймать искру во входящих, перенести её в материнский проект, разбить на подпроекты (видео / фотоочерк / длинная статья / поставка материалов), спланировать раскадровки, провести полевые съёмки с офлайн-очередью, зафиксировать, что произошло на самом деле, и замкнуть цикл ретроспективой. Результаты живут в версиях под платформы, так что один и тот же монтаж можно выпустить как Douyin / Bilibili / набор изображений для Xiaohongshu без дублирования самого проекта.
Он написан для одного человека — творца — и работает на его собственном компьютере. Никакой мультитенантности, никаких командных мест, никакого SaaS-бэкенда. После установки вся система живёт на одной машине, которой вы управляете.
Что здесь есть
Чтение исходного кода — авторитетный ответ на вопрос «что это на самом деле делает?» — приведённое ниже резюме — это карта, а не территория.
Входящие → Материнский проект → Подпроект → Версия платформы: полный хребет творческого рабочего процесса, с быстрым путём, позволяющим хорошей идее сразу перейти в активный подпроект, когда вы знаете, куда она относится.
Раскадровки с представлением списком и представлением доски, перетаскиванием для изменения порядка, эталонными изображениями для каждого кадра, экспортом в XLSX и печатной версией для использования на площадке.
Расписание и календарь: точное время, события на весь день и размытые окна («на этой неделе», «на выходных») сосуществуют в одном календаре; просроченное вычисляется, а не запоминается, так что ничто тихо не гниёт.
Напоминания и внутрисайтовые уведомления, дедуплицированные на уровне базы данных, чтобы перезапуск никогда не срабатывал дважды на одно и то же предупреждение.
Записи о выполнении для съёмок / пересъёмок / записи экрана / писательских сессий — прикрепите запись к тому слою проекта, который действительно соответствует тому, что вы сделали.
Ретроспективы, лёгкие или полные; каждое поле необязательно. Структура существует, чтобы напомнить вам, а не требовать.
Вложения четырёх видов: загруженные изображения (с миниатюрами), указатели путей (например,
NAS/2026/Aug shoots/), внешние ссылки и текстовые фрагменты. Мягко удалённые файлы лежат в корзине 30 дней.Полевой режим: мобильная страница для использования на площадке. Если сеть пропадает, правки ставятся в очередь в IndexedDB и синхронизируются при восстановлении соединения.
Полный экспорт: JSON + пакет загрузок для выноса данных, либо из CLI, либо со страницы настроек.
Резервные копии: онлайн-резервное копирование SQLite по расписанию и опциональные скрипты restic для зашифрованных внешних копий с настоящим средством прогона восстановления.
Канал MCP для ИИ-агентов (Claude, ChatGPT, Codex, …) — см. раздел ниже.
Related MCP server: todos
Принципы дизайна
Один пользователь, одна учётная запись. Модель данных несёт колонку рабочего пространства, чтобы будущая многопользовательская версия не перестраивала схему, но всё в поставляемом коде предполагает ровно одного пользователя.
Никаких внешних сервисов. SQLite на диске, файлы на диске. Никакого Redis, никакой очереди сообщений, никакой сторонней аутентификации. Можно запустить на VPS за $5/месяц.
Малый след. Цель — приложение 512 МиБ / планировщик 256 МиБ / (опционально) боковой контейнер обратного прокси 128 МиБ. Виртуальной машины на 2 ГиБ достаточно.
Сервер не собирает фронтенд. Vite-сборка выполняется локально (или в CI) и поставляется как предварительно собранные файлы. На машинах развёртывания Node не нужен.
Содержание важнее церемоний. В форме ретроспективы нет обязательных полей — схема существует, чтобы напомнить вам, о чём подумать, а не чтобы блокировать сохранение.
Технологический стек
Бэкенд: Python 3.12, FastAPI, SQLite (с
uvдля управления зависимостями).Фронтенд: React 19 + TypeScript, собирается с помощью Vite.
Развёртывание: Docker Compose (один хост). Обратное проксирование и TLS — на ваше усмотрение — подойдут Cloudflare Tunnel, Caddy, Nginx, Tailscale Funnel или просто SSH-туннели для локального использования.
Тестирование: pytest для бэкенда, vitest для фронтенда.
Канал MCP: подключение ИИ-агентов
Yoru Studio предоставляет сервер Model Context Protocol (MCP), чтобы агенты, говорящие на MCP — Claude Desktop, ChatGPT desktop, Codex CLI, Claude Code и другие — могли читать из вашей студии и (дополнять её) без копипасты.
Всего восемь инструментов, все ограничены записью-добавлением с идемпотентностью:
Чтение (5):
list_projects— список материнских проектов со счётчиками.get_project— полные детали одного материнского проекта, включая его подпроекты.get_sub_project— один подпроект со встроенными раскадровкой / записями о выполнении / ретроспективой.get_schedule— предстоящие (14 или 30 дней), все просроченные, ближайшие размытые события.get_inbox— ожидающие или отклонённые элементы входящих.
Запись (3, все только-добавление, все идемпотентные):
capture_inspiration— бросить искру во входящие.append_storyboard_shots— атомарно добавить N кадров в раскадровку видеоподпроекта.append_execution_record— зафиксировать съёмку / писательскую сессию / тест.
Каждый инструмент записи принимает idempotency_key. Повтор с тем же ключом возвращает первый результат; другая полезная нагрузка с тем же ключом — жёсткий конфликт. Ничто из того, что делает агент, не может молча перезаписать уже имеющуюся у вас работу.
Два пути аутентификации за одной конечной точкой /mcp (спецификация §5.1 в docs/spec/ в исходниках):
Статический Bearer-токен для личного / одноагентного использования. Вы создаёте одну длинную случайную строку, сохраняете её
sha256в окружении и передаёте токен агенту.OAuth 2.0 с PKCE + динамическая регистрация клиентов для коннекторов, которые этого ожидают (коннектор ChatGPT — текущий случай, который этого требует).
Оба пути могут сосуществовать. Оба необязательны — оставьте оба не заданными, и маршрут /mcp никогда не смонтируется.
Быстрый старт
Два пути в зависимости от того, как вы хотите запускать: из исходников (для разработки или если предпочитаете управлять Python самостоятельно) или через Docker Compose (для стабильной установки на одном хосте).
Из исходников
Требуется Python 3.12 и uv, плюс Node 20+ для фронтенда.
# 1. Install Python deps and set up the venv
uv sync
# 2. Initialize / migrate the database (creates ./data/studio.sqlite3)
uv run studio init-db
# 3. Start the API server on http://127.0.0.1:8000 (local mode — no auth)
uv run studio serve
# 4. In another terminal, run the frontend dev server
cd frontend
npm install
npm run dev # http://localhost:5173, proxies to the APIЛокальный режим привязывается к loopback и пропускает аутентификацию для удобства разработчика. Чтобы попробовать поток аутентификации локально, следуйте разделу «Включение удалённого режима» ниже.
Другие команды CLI:
uv run studio db-backup # verified online SQLite backup
uv run studio db-restore <path> --confirm-database ./data/studio.sqlite3
uv run studio export # full JSON + uploads takeout
uv run studio schedule-tick # run the periodic maintenance jobs once
uv run studio hash-password # interactively hash a password for STUDIO_AUTH_PASSWORD_HASHЗапустите тесты:
uv run pytest # backend
cd frontend && npm test # frontendDocker Compose
Файл docker-compose.yml в этом репозитории определяет три сервиса: app (FastAPI + собранный SPA), scheduler (цикл с тиком в 60 секунд, выполняющий резервное копирование, напоминания, хранение) и cloudflared (эталонный боковой контейнер обратного прокси — замените его на то, что подходит вашей инфраструктуре).
Обратное проксирование / TLS намеренно вне рамок приложения: выбирайте своё. Разумные варианты включают:
Cloudflare Tunnel (эталонный сервис
cloudflaredвdocker-compose.ymlсо скриптом подготовки вscripts/provision-cloudflare-tunnel.py).Caddy или Nginx как обратный прокси на уровне хоста с завершением TLS на ваших собственных сертификатах.
Tailscale Funnel для приватного размещения.
Просто SSH-форвард
-L 8000, если вам нужно только на своей машине.
Если вы используете Cloudflare Tunnel, либо отредактируйте, либо удалите сервис cloudflared и снимите STUDIO_TRUSTED_PROXY_IPS в .env.production. Если вы используете другой прокси, задайте STUDIO_TRUSTED_PROXY_IPS как IP вашего прокси, чтобы реальные IP клиентов попадали в журнал аудита.
Шаги развёртывания (когда ваш Docker-хост готов):
# 1. Build the frontend locally — the server never builds it.
cd frontend && npm ci && npm run build && cd ..
# 2. Copy the env template and fill in the required secrets.
cp deploy/env.production.example .env.production
chmod 600 .env.production
$EDITOR .env.production
# 3. Generate a scrypt-hashed password for STUDIO_AUTH_PASSWORD_HASH.
uv run studio hash-password
# Paste the "password_hash" value into .env.production, single-quoted.
# 4. Build and start.
docker compose --env-file .env.production build
docker compose --env-file .env.production up -dВ docs/deploy.md есть более подробное руководство, охватывающее эталонную компоновку, скрипты автоматизации резервного копирования в scripts/ и операционную блокировку, которую разделяют задания развёртывания и резервного копирования.
Включение удалённого режима
Удалённый режим превращает приложение из «локальной разработки без аутентификации» в «публичный URL за прокси с сессионными cookie». Задайте как минимум:
STUDIO_MODE=remoteSTUDIO_SESSION_SECRET— случайная строка не короче 32 символов.STUDIO_AUTH_PASSWORD_HASH— выводuv run studio hash-password.STUDIO_ALLOWED_HOSTS— точное имя (имена) хоста, на которые приложение будет отвечать (без подстановочных знаков; приложение откажется запускаться с*).STUDIO_TRUSTED_PROXY_IPS— если перед приложением стоит обратный прокси, IP-адрес(а), с которых он обращается к приложению.
Приложение отказывается запускаться в удалённом режиме, если отсутствует любой из обязательных секретов или allowed_hosts пуст — это намеренно. Не существует конфигурации «тихо открытой».
Конфигурация
Большинство значений живут в переменных окружения (так производство дружелюбно к Docker). Подмножество также может жить в TOML-файле, загружаемом через --config или STUDIO_CONFIG — см. config/config.example.toml для формы.
Секреты только в окружении по дизайну: они никогда не читаются из TOML-конфига, так что включение конфиг-файла в развёртывание никогда не может их утечь.
Переменная | Назначение | По умолчанию |
|
|
|
| Адрес, к которому привязывается сервер |
|
| Порт, к которому привязывается сервер |
|
| Список имён хостов через запятую, принимаемых в заголовке | (пусто) |
| Список IP прокси через запятую, чьим | (пусто) |
| Случайная строка ≥32 символов для подписи сессионных cookie (обязательно в remote-режиме) | (пусто) |
| scrypt-хеш пароля для входа из | (пусто) |
| Где хранится база данных SQLite |
|
| Где хранятся загруженные вложения |
|
| Куда записываются онлайн-резервные копии SQLite |
|
| Куда идут журналы приложения |
|
| Необязательный путь только для чтения, куда задания резервного копирования хоста кладут | (не задан — статус показывает |
| Лимит загрузки на один файл |
|
| Общая квота загрузки на поддерево каждого материнского проекта |
|
| Защита от бомбы декомпрессии |
|
|
| (не задан) |
|
| (не задан) |
| Публичный URL, на котором размещены метаданные OAuth AS; его установка активирует путь OAuth | (не задан) |
| Список имён хостов через запятую, разрешённых в redirect URI DCR (loopback разрешён всегда) |
|
| Время жизни OAuth access-токена |
|
| Время жизни OAuth refresh-токена |
|
| Время жизни OAuth кода авторизации |
|
Генерация хешированных токенов
Конечная точка приёма и путь статического Bearer MCP хранят sha256(token) — никогда не сам токен — поэтому утёкший .env.production не даёт ничего, что можно было бы воспроизвести.
# Generate a token and its hash. The token goes to whichever caller needs it
# (your external intake, your MCP client). The hash goes into .env.production.
TOKEN=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
printf %s "$TOKEN" | sha256sum | cut -d' ' -f1 # → STUDIO_RADAR_TOKEN_HASH / STUDIO_MCP_TOKEN_HASH
echo "$TOKEN" # → give to the caller, nowhere elseВнешний приём: передайте свой собственный поток входящих во входящие
Существует HTTP-конечная точка, предназначенная для приёма элементов от внешнего источника — скрапера RSS, инструмента радара тем, запланированного задания по сбору данных, любого инструмента, который загружает контент от вашего имени. Конечная точка универсальна: принесите свой собственный апстрим, подключите его сюда, и элементы попадут во входящие, где вы их разберёте.
Конечная точка: POST /api/inbox
Аутентификация: Authorization: Bearer <token>. Сервер сравнивает sha256(token) с STUDIO_RADAR_TOKEN_HASH за постоянное время. Если эта переменная окружения не задана, конечная точка возвращает 401 на каждый вызов Bearer — приём остаётся полностью закрытым.
CSRF не требуется на этом пути: CSRF-cookie защищает от воспроизведения браузерной сессии, что не является угрозой, когда вызывающая сторона предоставляет свой собственный bearer-заголовок.
Тело запроса (JSON):
Поле | Тип | Примечания |
| строка, обязательно, ≤500 символов | Заголовок элемента входящих. Пусто / отсутствует → |
| строка, необязательно | Ваш однострочный комментарий. |
| строка, необязательно | Произвольный текст — вставленные URL подойдут. |
| строка, необязательно, ≤500 символов | Идентификатор этой темы от вашего источника. Второй по силе ключ дедупликации. |
| строка, необязательно, ≤2000 символов | Канонический URL элемента. Третий по силе ключ дедупликации. |
| строка, необязательно, ≤500 символов | Уникальный ключ на каждую доставку. Самый сильный ключ дедупликации. |
Приоритет дедупликации: idempotency_key > radar_topic_id > canonical_url. При повторной доставке сервер возвращает уже существующую строку, а не создаёт вторую — даже если вы уже отклонили или преобразовали эту строку. Повторная доставка не должна отменять ваше решение по разбору.
Ответ:
201 Created— была вставлена новая строка.200 OK— повторная доставка была сопоставлена с существующей строкой (любой статус, включая отклонённый / преобразованный). Та же форма тела.400 Bad Request— отсутствует / недействителенtitle.401 Unauthorized— неверный или отсутствующий bearer-токен, или приём не настроен.
Тело ответа:
{
"item": {
"id": 42,
"title": "…",
"source": "radar",
"status": "pending",
"created_at": "2026-08-12T12:34:56Z",
"…": "…"
},
"deduplicated": false
}Пример curl:
curl -X POST https://studio.example.com/api/inbox \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Interesting minisite on typography systems",
"first_reaction": "worth a look for the next essay",
"links": "https://example.com/article",
"canonical_url": "https://example.com/article",
"idempotency_key": "myfeed-2026-08-12-a3f9"
}'Поле называется «radar» во всей кодовой базе, потому что изначально оно было подключено к внешнему инструменту радара контента; сама конечная точка универсальна и работает с любым источником, умеющим говорить по HTTP.
Лицензия
Copyright (C) 2026 yoruuuchan.
Yoru Studio лицензируется по GNU Affero General Public License, версия 3, только (AGPL-3.0-only). LICENSE содержит точный текст лицензии.
Одним предложением: вы можете свободно размещать у себя, использовать и изменять код для своей собственной творческой работы; если вы запускаете модифицированную версию как сетевой сервис, с которым взаимодействуют другие люди, вы должны предложить им исходный код этой модифицированной версии. Именно это AGPL и призвана обеспечивать — пункт о «сетевом использовании» (§13) делает взаимное обязательство срабатывающим при запуске, а не только при распространении.
Ожидания
Это личный проект. Он существует, потому что одному создателю он был нужен, и он решил им поделиться.
Не продукт. Нет дорожной карты, на которую кто-то другой имеет право, нет SLA поддержки и нет обещания, что следующий релиз не сломает вашу настройку.
Поддерживается в собственном ритме автора. Проблемы и pull request'ы приветствуются, но ответы приходят, когда приходят.
Вы размещаете его у себя. Хостинговая версия не существует. И планов на неё нет.
Данные живут на вашей машине. Ничего не обращается домой. Ничего не отправляется третьим лицам. В этом и смысл самостоятельного размещения; это также причина, по которой никто не спасёт ваши данные, если вы их потеряете. Делайте резервные копии.
Если что-то из этого читается как «не для меня» — это честный сигнал: пожалуйста, выберите что-то другое, и никаких обид.
Вклад в проект
Отчёты об ошибках приветствуются. Пожалуйста, включайте достаточно деталей, чтобы ошибку можно было воспроизвести на чистой копии репозитория.
Запросы функций: этот проект намеренно ограничивает свой масштаб и добавляет функции только после того, как реальное использование выявит потребность. Запрос функции, который звучит как «вот с чем я реально столкнулся, пытаясь использовать приложение», с гораздо большей вероятностью будет принят, чем тот, который звучит как «вот что было бы неплохо иметь».
Pull request'ы: для чего-то большего, чем исправление ошибки в одном файле, пожалуйста, сначала откройте issue, чтобы проверить, что направление подходит. AGPL-3.0-only означает, что вклад должен быть совместим с этой лицензией — открывая pull request, вы соглашаетесь, что ваш вклад распространяется на тех же условиях, что и остальная часть проекта.
Атрибуция
Создано Yoru, Claude Fable 5 и GPT 5.6 Sol — нами троими.
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 Connectors
Remote MCP server for AI.TV creators — delegate account operations to your AI agent over MCP.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
MCP server for QPost — lets AI agents publish video and image posts to YouTube, TikTok, Instagram.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Related MCP Servers
- AlicenseBqualityDmaintenanceProduction-grade MCP server that gives AI agents safe access to your local dev environment: filesystem, databases, processes, and OpenAPI specs.15673MIT
- AlicenseNot gradedqualityBmaintenanceMCP server for task management, project knowledge, workspace trust, runner sandboxes, extension registry, and workflow prompts, enabling AI agents to manage tasks and collaborate locally.5,117Apache 2.0
- AlicenseNot gradedqualityCmaintenanceLocal MCP server that plans, generates, and assembles production assets (images, audio, video) through multi-agent personas and official APIs, with free-tier budget guard.MIT
- AlicenseNot gradedqualityCmaintenanceA self-hosted MCP server that gives AI agents controlled access to a machine: filesystem, shell, background processes, git, web fetching and persistent key-value memory.GPL 3.0
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/yoruuuchan/yoru-studio-oss'
If you have feedback or need assistance with the MCP directory API, please join our Discord server