yoru-studio-mcp
Yoru Studio
Ein selbst gehostetes Studio für einen einzelnen Creator.
Lies dies auf Vereinfachtem Chinesisch.
Yoru Studio ist der Arbeitsbereich einer einzelnen Person, um Ideen in fertige kreative Arbeiten zu verwandeln: einen Funken im Posteingang aufgreifen, ihn in ein Mutterprojekt ziehen, in Unterprojekte aufteilen (Video / Fotoessay / langer Artikel / Asset-Lieferung), Storyboards planen, Außendrehs mit einer offline-sicheren Warteschlange durchführen, protokollieren, was tatsächlich passiert ist, und dann mit einer Retrospektive den Kreis schließen. Die Ergebnisse liegen unter Plattformversionen vor, sodass derselbe Schnitt als Douyin / Bilibili / ein Xiaohongshu-Bilderset ausgeliefert werden kann, ohne das Projekt selbst zu duplizieren.
Es ist für eine Person geschrieben – den Creator –, die es auf ihrem eigenen Rechner betreibt. Es gibt keine Multi-Tenant-Geschichte, keine Team-Sitze, kein SaaS-Backend. Wenn du es installierst, lebt das gesamte System auf einer Maschine, die du kontrollierst.
Was hier ist
Den Quellcode zu lesen ist die maßgebliche Antwort auf „Was macht es eigentlich?“ – die Zusammenfassung unten ist eine Karte, nicht das Gebiet.
Posteingang → Mutterprojekt → Unterprojekt → Plattformversion: das vollständige Rückgrat eines kreativen Workflows, mit einer Schnellspur, die eine gute Idee direkt in ein aktives Unterprojekt springen lässt, wenn du weißt, wohin sie gehört.
Storyboards mit Listenansicht und Board-Ansicht, Ziehen zum Neuanordnen, Referenzbildern pro Einstellung, XLSX-Export und einer druckbaren Version für den Einsatz am Set.
Zeitplan und Kalender: präzise Zeiten, ganztägige Daten und vage Zeitfenster („diese Woche“, „das Wochenende“) koexistieren in einem Kalender; Überfälligkeit wird berechnet, nicht erinnert, sodass nichts still verrottet.
Erinnerungen und In-Site-Benachrichtigungen, auf Datenbankebene dedupliziert, sodass ein Neustart nie dieselbe Warnung zweimal auslöst.
Ausführungsaufzeichnungen für Drehs / Nachdrehs / Bildschirmaufnahmen / Schreibsitzungen – hänge den Datensatz an die Projektebene an, die tatsächlich zu dem passt, was du getan hast.
Retrospektiven, leicht oder vollständig; jedes Feld ist optional. Die Struktur ist da, um dich zu erinnern, nicht um zu fordern.
Anhänge in vier Formen: hochgeladene Bilder (mit Thumbnails), Pfadverweise (z. B.
NAS/2026/Aug shoots/), externe Links und Textausschnitte. Soft gelöschte Dateien liegen 30 Tage lang im Papierkorb.Feldmodus: mobile-first Seite für den Einsatz am Set. Wenn das Netzwerk ausfällt, werden Bearbeitungen in IndexedDB in die Warteschlange gestellt und synchronisieren sich, wenn die Verbindung zurückkehrt.
Vollständiger Export: JSON + Uploads-Bundle für Takeout, entweder über die CLI oder die Einstellungsseite.
Backups: Online-SQLite-Backup nach Zeitplan und optionale restic-Skripte für verschlüsselte Off-Site-Kopien mit einem echten Restore-Übungs-Runner.
MCP-Kanal für KI-Agenten (Claude, ChatGPT, Codex, …) – siehe Abschnitt unten.
Related MCP server: todos
Design-Ansatz
Einzelner Benutzer, einzelnes Konto. Das Datenmodell trägt eine Workspace-Spalte, damit eine zukünftige Multi-User-Version das Schema nicht neu aufbauen muss, aber alles im ausgelieferten Code geht von genau einem Benutzer aus.
Keine externen Dienste erforderlich. SQLite auf der Festplatte, Dateien auf der Festplatte. Kein Redis, keine Nachrichtenwarteschlange, keine Drittanbieter-Authentifizierung. Du kannst es auf einem VPS für 5 $/Monat betreiben.
Kleiner Fußabdruck. Ziel sind App 512 MiB / Scheduler 256 MiB / (optional) Reverse-Proxy-Sidecar 128 MiB. Eine 2-GiB-VM reicht aus.
Der Server baut das Frontend nicht. Das Vite-Bundle wird lokal (oder in CI) gebaut und als vorgefertigte Dateien ausgeliefert. Deployment-Maschinen benötigen nie Node.
Inhalt vor Zeremonie. Das Retro-Formular hat keine Pflichtfelder – das Schema existiert, um dich daran zu erinnern, worüber du nachdenken sollst, nicht um das Speichern zu blockieren.
Tech-Stack
Backend: Python 3.12, FastAPI, SQLite (mit
uvfür die Abhängigkeitsverwaltung).Frontend: React 19 + TypeScript, gebaut mit Vite.
Deployment: Docker Compose (Single-Host). Reverse-Proxy und TLS liegen bei dir – Cloudflare Tunnel, Caddy, Nginx, Tailscale Funnel oder einfach SSH-Tunnel für rein lokale Nutzung funktionieren alle.
Testen: pytest für das Backend, vitest für das Frontend.
MCP-Kanal: KI-Agenten verbinden
Yoru Studio stellt einen Model Context Protocol (MCP)-Server bereit, damit Agenten, die MCP sprechen – Claude Desktop, ChatGPT Desktop, Codex CLI, Claude Code und andere – aus deinem Studio lesen und (daran anhängen) können, ohne dass du kopierst und einfügst.
Insgesamt acht Werkzeuge, alle auf Append-Only-Schreibvorgänge mit Idempotenz beschränkt:
Lesen (5):
list_projects– Mutterprojektliste mit Zählern.get_project– die vollständigen Details eines Mutterprojekts, einschließlich seiner Unterprojekte.get_sub_project– ein Unterprojekt, mit Storyboard / Ausführungsaufzeichnungen / Retrospektive integriert.get_schedule– anstehende (14 oder 30 Tage), alle überfälligen, kurzfristige vage Ereignisse.get_inbox– ausstehende oder verworfene Posteingangselemente.
Schreiben (3, alle Append-Only, alle idempotent):
capture_inspiration– einen Funken in den Posteingang werfen.append_storyboard_shots– atomar N Einstellungen zum Storyboard eines Video-Unterprojekts hinzufügen.append_execution_record– einen Dreh / eine Schreibsitzung / einen Test protokollieren.
Jedes Schreibwerkzeug nimmt einen idempotency_key entgegen. Ein erneuter Versuch mit demselben Schlüssel gibt das erste Ergebnis zurück; eine andere Nutzlast mit demselben Schlüssel ist ein harter Konflikt. Nichts, was ein Agent tut, kann stillschweigend Arbeit überschreiben, die du bereits hast.
Zwei Authentifizierungspfade hinter demselben /mcp-Endpunkt (Spezifikation §5.1 von docs/spec/ im Quellcode):
Statisches Bearer-Token für den persönlichen / Einzel-Agenten-Gebrauch. Du erzeugst eine lange zufällige Zeichenfolge, speicherst ihren
sha256in der Umgebung und gibst das Token dem Agenten.OAuth 2.0 mit PKCE + Dynamic Client Registration für Konnektoren, die es erwarten (ChatGPTs Konnektor ist der aktuelle Fall, der es erfordert).
Beide Pfade können koexistieren. Beide sind optional – lasse beide ungesetzt und die /mcp-Route wird nie gemountet.
Schnellstart
Zwei Wege, je nachdem, wie du es ausführen möchtest: aus dem Quellcode (für die Entwicklung oder wenn du Python selbst verwalten möchtest) oder über Docker Compose (für eine stabile Single-Host-Installation).
Aus dem Quellcode
Erfordert Python 3.12 und uv, plus Node 20+ für das Frontend.
# 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 APIDer lokale Modus bindet an Loopback und überspringt die Authentifizierung zur Bequemlichkeit des Entwicklers. Um den Authentifizierungsablauf lokal auszuprobieren, folge dem Abschnitt „Aktivieren des Remote-Modus“ weiter unten.
Andere CLI-Befehle:
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_HASHFühre die Tests aus:
uv run pytest # backend
cd frontend && npm test # frontendDocker Compose
Die docker-compose.yml in diesem Repository definiert drei Dienste: app (das FastAPI + gebaute SPA), scheduler (eine Schleife mit 60-Sekunden-Takt, die Backups, Erinnerungen und Aufbewahrung ausführt) und cloudflared (ein Referenz-Reverse-Proxy-Sidecar – tausche es gegen das aus, was zu deiner Infrastruktur passt).
Reverse-Proxy / TLS ist bewusst außerhalb des Anwendungsbereichs der App: Wähle deine eigene. Vernünftige Optionen sind:
Cloudflare Tunnel (der Referenz-
cloudflared-Dienst indocker-compose.yml, mit dem Bereitstellungsskript inscripts/provision-cloudflare-tunnel.py).Caddy oder Nginx als Reverse-Proxy auf Host-Ebene, der TLS mit deinen eigenen Zertifikaten beendet.
Tailscale Funnel für privates Hosting an erster Stelle.
Einfach SSH weiterleiten
-L 8000, wenn du es nur auf deiner eigenen Maschine haben möchtest.
Wenn du Cloudflare Tunnel verwendest, bearbeite oder entferne entweder den cloudflared-Dienst und setze STUDIO_TRUSTED_PROXY_IPS in .env.production zurück. Wenn du einen anderen Proxy verwendest, setze STUDIO_TRUSTED_PROXY_IPS auf die IP deines Proxys, damit echte Client-IPs im Audit-Log landen.
Bereitstellungsschritte (sobald dein Docker-Host bereit ist):
# 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 enthält eine längere Anleitung, die das Referenzlayout, die Backup-Automatisierungsskripte unter scripts/ und die Betriebssperre abdeckt, die die Bereitstellungs- und Backup-Jobs teilen.
Aktivieren des Remote-Modus
Der Remote-Modus verwandelt die App von „lokale Entwicklung ohne Authentifizierung“ in „öffentliche URL hinter einem Proxy mit Session-Cookies“. Setze mindestens:
STUDIO_MODE=remoteSTUDIO_SESSION_SECRET– eine zufällige Zeichenfolge, mindestens 32 Zeichen.STUDIO_AUTH_PASSWORD_HASH– die Ausgabe vonuv run studio hash-password.STUDIO_ALLOWED_HOSTS– die genauen Hostnamen, auf die die App antworten wird (keine Wildcards; die App weigert sich, mit*zu starten).STUDIO_TRUSTED_PROXY_IPS– wenn ein Reverse-Proxy davor ist, die IP(s), die er verwendet, um mit der App zu sprechen.
Die App weigert sich, im Remote-Modus zu starten, wenn eines der erforderlichen Geheimnisse fehlt oder wenn allowed_hosts leer ist – das ist beabsichtigt. Es gibt keine „still offene“ Konfiguration.
Konfiguration
Die meisten Werte leben in Umgebungsvariablen (Produktion ist auf diese Weise Docker-freundlich). Eine Teilmenge kann auch in einer TOML-Datei leben, die über --config oder STUDIO_CONFIG geladen wird – siehe config/config.example.toml für die Form.
Geheimnisse sind nur über Umgebungsvariablen konzipiert: Sie werden nie aus der TOML-Konfiguration gelesen, sodass das Bündeln der Konfigurationsdatei mit einer Bereitstellung sie niemals preisgeben kann.
Variable | Zweck | Standard |
|
|
|
| Adresse, an die der Server bindet |
|
| Port, an den der Server bindet |
|
| Kommagetrennte Liste von Hostnamen, die im | (leer) |
| Kommagetrennte Liste von Proxy-IPs, deren | (leer) |
| Zufällige Zeichenkette mit ≥32 Zeichen zum Signieren von Sitzungs-Cookies (erforderlich im Remote-Modus) | (leer) |
| scrypt-gehashtes Anmeldekennwort von | (leer) |
| Wo die SQLite-Datenbank liegt |
|
| Wo hochgeladene Anhänge gespeichert werden |
|
| Wo SQLite-Online-Backups geschrieben werden |
|
| Wo Anwendungsprotokolle abgelegt werden |
|
| Optionaler schreibgeschützter Pfad, in den die Backup-Jobs des Hosts | (nicht gesetzt — Status zeigt |
| Obergrenze für Upload pro Datei |
|
| Gesamt-Upload-Kontingent pro Unterbaum des Mutterprojekts |
|
| Schutz vor Dekompressionsbomben |
|
|
| (nicht gesetzt) |
|
| (nicht gesetzt) |
| Öffentliche URL, die die OAuth-AS-Metadaten hostet; das Setzen aktiviert den OAuth-Pfad | (nicht gesetzt) |
| Kommagetrennte Hostnamen, die in DCR-Weiterleitungs-URIs erlaubt sind (Loopback ist immer erlaubt) |
|
| Lebensdauer des OAuth-Zugriffstokens |
|
| Lebensdauer des OAuth-Refresh-Tokens |
|
| Lebensdauer des OAuth-Autorisierungscodes |
|
Generieren von gehashten Tokens
Der Aufnahme-Endpunkt und der MCP-Statisch-Bearer-Pfad speichern beide sha256(token) – niemals das Token selbst –, sodass ein durchgesickertes .env.production nichts Wiederverwendbares liefert.
# 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 elseExterner Eingang: Übergebe deinen eigenen Feed an den Posteingang
Es gibt einen HTTP-Endpunkt, der dafür ausgelegt ist, Elemente von einem externen Zuführer zu empfangen – einen RSS-Scraper, ein Themen-Radar-Tool, einen geplanten Scrape-Job, was auch immer Inhalte in deinem Namen aufnimmt. Der Endpunkt ist generisch: Bringe deine eigene Quelle mit, verbinde sie hier, und die Elemente landen im Posteingang, wo du sie sortierst.
Endpunkt: POST /api/inbox
Authentifizierung: Authorization: Bearer <token>. Der Server vergleicht sha256(token) mit STUDIO_RADAR_TOKEN_HASH in konstanter Zeit. Wenn diese Umgebungsvariable nicht gesetzt ist, gibt der Endpunkt bei jedem Bearer-Aufruf 401 zurück – der Eingang bleibt vollständig geschlossen.
CSRF ist auf diesem Pfad nicht erforderlich: Das CSRF-Cookie schützt vor Browser-Sitzungs-Wiedergabe, was keine Bedrohung darstellt, wenn der Aufrufer seinen eigenen Bearer-Header liefert.
Anfragekörper (JSON):
Feld | Typ | Hinweise |
| Zeichenkette, erforderlich, ≤500 Zeichen | Der Titel des Posteingangselements. Leer / fehlend → |
| Zeichenkette, optional | Deine einzeilige Kurzmeinung. |
| Zeichenkette, optional | Freitext – eingefügte URLs sind in Ordnung. |
| Zeichenkette, optional, ≤500 Zeichen | Die Kennung deines Zuführers für dieses Thema. Zweitstärkster Deduplizierungsschlüssel. |
| Zeichenkette, optional, ≤2000 Zeichen | Kanonische URL des Elements. Drittstärkster Deduplizierungsschlüssel. |
| Zeichenkette, optional, ≤500 Zeichen | Eindeutiger Schlüssel pro Zustellung. Stärkster Deduplizierungsschlüssel. |
Deduplizierungspriorität: idempotency_key > radar_topic_id > canonical_url. Bei einer wiederholten Zustellung gibt der Server die bereits vorhandene Zeile zurück, anstatt eine zweite zu erstellen – selbst wenn du diese Zeile bereits verworfen oder konvertiert hast. Eine erneute Zustellung darf deine Triage-Entscheidung nicht umstoßen.
Antwort:
201 Created– eine brandneue Zeile wurde eingefügt.200 OK– eine wiederholte Zustellung wurde einer vorhandenen Zeile zugeordnet (beliebiger Status, einschließlich verworfen / konvertiert). Gleiche Antwortstruktur.400 Bad Request– fehlender / ungültigertitle.401 Unauthorized– ungültiges oder fehlendes Bearer-Token oder Eingang nicht konfiguriert.
Antwortkörper:
{
"item": {
"id": 42,
"title": "…",
"source": "radar",
"status": "pending",
"created_at": "2026-08-12T12:34:56Z",
"…": "…"
},
"deduplicated": false
}Curl-Beispiel:
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"
}'Das Feld wird im gesamten Codebase als „radar“ bezeichnet, weil es ursprünglich mit einem externen Content-Radar-Tool verbunden war; der Endpunkt selbst ist generisch und funktioniert mit jedem Zuführer, der HTTP sprechen kann.
Lizenz
Copyright (C) 2026 yoruuuchan.
Yoru Studio ist unter der GNU Affero General Public License, Version 3, nur (AGPL-3.0-only) lizenziert. LICENSE enthält den wörtlichen Lizenztext.
In einem Satz: Du kannst den Code für deine eigene kreative Arbeit frei selbst hosten, verwenden und modifizieren; wenn du eine modifizierte Version als Netzwerkdienst betreibst, mit dem andere Personen interagieren, musst du ihnen den Quellcode dieser modifizierten Version anbieten. Genau das soll die AGPL durchsetzen – die „Netzwerknutzungs“-Klausel (§13) löst die wechselseitige Verpflichtung bereits beim Betreiben aus, nicht erst beim Verteilen.
Erwartungen
Dies ist ein persönliches Projekt. Es existiert, weil ein Ersteller es brauchte und beschloss, es zu teilen.
Kein Produkt. Es gibt keine Roadmap, auf die jemand anderes Anspruch hätte, keine Support-SLA und kein Versprechen, dass die nächste Version deine Einrichtung nicht bricht.
Wird im eigenen Rhythmus des Autors gepflegt. Issues und Pull-Requests sind willkommen, aber Antworten kommen, wann sie kommen.
Du hostest es selbst. Es gibt keine gehostete Version. Es gibt keinen Plan für eine.
Daten leben auf deinem Rechner. Nichts ruft nach Hause. Nichts wird an Dritte gesendet. Das ist der Sinn des Selbsthostens; es ist auch der Grund, warum niemand deine Daten retten wird, wenn du sie verlierst. Mache Backups.
Wenn das für dich wie „nichts für mich“ klingt, ist das das ehrliche Signal – bitte wähle etwas anderes, und es gibt keine bösen Gefühle.
Mitwirken
Fehlerberichte sind willkommen. Bitte füge genügend Details hinzu, damit der Fehler gegen einen sauberen Checkout reproduziert werden kann.
Feature-Anfragen: Dieses Projekt hält sich bewusst klein und fügt Funktionen nur hinzu, nachdem die reale Nutzung einen Bedarf aufgedeckt hat. Eine Feature-Anfrage, die sich liest wie „hier ist, worauf ich tatsächlich gestoßen bin, als ich die App benutzt habe“, hat weitaus bessere Chancen als eine, die sich liest wie „hier ist eine nette Sache, die man haben könnte“.
Pull-Requests: Für alles, was größer ist als ein Ein-Datei-Fehlerbehebung, öffne bitte zuerst ein Issue, um zu prüfen, ob die Richtung passt. AGPL-3.0-only bedeutet, dass Beiträge mit dieser Lizenz kompatibel sein müssen – mit dem Öffnen eines Pull-Requests stimmst du zu, dass dein Beitrag unter denselben Bedingungen wie der Rest des Projekts steht.
Namensnennung
Erstellt von Yoru, Claude Fable 5 und GPT 5.6 Sol – wir drei.
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