Skip to main content
Glama
leanhduy-iuh

tiktok-uploader-mcp

by leanhduy-iuh
README.md
# tiktok-uploader-mcp

> MCP server + CLI để **đóng gói (bundle)** TikTok photo carousel uploads.
> Chuẩn bị folder ảnh + caption + manifest cho upload thủ công qua app
> mobile.

[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Tests](https://img.shields.io/badge/tests-22%20passing-brightgreen.svg)](#testing)

## Tại sao cần repo này?

TikTok **chỉ cho upload photo carousel (slide ảnh) qua app mobile**, không qua
web PC (đã verify: TikTok VN redirect `tiktok.com/creator-center/upload` →
`tiktokstudio/upload` chỉ có "Select Video", không có Photo mode).

Repo này giải quyết bằng cách **đóng gói sẵn** ảnh + caption + manifest + README
hướng dẫn thành 1 bundle, bạn copy vào điện thoại rồi upload qua app TikTok
(nhanh, ~2 phút/post).

## Tính năng

- ✅ **Bundle folder ảnh + caption** thành package phone-ready.
- ✅ **4 MCP tools** tích hợp Antigravity / Claude Desktop / Cursor.
- ✅ **CLI wrappers** cho agent auto-approve (`.cmd` on Windows).
- ✅ **caption.txt** paste-ready, **manifest.json** có SHA-256 hash.
- ✅ **README.txt** hướng dẫn upload từng bước (tiếng Việt).
- ✅ **ZIP optional** để dễ transfer sang điện thoại.
- ✅ **Cross-platform** Windows/Linux/macOS (không cần Playwright browser).
- ✅ **Error playbook** E1-E5 với retry protocol.
- ✅ **22 unit tests** validation + end-to-end.

## Cài đặt

### Yêu cầu

- Python 3.11+
- pip

### Install

```powershell
git clone https://github.com/leanhduy-iuh/tiktok-uploader-mcp.git
cd tiktok-uploader-mcp
pip install -e .
```

## Sử dụng

### CLI (qua wrapper)

```powershell
# Tạo bundle
.\wrappers\run_bundle.cmd `
    --images-dir "C:\path\to\slides" `
    --caption "Hook...

Body text.

CTA." `
    --hashtags sinhVienIT thuthuatvat `
    --series-slug office-real-vs-fake `
    --part-slug phan-1

# Liệt kê bundle đã tạo
.\wrappers\run_list.cmd
```

### MCP server

Thêm vào config MCP client của bạn:

```json
{
  "mcpServers": {
    "tiktok-uploader": {
      "command": "uv",
      "args": [
        "tool", "run", "--from",
        "git+https://github.com/leanhduy-iuh/tiktok-uploader-mcp.git",
        "tiktok-uploader-mcp"
      ]
    }
  }
}
```

4 tools:
- `tiktok_create_bundle(images_dir, caption, hashtags=[], series_slug, part_slug, make_zip=True)`
- `tiktok_list_bundles()`
- `tiktok_get_bundle(bundle_id)`
- `tiktok_delete_bundle(bundle_id)`

### Output structure

```
bundles/
├── <series>_<part>_<timestamp>/
│   ├── images/
│   │   ├── 01.png
│   │   ├── 02.png
│   │   └── ...
│   ├── caption.txt      ← Paste vào TikTok
│   ├── manifest.json    ← Metadata (hashes, timestamps)
│   └── README.txt       ← Hướng dẫn upload từng bước
└── <series>_<part>_<timestamp>.zip
```

## Upload lên TikTok (trên điện thoại)

Sau khi có bundle:

1. **Copy** bundle folder (hoặc ZIP) vào điện thoại qua:
   - Google Drive (recommend — đã sync sẵn với `pdf_to_images.py`).
   - USB cable.
   - AirDrop / Quick Share.

2. **Giải nén** ZIP nếu cần.

3. **Mở app TikTok** → bấm **[+]** → **[Tải lên]** → tab **[Ảnh]**.

4. **Chọn tất cả ảnh** trong `images/` (theo thứ tự 01, 02, ...).

5. **Bấm [Tiếp]** → dán nội dung `caption.txt` vào ô **[Chú thích]**.

6. **Bấm [Đăng]**.

Chi tiết trong file `README.txt` đi kèm mỗi bundle.

## Architecture

```
┌──────────────────────────────────────────────────────────┐
│                      MCP Client                           │
│            (Antigravity / Claude / Cursor)                │
└──────────────────────┬───────────────────────────────────┘
                       │ stdio JSON-RPC
                       ▼
┌──────────────────────────────────────────────────────────┐
│              tiktok-uploader-mcp (FastMCP)                │
│                                                          │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌─────────┐  │
│  │ create_  │  │ list_    │  │ get_     │  │ delete_ │  │
│  │ bundle   │  │ bundles  │  │ bundle   │  │ bundle  │  │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬────┘  │
│       │             │              │              │       │
│       ▼             ▼              ▼              ▼       │
│  ┌──────────────────────────────────────────────────┐    │
│  │  bundler.py                                       │    │
│  │  ├── collect_images()   validate_caption()        │    │
│  │  ├── build_full_caption()  make_bundle_id()       │    │
│  │  ├── create_bundle()    list_bundles()            │    │
│  │  ├── get_bundle()       delete_bundle()           │    │
│  │  └── BundleManifest dataclass                     │    │
│  └──────────────────────────────────────────────────┘    │
│                       │                                  │
│                       ▼                                  │
│              bundles/<bundle_id>/                         │
│              ├── images/    caption.txt                   │
│              ├── manifest.json    README.txt              │
│              └── <bundle_id>.zip                          │
└──────────────────────────────────────────────────────────┘
                       │ Copy to phone
                       ▼
              TikTok mobile app
```

## Testing

```powershell
pip install -e ".[dev]"
pytest tests/
```

22 unit tests cover:
- Caption validation (empty, too long, hashtag count, strip leading #).
- Image collection (mixed exts, sorted, unsupported, count limits).
- Bundle ID generation (special chars, slug formatting).
- End-to-end bundle creation (with/without ZIP, manifest correctness).
- List / get / delete lifecycle.

## Roadmap

- [ ] Auto-copy bundle to Google Drive folder (giảm manual step).
- [ ] Generate QR code linking to bundle (scan từ điện thoại).
- [ ] Caption templates (per audience type: student/office/dev).
- [ ] Multi-account support (different bundle dirs per TikTok account).
- [ ] Upload tracking (mark bundle as "posted" + post URL).

## Why not auto-upload?

Đã thử 3 hướng trước khi pivot sang bundle workflow:

1. **Playwright qua web PC**: TikTok VN redirect tới TikTok Studio chỉ có
   "Select Video", không có Photo mode. (Đã verify với 6 URL khác nhau.)
2. **TikTok Content Posting API**: Yêu cầu đăng ký TikTok for Developers +
   review process dài. Photo carousel API chưa stable.
3. **ADB automation trên app Android**: Khả năng cao nhưng cần thiết bị test
   Android + risk break khi TikTok update app.

Bundle workflow **đơn giản, ổn định, không phụ thuộc TikTok UI changes** —
chỉ là tổ chức file.

## FAQ

**Q: Tại sao không tự upload luôn?**

A: TikTok VN không hỗ trợ photo carousel upload qua web. Bundle là cách tiếp
cận务实 — chuẩn bị sẵn mọi thứ, user chỉ paste + click.

**Q: Có thể tự động copy sang Google Drive không?**

A: Có, xem roadmap. Hiện tại copy thủ công (nhưng nhanh — chỉ 1 thao tác).

**Q: Bundle lưu ở đâu?**

A: Mặc định `bundles/` ở repo root. Có thể override qua `--bundles-dir`.

**Q: Có support Linux/macOS không?**

A: Code Python thuần, không phụ thuộc Playwright nên chạy được. Wrapper `.cmd`
chỉ cho Windows — PR `.sh` cho Linux/macOS welcome.

## Contributing

PR welcome. Branch `main` = stable, branch `dev` = WIP.

## License

MIT © [Duy Le](https://github.com/leanhduy-iuh)

TDQS

A4.3/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: create, delete, get, and list bundles. No overlap exists, and the descriptions make it easy to differentiate.

Naming Consistency5/5

All tools follow the consistent pattern tiktok_verb_noun (e.g., tiktok_create_bundle, tiktok_list_bundles). Naming is predictable and uniform.

Tool Count5/5

Four tools is well-scoped for the domain of bundle management. Each tool serves a necessary CRUD-like function without being excessive or too sparse.

Completeness5/5

The tool set covers all essential operations for bundle lifecycle: create, read (get/list), and delete. No obvious gaps given the manual upload workflow.

Maintenance

ActivityInactive
ResponsivenessNo issues