yoru-studio-mcp
Yoru Studio
一个为单一创作者提供的自托管执行工作室。
阅读此文档的简体中文版本。
Yoru Studio 是一个人的工作空间,用于将想法转化为完成的创意作品:在收件箱中捕捉灵感,将其拉入母项目,拆分为子项目(视频 / 图片散文 / 长文 / 资产交付),规划故事板,使用离线安全队列进行外景拍摄,记录实际发生的情况,然后通过回顾来闭环。交付物位于平台版本之下,因此同一剪辑可以作为抖音 / 哔哩哔哩 / 小红书图片集发布,而无需复制项目本身。
它是为一个人——创作者——在自己的机器上运行而编写的。没有多租户的故事,没有团队席位,没有 SaaS 后端。当你安装它时,整个系统都位于你控制的一台机器上。
这里有什么
阅读源代码是回答“它实际上做什么?”的权威方式——下面的摘要是一张地图,而不是领土本身。
收件箱 → 母项目 → 子项目 → 平台版本:创意工作流的完整主干,并带有快速通道,当你知道一个好想法属于哪里时,可以直接跳入活跃的子项目。
故事板:支持列表视图和看板视图,拖拽排序,每个镜头的参考图片,XLSX 导出,以及用于现场的可打印版本。
日程与日历:精确时间、全天日期和模糊时间窗口(“本周”、“周末”)共存于一个日历中;逾期是计算出来的,而不是记住的,所以不会悄悄腐烂。
提醒和站内通知,在数据库层去重,因此重启永远不会重复触发同一条提醒。
执行记录:用于拍摄 / 重拍 / 屏幕录制 / 写作会话——将记录附加到与你实际所做匹配的任何项目层。
回顾,轻量或完整;每个字段都是可选的。结构的存在是为了提醒你,而不是要求你。
附件有四种形式:上传的图片(带缩略图)、路径指针(例如
NAS/2026/Aug shoots/)、外部链接和文本片段。软删除的文件在回收站中保留 30 天。现场模式:为现场使用而设计的移动优先页面。如果网络断开,编辑内容会在 IndexedDB 中排队,并在连接恢复时同步。
完整导出:JSON + 上传文件捆绑包,用于数据迁移,可从 CLI 或设置页面进行。
备份:按计划进行在线 SQLite 备份,以及可选的 restic 脚本,用于加密的异地副本,并带有真正的恢复演练运行器。
MCP 通道,用于 AI 代理(Claude、ChatGPT、Codex 等)——请参阅下面的章节。
Related MCP server: todos
设计立场
单用户,单账户。 数据模型带有一个工作区列,因此未来的多用户版本不必重建模式,但已发布代码中的所有内容都假设只有一个用户。
不需要外部服务。 磁盘上的 SQLite,磁盘上的文件。没有 Redis,没有消息队列,没有第三方认证。你可以在每月 5 美元的 VPS 上运行它。
占用空间小。 目标是应用 512 MiB / 调度器 256 MiB /(可选)反向代理边车 128 MiB。2 GiB 的虚拟机就足够了。
服务器不构建前端。 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 暴露了一个模型上下文协议(MCP)服务器,因此支持 MCP 的代理——Claude Desktop、ChatGPT 桌面版、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 端点后面有两条认证路径(源代码中 docs/spec/ 的规范 §5.1):
静态 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本地模式绑定到回环地址并跳过认证,以方便开发。要在本地尝试认证流程,请按照下面的“启用远程模式”部分操作。
其他 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(
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。如果你使用其他代理,请将 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 -ddocs/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 友好)。一部分也可以位于由 --config 或 STUDIO_CONFIG 加载的 TOML 文件中——有关格式,请参阅 config/config.example.toml。
密钥在设计上仅限环境变量:它们永远不会从 TOML 配置中读取,因此将配置文件与部署捆绑在一起永远不会泄露它们。
变量 | 用途 | 默认值 |
|
|
|
| 服务器绑定的地址 |
|
| 服务器绑定的端口 |
|
| 在 | (空) |
| 逗号分隔的代理 IP 列表,这些代理的 | (空) |
| 用于签名会话 Cookie 的随机字符串,长度 ≥32 字符(远程模式必需) | (空) |
| 来自 | (空) |
| SQLite 数据库所在位置 |
|
| 上传附件所在位置 |
|
| SQLite 在线备份写入位置 |
|
| 应用日志存放位置 |
|
| 可选的只读路径,主机的备份任务会在其中放置 | (未设置——状态显示 |
| 单文件上传上限 |
|
| 每个母项目子树的上传总配额 |
|
| 解压炸弹防护 |
|
| 摄取通道 bearer 令牌的 | (未设置) |
| 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外部摄取:将你自己的源交给收件箱
有一个 HTTP 端点,用于接收来自外部供给器的条目——可以是 RSS 抓取器、主题雷达工具、定时抓取任务,或任何代你摄取内容的程序。该端点是通用的:自带上游,接到这里,条目就会进入收件箱,由你进行分流处理。
端点: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 字符 | 你的供给器对该主题的标识符。第二强的去重键。 |
| string,可选,≤2000 字符 | 条目的规范 URL。第三强的去重键。 |
| string,可选,≤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 通用公共许可证,仅第 3 版(AGPL-3.0-only)授权。LICENSE 包含逐字许可证文本。
一句话概括:你可以自由地自行托管、使用和修改代码,用于你自己的创作;如果你将修改后的版本作为网络服务运行供他人交互,你必须向他们提供该修改版本的源代码。这正是 AGPL 的设计目标——“网络使用”条款(§13)使互惠义务在运行该服务时即触发,而不仅仅是在分发时触发。
期望
这是一个个人项目。它之所以存在,是因为一位创作者需要它,并决定将其分享出来。
不是产品。 没有哪条路线图是别人有权要求的,没有支持 SLA,也不保证下一个版本不会破坏你的现有环境。
按作者自己的节奏维护。 欢迎提交 issue 和 pull request,但回复时间不定。
由你自己托管。 不存在托管版本,也没有相关计划。
数据保存在你的机器上。 没有任何东西会回传,也不会向第三方发送任何内容。这正是自我托管的意义所在;也是如果你丢失数据,没有人会来救你的原因。请做好备份。
如果其中任何一条让你觉得“不适合我”,那这就是真实的信号——请选择其他方案,彼此无需介怀。
贡献
欢迎提交错误报告。请提供足够的细节,使错误能够在干净检出(clean checkout)上重现。
功能请求:这个项目刻意保持小范围,只有在实际使用暴露出需求后才会添加功能。一个读起来像“这是我在使用应用时实际遇到的问题”的功能请求,远比读起来像“这是一个锦上添花的功能”的请求更有可能被采纳。
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