# Postiz Media Manager - MCP Server
MCP (Model Context Protocol) Server สำหรับจัดการและเคลียร์ media ที่ไม่ถูกใช้งานใน Postiz
## คุณสมบัติหลัก
- **ดึงรายการ Media IDs ที่ถูกป้องกัน** - media ที่ถูกใช้ในโพสต์สถานะ draft, scheduled, หรือ queued
- **ค้นหา Orphan Media** - media ที่ไม่ได้ถูกใช้ในโพสต์อนาคตใด ๆ
- **ลบ Media อัตโนมัติ** - พร้อม dry-run mode เพื่อดูผลลัพธ์ก่อนลบจริง
- **สถิติการใช้งาน Media** - แสดงจำนวน media ทั้งหมด, ที่ถูกป้องกัน, และ orphan
## โครงสร้างโปรเจกต์
```
mcp-postiz/
├── src/
│ ├── types.ts # TypeScript type definitions
│ ├── config.ts # Configuration management
│ ├── postizClient.ts # Postiz API client (PLACEHOLDER endpoints)
│ ├── mediaService.ts # Business logic for media management
│ └── mcpServer.ts # MCP server implementation
├── package.json
├── tsconfig.json
├── .env.example
└── README.md
```
## การติดตั้ง
### 1. Clone และติดตั้ง dependencies
```bash
npm install
```
### 2. ตั้งค่า Environment Variables
สร้างไฟล์ `.env` จาก `.env.example`:
```bash
cp .env.example .env
```
แก้ไขไฟล์ `.env`:
```env
# Base URL ของ Postiz API
POSTIZ_BASE_URL=https://api.postiz.app
# API Token สำหรับ authentication
POSTIZ_API_TOKEN=your_actual_api_token_here
# Log level (debug, info, warn, error)
LOG_LEVEL=info
```
### 3. ปรับแต่ง API Endpoints (สำคัญ!)
**⚠️ สำคัญมาก:** ไฟล์ `src/postizClient.ts` ใช้ **PLACEHOLDER endpoints**
คุณต้องแก้ไข endpoints ให้ตรงกับ Postiz API จริงของคุณ:
- `GET /v1/posts` → แก้เป็น endpoint จริงสำหรับดึงรายการโพสต์
- `GET /v1/media` → แก้เป็น endpoint จริงสำหรับดึงรายการ media
- `DELETE /v1/media/:id` → แก้เป็น endpoint จริงสำหรับลบ media
ตรวจสอบเอกสาร API ของ Postiz และแก้ไขใน `src/postizClient.ts`
### 4. ปรับแต่ง Media Field Extraction (สำคัญ!)
ใน `src/mediaService.ts` ฟังก์ชัน `extractMediaIds()` ตรวจสอบหลายฟิลด์ที่อาจมี media IDs:
```typescript
// ปรับแต่งตามโครงสร้าง API จริงของคุณ
- post.mediaIds
- post.files
- post.attachments
- post.media
```
แก้ไขให้ตรงกับฟิลด์ที่ Postiz API ของคุณใช้จริง
### 5. Build โปรเจกต์
```bash
npm run build
```
### 6. เริ่มใช้งาน MCP Server
```bash
npm start
```
## MCP Tools ที่มีให้ใช้งาน
### 1. `postiz_list_future_protected_media_ids`
ดึงรายการ media IDs ที่ห้ามลบ (ถูกใช้ในโพสต์อนาคต)
**Input:**
```json
{
"statuses": ["draft", "scheduled", "queued"] // Optional
}
```
**Output:**
```json
{
"protectedMediaIds": ["media-id-1", "media-id-2", "media-id-3"],
"count": 3
}
```
### 2. `postiz_list_all_media`
ดึงรายการ media ทั้งหมด
**Input:**
```json
{
"limit": 100 // Optional
}
```
**Output:**
```json
{
"items": [
{
"id": "media-id-1",
"url": "https://example.com/media1.jpg",
"createdAt": "2025-01-01T00:00:00Z",
"deleted": false,
"deletedAt": null
}
],
"total": 150,
"returned": 100
}
```
### 3. `postiz_find_orphan_media`
ค้นหา media ที่ไม่ถูกใช้ในโพสต์อนาคต (orphan media)
**Input:**
```json
{
"limit": 50 // Optional
}
```
**Output:**
```json
{
"items": [
{
"id": "orphan-media-1",
"url": "https://example.com/orphan1.jpg",
"createdAt": "2024-12-01T00:00:00Z"
}
],
"totalCandidates": 25
}
```
### 4. `postiz_cleanup_orphan_media`
ลบ orphan media (พร้อม dry-run mode)
**Input:**
```json
{
"dryRun": true, // true = ไม่ลบจริง, false = ลบจริง (default: false)
"limit": 10 // Optional: จำกัดจำนวนที่จะลบ
}
```
**Output:**
```json
{
"totalCandidates": 10,
"deletedCount": 8,
"failedCount": 2,
"deletedIds": ["media-1", "media-2", "media-3"],
"failedIds": [
{
"id": "media-4",
"reason": "Permission denied"
}
]
}
```
### 5. `postiz_get_media_stats`
ดูสถิติการใช้งาน media
**Input:**
```json
{}
```
**Output:**
```json
{
"totalMedia": 1000,
"protectedMedia": 750,
"orphanMedia": 250
}
```
## การใช้งานแนะนำ
### ขั้นตอนการเคลียร์ media ที่ปลอดภัย:
1. **ดูสถิติก่อน:**
```json
Tool: postiz_get_media_stats
```
2. **ทดสอบด้วย dry-run:**
```json
Tool: postiz_cleanup_orphan_media
Input: { "dryRun": true, "limit": 10 }
```
3. **ตรวจสอบรายการที่จะลบ:**
```json
Tool: postiz_find_orphan_media
Input: { "limit": 10 }
```
4. **ลบจริง (เริ่มจากจำนวนน้อย):**
```json
Tool: postiz_cleanup_orphan_media
Input: { "dryRun": false, "limit": 10 }
```
5. **ตรวจสอบผลลัพธ์และทำซ้ำ**
## Logic การทำงาน
### Orphan Media คืออะไร?
Media จะถือว่าเป็น "orphan" (ไม่ถูกใช้งาน) เมื่อ:
1. **ไม่ได้ถูกอ้างอิงในโพสต์ใด ๆ** ที่มีสถานะเป็น:
- `draft` (แบบร่าง)
- `scheduled` (กำหนดเวลาไว้)
- `queued` (อยู่ในคิว)
2. **ยังไม่ถูกลบ** (`deleted = false` หรือ `deletedAt = null`)
### ทำไมไม่ใช้วันที่เป็นเกณฑ์?
โปรแกรมนี้ **ไม่ได้ใช้วันที่** เป็นเกณฑ์ในการลบ เพราะ:
- Media ที่เก่าแต่ยังถูกใช้ในโพสต์ scheduled ไว้ → **ไม่ลบ**
- Media ที่ใหม่แต่ไม่ถูกใช้ในโพสต์ใด ๆ → **ลบได้**
วิธีนี้ปลอดภัยกว่าและแม่นยำกว่าการใช้วันที่
## การ Config MCP Client
เพิ่ม server นี้ใน MCP client configuration (เช่น Claude Desktop):
```json
{
"mcpServers": {
"postiz-media-manager": {
"command": "node",
"args": ["/path/to/mcp-postiz/dist/mcpServer.js"],
"env": {
"POSTIZ_BASE_URL": "https://api.postiz.app",
"POSTIZ_API_TOKEN": "your_token_here"
}
}
}
}
```
## Development
### Build และ Watch Mode
```bash
# Build แบบปกติ
npm run build
# Watch mode (auto-rebuild on change)
npm run dev
# Clean build artifacts
npm run clean
```
### ทดสอบ
1. ตรวจสอบว่า TypeScript compile ผ่าน:
```bash
npm run build
```
2. ทดสอบรัน server:
```bash
npm start
```
3. ทดสอบเชื่อมต่อกับ MCP client
## Error Handling
- ทุก API call มี try-catch และ error logging
- การลบ media ที่ล้มเหลวจะถูกบันทึกใน `failedIds` ไม่ทำให้กระบวนการทั้งหมดหยุด
- Axios interceptor จัดการ HTTP errors โดยอัตโนมัติ
## คำเตือนและข้อควรระวัง
⚠️ **สำคัญมาก:**
1. **ทดสอบด้วย `dryRun: true` เสมอก่อนลบจริง**
2. **สำรองข้อมูลก่อนรัน cleanup ครั้งแรก**
3. **ตรวจสอบ endpoint URLs ให้ถูกต้อง** - ตัวอย่างใน code เป็น placeholder เท่านั้น
4. **ตรวจสอบฟิลด์ media ให้ตรงกับ API** - แก้ `extractMediaIds()` ให้เหมาะสม
5. **เริ่มต้นด้วย `limit` น้อย ๆ** เพื่อทดสอบการทำงาน
## License
MIT
## ผู้พัฒนา
สร้างด้วย TypeScript + MCP SDK สำหรับจัดการ media ใน Postiz อย่างมีประสิทธิภาพ