{"id":51194666,"url":"https://github.com/davidmosiah/youtube-shorts-agent","last_synced_at":"2026-06-27T19:01:54.927Z","repository":{"id":355832862,"uuid":"1229801172","full_name":"davidmosiah/youtube-shorts-agent","owner":"davidmosiah","description":"Agent-first YouTube Shorts upload CLI and MCP server with dry-run API uploads","archived":false,"fork":false,"pushed_at":"2026-05-29T19:18:11.000Z","size":204,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-29T20:12:49.178Z","etag":null,"topics":["agent-tools","agentic-workflows","ai-agents","claude","cli","codex","creator-tools","dry-run","local-first","mcp","mcp-server","model-context-protocol","oauth","youtube","youtube-api","youtube-shorts"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/youtube-shorts-agent","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/davidmosiah.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-05T11:54:14.000Z","updated_at":"2026-05-29T19:18:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/davidmosiah/youtube-shorts-agent","commit_stats":null,"previous_names":["davidmosiah/youtube-shorts-agent"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/davidmosiah/youtube-shorts-agent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmosiah%2Fyoutube-shorts-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmosiah%2Fyoutube-shorts-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmosiah%2Fyoutube-shorts-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmosiah%2Fyoutube-shorts-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davidmosiah","download_url":"https://codeload.github.com/davidmosiah/youtube-shorts-agent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmosiah%2Fyoutube-shorts-agent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34864431,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-27T02:00:06.362Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-tools","agentic-workflows","ai-agents","claude","cli","codex","creator-tools","dry-run","local-first","mcp","mcp-server","model-context-protocol","oauth","youtube","youtube-api","youtube-shorts"],"created_at":"2026-06-27T19:01:52.140Z","updated_at":"2026-06-27T19:01:54.919Z","avatar_url":"https://github.com/davidmosiah.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- delx header v2 --\u003e\n\u003ch1 align=\"center\"\u003eYouTube Shorts Agent\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"assets/banner.png\" alt=\"YouTube Shorts Agent\" width=\"85%\" /\u003e\n\u003c/div\u003e\n\n\u003ch3 align=\"center\"\u003e\n  Agent-first YouTube Shorts uploader for the YouTube Data API.\u003cbr\u003eDry-run safe, OAuth readiness checks, MCP-ready for Codex / Claude / Cursor / Hermes.\n\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/youtube-shorts-agent\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/youtube-shorts-agent?style=for-the-badge\u0026labelColor=0F172A\u0026color=10B981\u0026logo=npm\u0026logoColor=white\" alt=\"npm version\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/youtube-shorts-agent\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/youtube-shorts-agent?style=for-the-badge\u0026labelColor=0F172A\u0026color=0EA5A3\u0026logo=npm\u0026logoColor=white\" alt=\"npm downloads\" /\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/LICENSE-MIT-22C55E?style=for-the-badge\u0026labelColor=0F172A\" alt=\"License MIT\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://modelcontextprotocol.io\"\u003e\u003cimg src=\"https://img.shields.io/badge/BUILT_FOR-MCP-7C3AED?style=for-the-badge\u0026labelColor=0F172A\" alt=\"Built for MCP\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/davidmosiah/youtube-shorts-agent/stargazers\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/davidmosiah/youtube-shorts-agent?style=for-the-badge\u0026labelColor=0F172A\u0026color=FBBF24\u0026logo=github\" alt=\"GitHub stars\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/davidmosiah/youtube-shorts-agent/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/davidmosiah/youtube-shorts-agent/actions/workflows/ci.yml/badge.svg\" alt=\"CI status\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/davidmosiah\"\u003e\u003cimg src=\"https://img.shields.io/badge/PART_OF-Delx_Agent_Stack-0EA5A3?style=for-the-badge\u0026labelColor=0F172A\" alt=\"Part of the Delx agent stack\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/davidmosiah/youtube-shorts-agent\"\u003e\u003cimg src=\"https://img.shields.io/badge/CATEGORY-Reach-FF0000?style=for-the-badge\u0026labelColor=0F172A\" alt=\"Category\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003e ⭐ **If this agent-first tool helps your workflow, please star the repo.** Stars make this tooling easier for other builders to discover and help Delx keep shipping open infrastructure.\u003cbr\u003e\n\u003e 🧱 Part of the [Delx agent stack](https://github.com/davidmosiah) \u0026mdash; 15 open-source MCP servers across **body, reach and coordination**.\n\n---\n\n\u003c!-- /delx header v2 --\u003e\n\nAgent-first YouTube Shorts uploader for the YouTube Data API. It is designed for Codex, Claude, Cursor, Hermes, OpenClaw and any MCP client that needs a predictable upload workflow with dry-run safety, OAuth readiness checks and structured output.\n\nUse it when an agent needs to prepare, validate or upload Shorts through the official API without touching YouTube Studio UI.\n\n## What Agents Get\n\n- `youtube_agent_manifest` for install/runtime guidance\n- `youtube_connection_status` before upload attempts\n- `youtube_privacy_audit` for local token and media boundaries\n- `youtube_oauth_authorize_url` with local PKCE session storage\n- `youtube_upload_short` with `containsSyntheticMedia` support\n- `youtube_list_recent_videos` for lightweight post-upload checks\n\n## Install\n\n```bash\nnpm install -g youtube-shorts-agent\n```\n\nOr run directly:\n\n```bash\nnpm exec --yes --package=youtube-shorts-agent -- youtube-shorts-agent doctor\n```\n\n## CLI\n\n```bash\nyoutube-shorts-agent manifest --client codex\nyoutube-shorts-agent doctor\nyoutube-shorts-agent privacy-audit\nyoutube-shorts-agent auth-url --redirect-uri http://localhost:8787/callback\nyoutube-shorts-agent upload-short --video ./short.mp4 --title \"Launch title\" --caption-file copy.txt\nyoutube-shorts-agent list-recent --max-results 10\n```\n\nDry-run is enabled by default. Set `YOUTUBE_DRY_RUN=false` only when `doctor` reports a complete OAuth setup and you intend to call the live API.\n\n## First Upload (dry-run walkthrough)\n\nThis is the full first-run path. Every step here is **dry-run safe** — no credentials are required and nothing is sent to YouTube. The output below is captured verbatim from a real run.\n\n**1. Check readiness.** With no OAuth configured, `doctor` confirms you are in dry-run mode:\n\n```bash\nyoutube-shorts-agent doctor\n```\n\n```json\n{\n  \"ok\": true,\n  \"dry_run\": true,\n  \"configured\": {\n    \"client_credentials\": \"missing\",\n    \"access_token\": \"missing\",\n    \"refresh_token\": \"missing\"\n  },\n  \"missing_count\": 3,\n  \"ready_for_live_upload\": false,\n  \"next_steps\": [\n    \"Current mode is dry-run. Validate metadata and agent flow before live uploads.\"\n  ]\n}\n```\n\n**2. Prepare a Short and its caption.**\n\n```bash\nprintf 'Launching the agent-first Shorts uploader.\\n#shorts #ai #agents' \u003e copy.txt\n# short.mp4 is your vertical 9:16 clip\n```\n\n**3. Run the upload in dry-run.** No network call is made; the tool returns the exact job and result it would publish, so an agent can validate metadata before going live:\n\n```bash\nyoutube-shorts-agent upload-short \\\n  --video ./short.mp4 \\\n  --title \"Agent-first Shorts upload\" \\\n  --caption-file copy.txt \\\n  --tags ai,agents \\\n  --duration 24\n```\n\n```json\n{\n  \"ok\": true,\n  \"dry_run\": true,\n  \"job\": {\n    \"id\": \"youtube_1780082215631\",\n    \"platform\": \"youtube\",\n    \"status\": \"queued\",\n    \"createdAt\": \"2026-05-29T19:16:55.631Z\",\n    \"caption\": \"Launching the agent-first Shorts uploader.\\n#shorts #ai #agents\",\n    \"targetUrl\": \"\",\n    \"mediaPaths\": [\"./short.mp4\"],\n    \"metadata\": {\n      \"title\": \"Agent-first Shorts upload\",\n      \"youtube_title\": \"Agent-first Shorts upload\",\n      \"youtube_tags\": [\"ai\", \"agents\"],\n      \"youtube_contains_synthetic_media\": true,\n      \"video_duration_sec\": 24,\n      \"video_aspect_ratio\": \"9:16\"\n    }\n  },\n  \"result\": {\n    \"provider\": \"youtube_official\",\n    \"platformPostId\": \"dryrun_1780082215631\",\n    \"releaseUrl\": \"https://www.youtube.com\",\n    \"raw\": { \"dryRun\": true, \"jobId\": \"youtube_1780082215631\" }\n  }\n}\n```\n\n`platformPostId` is prefixed with `dryrun_` and `releaseUrl` is the YouTube root — both signal that nothing was uploaded. The `id`, `createdAt` and `dryrun_*` values vary per run.\n\n**4. Confirm the channel listing path** (returns an empty list in dry-run):\n\n```bash\nyoutube-shorts-agent list-recent --max-results 5\n```\n\n```json\n{ \"items\": [] }\n```\n\n**Going live.** Configure OAuth (`youtube-shorts-agent auth-url --redirect-uri http://localhost:8787/callback`, then exchange the callback code for tokens), set `YOUTUBE_CLIENT_ID` / `YOUTUBE_CLIENT_SECRET` / `YOUTUBE_ACCESS_TOKEN` / `YOUTUBE_REFRESH_TOKEN` in `.env`, re-run `doctor` until `ready_for_live_upload` is `true`, then set `YOUTUBE_DRY_RUN=false` and re-run the same `upload-short` command.\n\n## MCP\n\n```bash\nyoutube-shorts-mcp\n```\n\nHTTP transport:\n\n```bash\nYOUTUBE_MCP_TRANSPORT=http youtube-shorts-mcp\n```\n\nHermes-style config:\n\n```yaml\nmcp_servers:\n  youtube_shorts:\n    command: npx\n    args: [\"-y\", \"youtube-shorts-agent\"]\n    sampling:\n      enabled: false\n```\n\nRecommended first calls:\n\n1. `youtube_connection_status`\n2. `youtube_privacy_audit`\n3. `youtube_upload_short`\n\n## Agent Surfaces\n\n| Tool | Purpose |\n|---|---|\n| `youtube_agent_manifest` | Install/runtime guidance for Codex, Claude, Cursor, Hermes and OpenClaw |\n| `youtube_connection_status` | OAuth and dry-run readiness without token values |\n| `youtube_privacy_audit` | Upload scope, synthetic media and local file boundaries |\n| `youtube_oauth_authorize_url` | PKCE authorization URL with local session storage |\n| `youtube_upload_short` | Dry-run or live Shorts upload |\n| `youtube_list_recent_videos` | Lightweight channel verification |\n\n## Copy-Paste Agent Prompt\n\n```text\nUse youtube-shorts-agent. First call youtube_connection_status and youtube_privacy_audit.\nIf uploading AI-generated media, keep containsSyntheticMedia=true. Never print token values.\n```\n\n## Configuration\n\nCopy `.env.example` to `.env`. Keep `.env` and `.agent-data/` out of Git.\n\nThe upload tool sets `containsSyntheticMedia=true` by default for AI-generated or AI-edited videos. Override only when that is not true for the asset.\n\n## Safety Model\n\n- OAuth tokens are never returned by CLI or MCP tools.\n- PKCE verifier is stored locally in `.agent-data/`.\n- Live upload requires `YOUTUBE_DRY_RUN=false`.\n- The package uses the official YouTube Data API and does not automate Studio UI.\n\n## Development\n\n```bash\nnpm install\nnpm test\nnpm run check\n```\n\n---\n\n## 📧 Contact \u0026 Support\n\n- 📨 **support@delx.ai** — general questions, integration help, partnerships\n- 🐛 **Bug reports / feature requests** — [GitHub Issues](https://github.com/davidmosiah/youtube-shorts-agent/issues)\n- 🐦 **Updates** — [@delx369](https://x.com/delx369) on X\n- 🌐 **Site** — [wellness.delx.ai](https://wellness.delx.ai)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidmosiah%2Fyoutube-shorts-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavidmosiah%2Fyoutube-shorts-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidmosiah%2Fyoutube-shorts-agent/lists"}