yoru-studio-mcp
Yoru Studio
一人のクリエイターのためのセルフホスト型実行スタジオ。
簡体字中国語でも読めます。
Yoru Studio は、アイデアを完成したクリエイティブ作品に変えるための一人用ワークスペースです。受信トレイでひらめきを拾い、マザープロジェクトに引き込み、サブプロジェクト(動画/フォトエッセイ/長文記事/アセット納品)に分割し、ストーリーボードを計画し、オフラインでも安全なキューで現場撮影を実行し、実際に起きたことを記録し、レトロスペクティブでループを閉じます。成果物はプラットフォームバージョンごとに管理されるため、同じカットを Douyin/Bilibili/Xiaohongshu の画像セットとして、プロジェクト自体を複製せずに納品できます。
これは一人の人間——クリエイター——が自分のマシンで動かすために書かれています。マルチテナントの話も、チームシートも、SaaS バックエンドもありません。インストールすると、システム全体があなたが管理する一台のマシン上で動作します。
ここにあるもの
ソースを読むことが「実際に何をするのか」に対する権威ある答えです——以下の要約は地図であって、領土そのものではありません。
受信トレイ → マザープロジェクト → サブプロジェクト → プラットフォームバージョン: クリエイティブワークフローの全軸。良いアイデアが属先のわかっている場合は、アクティブなサブプロジェクトに直接スキップできるファストトラック付き。
ストーリーボード: リストビューとボードビュー、ドラッグで並べ替え、ショットごとの参照画像、XLSX エクスポート、現場用の印刷可能バージョン。
スケジュールとカレンダー: 正確な時刻、終日日付、曖昧な期間(「今週」「週末」)が一つのカレンダーに共存。期限超過は記憶ではなく計算で判定されるため、静かに腐ることはありません。
リマインダーとサイト内通知: データベース層で重複排除されるため、再起動しても同じアラートが二度発火することはありません。
実行記録: 撮影/再撮影/画面収録/執筆セッション用——実際に行ったことに合うプロジェクト階層に記録を紐付けます。
レトロスペクティブ: 軽量版とフル版。すべてのフィールドは任意です。構造は思い出させるためのものであり、要求するためのものではありません。
添付ファイル: 4 つの形態——アップロード画像(サムネイル付き)、パス参照(例:
NAS/2026/Aug shoots/)、外部リンク、テキストスニペット。ソフト削除されたファイルはゴミ箱に 30 日間保管されます。フィールドモード: 現場用のモバイルファーストページ。ネットワークが切れた場合、編集内容は IndexedDB にキューされ、接続が回復すると同期されます。
完全エクスポート: JSON + アップロードのバンドルによるデータ持ち出し。CLI または設定ページから実行可能。
バックアップ: スケジュールによるオンライン SQLite バックアップ、および暗号化されたオフサイトコピー用のオプションの restic スクリプト(実際のリストア訓練ランナー付き)。
AI エージェント用 MCP チャネル(Claude、ChatGPT、Codex など)——以下のセクションを参照。
Related MCP server: todos
設計方針
単一ユーザー、単一アカウント。 データモデルにはワークスペース列があるため、将来のマルチユーザー版でもスキーマを再構築する必要はありませんが、出荷されるコードはすべて正確に一人のユーザーを前提としています。
外部サービス不要。 ディスク上の SQLite、ディスク上のファイル。Redis もメッセージキューもサードパーティ認証もありません。月 5 ドルの VPS で動かせます。
小さなフットプリント。 目標はアプリ 512 MiB/スケジューラ 256 MiB/(任意)リバースプロキシサイドカー 128 MiB。2 GiB の VM で十分です。
サーバーはフロントエンドをビルドしない。 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 チャネル: AI エージェントを接続する
Yoru Studio は Model Context Protocol(MCP)サーバーを公開しているため、MCP を話すエージェント——Claude Desktop、ChatGPT デスクトップ、Codex CLI、Claude Code など——が、コピーペーストなしでスタジオを読み取り、(追記)できます。
合計 8 つのツール、すべて追記専用の書き込みと冪等性にスコープされています:
読み取り(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 エンドポイントの背後にある 2 つの認証パス(ソースの docs/spec/ の仕様 §5.1):
静的 Bearer トークン — 個人/単一エージェント用。長いランダム文字列を 1 つ生成し、その
sha256を環境変数に保存し、トークンをエージェントに渡します。PKCE + 動的クライアント登録を伴う OAuth 2.0 — それを期待するコネクタ用(ChatGPT のコネクタが現在それを必要とするケースです)。
両方のパスは共存できます。両方ともオプションです——両方とも未設定のままにすると、/mcp ルートはマウントされません。
クイックスタート
実行方法に応じて 2 つのパスがあります: ソースから(開発用、または 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ローカルモードはループバックにバインドし、開発者の利便性のために認証をスキップします。認証フローをローカルで試すには、以下の「リモートモードを有効にする」セクションに従ってください。
その他の 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 は 3 つのサービスを定義しています: app(FastAPI + ビルド済み SPA)、scheduler(バックアップ、リマインダー、保持ポリシーを実行する 60 秒ティックのループ)、cloudflared(参照用リバースプロキシサイドカー——インフラに合うものに置き換えてください)。
リバースプロキシ/TLS は意図的にアプリのスコープ外です: ご自身で選んでください。妥当な選択肢は次のとおりです:
Cloudflare Tunnel(
docker-compose.ymlの参照cloudflaredサービス、scripts/provision-cloudflare-tunnel.pyのプロビジョニングスクリプト付き)。Caddy または Nginx をホストレベルのリバースプロキシとして使用し、独自の証明書で TLS を終端。
Tailscale Funnel によるプライベートファーストのホスティング。
自分のマシンだけで使うなら SSH フォワード
-L 8000だけでも。
Cloudflare Tunnel を使用する場合は、cloudflared サービスを編集または削除し、.env.production の STUDIO_TRUSTED_PROXY_IPS を未設定にしてください。別のプロキシを使用する場合は、実際のクライアント IP が監査ログに記録されるよう、STUDIO_TRUSTED_PROXY_IPS にプロキシの 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 -ddocs/deploy.md には、参照レイアウト、scripts/ 配下のバックアップ自動化スクリプト、デプロイジョブとバックアップジョブが共有する操作ロックをカバーする、より長いウォークスルーがあります。
リモートモードを有効にする
リモートモードは、アプリを「認証なしのローカル開発」から「セッションクッキー付きのプロキシ背後にある公開 URL」に変えます。最低限以下を設定します:
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 フレンドリーです)。一部の値は --config または STUDIO_CONFIG で読み込まれる TOML ファイルにも置けます——形状は config/config.example.toml を参照してください。
シークレットは設計上 環境変数のみ です: TOML 設定から読み取られることは決してないため、設定ファイルをデプロイに同梱してもシークレットが漏れることはありません。
変数 | 用途 | デフォルト |
|
|
|
| サーバーがバインドするアドレス |
|
| サーバーがバインドするポート |
|
| 受け付ける |
|
|
|
|
| セッションCookieの署名に使う32文字以上のランダム文字列 (remote モードでは必須) |
|
|
|
|
| SQLite データベースの保存先 |
|
| アップロードされた添付ファイルの保存先 |
|
| SQLite オンラインバックアップの書き出し先 |
|
| アプリのログの保存先 |
|
| ホストのバックアップジョブがアプリ内ステータスウィジェット用に |
|
| ファイルごとのアップロード上限 |
|
| マザープロジェクトのサブツリーごとのアップロード総量クォータ |
|
| 展開爆弾 (decompression bomb) ガード |
|
| 取り込みチャネルのベアラートークンの |
|
| MCP 静的 Bearer トークンの |
|
| OAuth AS メタデータをホストする公開 URL。設定すると OAuth パスが有効になる |
|
| DCR リダイレクト URI で許可するホスト名のカンマ区切りリスト (ループバックは常に許可) |
|
| OAuth アクセストークンの有効期間 |
|
| OAuth リフレッシュトークンの有効期間 |
|
| OAuth 認可コードの有効期間 |
|
ハッシュ化トークンの生成
取り込みエンドポイントと MCP 静的 Bearer パスはどちらも、トークンそのものではなく 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外部取り込み: 自前のフィードを受信ボックスに届ける
外部フィーダー — RSS スクレイパー、トピックレーダーツール、定期スクレイプジョブなど、あなたに代わってコンテンツを取り込むあらゆる仕組み — から項目を受け取るために設計された HTTP エンドポイントがあります。このエンドポイントは汎用的です。自前の上流ソースを持ってきてここに接続すれば、項目はあなたがトリアージする受信ボックスに届きます。
エンドポイント: POST /api/inbox
認証: Authorization: Bearer <token>。サーバーは sha256(token) を STUDIO_RADAR_TOKEN_HASH と定数時間で比較します。この環境変数が未設定の場合、エンドポイントはすべての Bearer 呼び出しに 401 を返します — 取り込みは完全に閉じたままです。
このパスで CSRF は不要です。CSRF Cookie はブラウザのセッションリプレイへの防御ですが、呼び出し側が独自の Bearer ヘッダーを提供する場合は脅威になりえません。
リクエストボディ (JSON):
フィールド | 型 | 備考 |
| string、必須、500文字以内 | 受信ボックス項目のタイトル。空白/欠落 → |
| string、任意 | あなたのひとことのホットテイク。 |
| string、任意 | 自由記述テキスト — 貼り付けた URL のままで問題ありません。 |
| string、任意、500文字以内 | このトピックに対するフィーダ側の識別子。2番目に強い重複排除キー。 |
| string、任意、2000文字以内 | 項目の正規 URL。3番目に強い重複排除キー。 |
| string、任意、500文字以内 | 配信ごとの一意なキー。最も強い重複排除キー。 |
重複排除の優先順位: idempotency_key > radar_topic_id > canonical_url。再配信時、サーバーは2つ目を生成するのではなく、既存の行を返します — その行をすでに破棄または変換していたとしても同じです。再配信によってあなたのトリアージ判断が覆されることはありません。
レスポンス:
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, version 3, only (AGPL-3.0-only) の下でライセンスされています。LICENSE にはライセンス条文の原文が含まれています。
ひとことで言うと: 自分の創作活動のために、このコードを自由に自己ホスト・利用・変更できます。ただし、変更版を他の人が接するネットワークサービスとして実行する場合は、その変更版のソースコードを提供しなければなりません。これはまさに AGPL が実現しようとしていることです — 「ネットワーク利用」条項 (§13) により、相互的な義務は配布時だけでなく実行時にも発生します。
期待すること
これは個人プロジェクトです。一人の作り手が必要とし、共有したいと思ったために存在します。
製品ではありません。 誰かが期待できるロードマップも、サポート SLA も、次のリリースがあなたの環境を壊さないという約束もありません。
作者自身のペースでメンテナンスされています。 イシューやプルリクエストは歓迎ですが、返答はあるときに来ます。
あなたが自分でホストします。 ホステッドバージョンはありません。その計画もありません。
データはあなたのマシンに置かれます。 外部に連絡することはありません。第三者に送信されることもありません。それがセルフホスティングの要点であり、データを失ったときに誰も助けてくれなかったりしない理由でもあります。バックアップを取りましょう。
どれかが「自分の対象外だ」と読めたなら、それが正直なシグナルです — 別のものを選んでください。恨みはありません。
コントリビューション
バグ報告は歓迎します。クリーンなチェックアウトで再現できる十分な詳細を含めてください。
機能リクエスト: このプロジェクトは意図的に小さなスコープに抑えており、実際に使ってニーズが現れた後にのみ機能を追加します。「アプリを使っていて実際にぶつかったのはこういうものです」という内容の機能リクエストは、「こういうものがあったらいいのにな」という内容のものよりはるかに採用されやすいです。
プルリクエスト: 1つのファイルの修正より大きなものは、最初にイシューを開いて方向性が合っているか確認してください。AGPL-3.0-only であるため、コントリビューションはそのライセンスと互換である必要があります — プルリクエストを開くことで、あなたのコントリビューションがプロジェクトの他部分と同じ条件に同意したことになります。
クレジット
Yoru、Claude Fable 5、GPT 5.6 Sol によって構築されました — この3人です。
This server cannot be deployed
Related MCP Connectors
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Remote MCP server for AI.TV creators — delegate account operations to your AI agent over MCP.
Hosted MCP server for AI agents to post to LinkedIn profiles and X and upload to YouTube.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Related MCP Servers
- AlicenseBqualityDmaintenanceProduction-grade MCP server that gives AI agents safe access to your local dev environment: filesystem, databases, processes, and OpenAPI specs.1565 npm4MIT
- 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,117 npmApache 2.0
- AlicenseNot gradedqualityBmaintenanceA 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
- FlicenseAqualityCmaintenanceA local-first MCP server that handles daily work tasks through your AI assistant: converts meeting notes into todos, manages todo lifecycle, tracks work hours, generates daily/weekly reports, organizes files via move-only operations, and diagnoses dev environments, all guarded by a human-maintained preview/apply safety model.25-