meshy-youtube-mcp
# meshy-youtube-mcp
[](BCOS.md)
[](LICENSE)
## What is meshy-youtube-mcp? (answer-first)
**meshy-youtube-mcp is a Python MCP server that lets an AI agent generate a
Meshy.ai 3D model, render it with Blender and ffmpeg, and publish the resulting
video to YouTube through OAuth-backed `videos.insert`.** For LLM/search/answer
engine context, see the root [`llms.txt`](llms.txt) profile.
**An MCP server that takes a text prompt all the way to a published YouTube video:
[Meshy.ai](https://www.meshy.ai/) 3D generation → Blender turntable → YouTube upload.**
```
prompt ──▶ Meshy text-to-3D ──▶ Blender 360° turntable ──▶ ffmpeg ──▶ YouTube videos.insert
(.glb model) (PNG frames) (.mp4) (published video)
```
Any MCP-capable agent — Claude, or anything that speaks [MCP](https://modelcontextprotocol.io)
— can call it to generate rotating 3D content and publish it straight to YouTube.
> **Sibling project:** [`meshy-bottube-mcp`](https://github.com/Scottcjn/meshy-bottube-mcp)
> publishes the same pipeline to **BoTTube** (a video network *for AI agents*).
> **BoTTube is the agent-native channel; YouTube is the human-reach channel** — same
> Meshy generation, two audiences. Pick the publisher that fits who's watching.
The shared render core is proven end-to-end on the BoTTube edition:
a [PBR-textured turntable](https://bottube.ai/watch/piP8ls-AsrS) and an
[animated walking character](https://bottube.ai/watch/upEzFIx0rF5) (the
`render_animation` moving-clip path).
## Tools
| Tool | Input | Output |
|------|-------|--------|
| `generate_3d_model` | prompt, art_style | `.glb` + task ids (preview→refine, PBR textured) |
| `generate_3d_from_image` | image (URL/path) | `.glb` from a single image |
| `generate_3d_from_images` | 1–4 images | `.glb` from multiple reference images |
| `retexture_model` | model + style | re-textured `.glb` variant |
| `rig_model` · `animate_model` | model / rig+action_id | rigged / animated `.glb` |
| `get_meshy_task_status` | task_id | status / `.glb` on success |
| `render_turntable` · `frames_to_video` | `.glb` / frames | PNG frames / `.mp4` |
| `upload_to_youtube` | `.mp4`, title | `video_id`, `watch_url` (OAuth) |
| **`meshy_to_youtube`** | prompt | **one-shot:** text → 3D → turntable → published |
| **`image_to_youtube`** | image | **one-shot:** image → 3D → turntable → published |
| **`retexture_to_youtube`** | model + style | **one-shot:** re-texture → turntable → published |
| **`animate_to_youtube`** | model, action_id | **one-shot:** rig → animate → render motion → published |
## Requirements
- Python 3.10+
- [`ffmpeg`](https://ffmpeg.org/) and [Blender](https://www.blender.org/) on `PATH`
- A [Meshy.ai](https://www.meshy.ai/) API key
- A Google account + a YouTube OAuth client (one-time setup, below)
## Install
```bash
git clone https://github.com/Scottcjn/meshy-youtube-mcp
cd meshy-youtube-mcp
pip install -r requirements.txt
cp .env.example .env # add your MESHY_API_KEY
```
## One-time YouTube authorization
YouTube uploads use OAuth2 (not a simple API key). Set it up once:
1. [Google Cloud Console](https://console.cloud.google.com/) → create/select a project
2. Enable **YouTube Data API v3**
3. **Credentials → Create OAuth client ID → Desktop app** → download the JSON
4. Save it as `~/.config/meshy-youtube-mcp/client_secret.json`
(or set `YOUTUBE_CLIENT_SECRET_FILE`)
5. Authorize once — opens a browser, mints a reusable token:
```bash
python -m meshy_youtube.authorize
```
After that, uploads run unattended via the stored refresh token. You only
re-authorize if the token is revoked or deleted.
> **Quota:** YouTube's default free quota is 10,000 units/day and a
> `videos.insert` costs 1,600 — about **6 uploads/day**. Request more in the
> Cloud Console if you need it.
## Run as an MCP server
```json
{
"mcpServers": {
"meshy-youtube": {
"command": "python3",
"args": ["/path/to/meshy-youtube-mcp/meshy_youtube/server.py"],
"env": {
"MESHY_API_KEY": "your_meshy_key",
"YOUTUBE_TOKEN_FILE": "/home/you/.config/meshy-youtube-mcp/token.json"
}
}
}
}
```
Then ask your agent: *"Generate a 3D crystal dragon and publish it to YouTube as
an unlisted turntable."* It calls `meshy_to_youtube` and hands back a watch URL.
You can also `pip install -e .` and run `meshy-youtube-mcp`, or
`python -m meshy_youtube.server`.
## Use as a library
```python
from meshy_youtube import meshy, turntable, video, youtube
info = meshy.generate("a steampunk robot", "model.glb", art_style="realistic")
tt = turntable.render(info["glb_path"], "frames/", resolution=1080)
mp4 = video.frames_to_video(tt["frames_dir"], "turntable.mp4")
res = youtube.upload(mp4, title="Steampunk Robot — 3D Turntable",
tags=["3d", "meshy"], privacy="unlisted")
print(res["watch_url"])
```
## Privacy & categories
- `privacy`: `public` | `unlisted` | `private` (default **unlisted** — shareable
by link, not surfaced publicly until you choose to).
- `category_id`: YouTube category. Defaults to `22` (People & Blogs). Common ones:
`1` Film & Animation, `20` Gaming, `23` Comedy, `24` Entertainment,
`28` Science & Technology.
## Behavior notes
- The one-shot `meshy_to_youtube` **always returns a dict** (`ok` + `watch_url`,
or `ok=False` + `error`/`failed_stage` + partial paths). Granular tools raise.
- Secrets (`client_secret.json`, `token.json`, `.env`) are gitignored and the
token is written `0600`. Never commit them.
- The Meshy/Blender/ffmpeg stages are shared, hardened code from the
[BoTTube edition](https://github.com/Scottcjn/meshy-bottube-mcp) (two-stage
preview→refine, atomic GLB download, subprocess isolation, numeric frame
normalization, bounds + preflight).
## Roadmap
**v0.1–v0.2 (shipped):** two-stage Meshy generation, PBR texturing controls
(`texture_prompt`/`enable_pbr`), Blender turntable, YouTube OAuth publish
(resumable upload, atomic `0600` token, COPPA `madeForKids` as an explicit
choice), resilient polling, 21 tests.
**v0.3 (shipped):** the full Meshy modality set — image-to-3D, multi-image-to-3D,
retexture, and **rigging + animation** (rig a humanoid, apply a motion from
Meshy's 500+ action library, and render the **moving** character via a dedicated
Blender animation-render path).
> Note: Meshy's **3D-to-Video** is a web-app feature with no public API, so it
> can't be an MCP tool. The rig→animate→render chain delivers the same outcome.
**Next:** multi-model scenes (camera moves, staging), smarter per-style framing.
## Tests
```bash
python -m unittest discover -s tests -v
```
## License
MIT © 2026 Scott Boudreaux / [Elyan Labs](https://github.com/Scottcjn).
TDQS
Scored across 14 tools
Most tools target a distinct pipeline stage: generation, retexturing, rigging, animation, rendering, video encoding, and upload. The four *_to_youtube pipeline tools intentionally overlap with the step-wise tools, but their one-shot descriptions and naming make the intended choice clear.
Core tools follow a consistent verb_noun snake_case pattern (generate_3d_model, retexture_model, rig_model, animate_model). The *_to_youtube pipeline tools are internally consistent but deviate from the verb-first pattern, and get_meshy_task_status embeds the brand name.
14 tools are well-scoped for a generation-to-YouTube pipeline. Each stage has dedicated tools, and the four pipelines add useful high-level entry points without becoming bloated.
The surface covers the full workflow from text/image/model input through retexture, rig, animate, render, encode, and upload, with status checks throughout. The main gap is that animate_model refers to Meschy's action library without a tool to list available actions.