# Threads Post Draft

> 주제를 Threads 게시글 초안으로 작성합니다. 저장된 문체 프로필이 있으면 자동으로 적용합니다. 초안은 발행 전에 ⟨한국어 감사 3단⟩(ai-slop-reviewer → korean-spell-check → korean-humanize)을 반드시 통과하며, 감사를 통과한 최종본을 사용자가 AskUserQuestion 으로 승인해야 Graph API 로 발행합니다 — 큐·예약·상태머신 없이 세션 안에서 직접 발행합니다. 예약·정기 발행은 Claude Cowork 이 담당합니다. 다음과 같은 요청 시 사용하세요: - "이 주제로 Threads 포스트 작성해줘" - "Threads에 올릴 글 초안 만들어줘" - "이 뉴스를 Threads용으로 요약해줘" - "블로그 글을 Threads 포스트로 변환해줘" - "내 문체로 초안 작성해줘" (저장된 프로필 자동 적용) - "이 초안 그대로 Threads에 올려줘" (감사 3단 → 승인 → 즉시 발행) [책임 경계] vs 형제 스킬: 초안 작성(저장된 문체 프로필 적용 포함)·발행 전 한국어 감사·승인 후 즉시 발행을 담당합니다. 문체 *분석·저장* 은 threads-style-learn, 멀티 채널(Facebook/X) 포맷은 threads-multichannel, 이미지/비디오 발행은 MCP 도구(threads_publish_image, threads_publish_video)를 직접 사용하세요. 예약·정기 발행은 Claude Cowork 에게 맡깁니다.

- Skill: `modu-ai/threads-post-draft` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add modu-ai/threads-post-draft`
- Raw SKILL.md: https://api.skillmd.com/api/skills/modu-ai/threads-post-draft/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- Author: modu-ai (https://skillmd.com/u/modu-ai)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/modu-ai/threads-post-draft

---


# Threads 초안 작성·직접 발행 (threads-post-draft)

## 개요

주제를 받아 Threads 최적화 초안을 작성하고, **발행 전에 한국어 품질을 감사한 뒤**, 감사를 통과한 최종본을 사용자가 승인하면 **즉시** Graph API 로 발행합니다. 큐·예약·상태머신은 없습니다 — 세션 안에서 한 흐름으로 작성 → 감사 → 승인 → 발행합니다.

발행은 공개된 계정에 되돌릴 수 없이 나가는 일입니다. 맞춤법이 틀렸거나 AI 티가 나는 한국어가 사업 계정으로 나가면 그대로 남습니다 — 그래서 감사가 선택이 아니라 필수 단계입니다.

> 예약·정기 발행(예: "매주 수요일 12시")은 Claude Cowork 이 담당합니다. 본 스킬은 즉시 발행만 합니다.

## 트리거 키워드

Threads, 스레드, 초안, 작성, 발행, 포스트, 게시글, 주제, 변환

## 워크플로우

### 0단계: 문체 적용 (있으면)

초안 작성 *전* 에 저장된 문체 프로필이 있는지 확인합니다:

```python
threads_style_load(path=None)
# → {path, exists: bool, profile: <markdown or None>}
```

- **프로필이 있으면** (`exists: True`): 반환된 마크다운의 차원(말투·문장 길이·오프닝·클로징·이모지·시그니처 구절 등) 을 아래 1단계 초안 작성에 반영합니다. 프로필은 `threads-style-learn` 스킬이 만들어 저장한 것입니다.
- **프로필이 없으면** (`exists: False`): 브랜드 톤이 지정됐으면 그것을, 아니면 합리적 기본 톤(캐주얼 대화체) 으로 작성합니다. 프로필 없어도 초안 작성은 정상 동작합니다.

> 프로필을 새로 만들거나 갱신하려면 `threads-style-learn` 스킬을 먼저 호출하세요.

### 1단계: 주제 분석 및 초안 작성

사용자의 주제/블로그 글/뉴스를 분석하여 Threads 최적화 초안을 작성합니다:

- **길이 제한**: 최대 500 UTF-8 바이트 (아래 바이트 계산 규칙 참조)
- **구조**: 짧은 문장, 대화 유도, 핵심 메시지 1-2개
- **톤**: 브랜드 톤 일치 (지정 시), 기본값은 캐주얼한 대화체
- **토픽 태그**: 선택사항, 최대 1개 (Threads 알고리즘 — 토픽 태그는 노출에 도움)
- **링크**: 선택사항, 최대 5개 (프리뷰 자동 생성)

### 2단계: 한국어 감사 3단 (발행 전 필수)

초안을 사용자에게 보여주기 **전에** ⟨한국어 감사 3단⟩을 통과시킵니다. 순서는 고정입니다:

```
  moai-coworker:ai-slop-reviewer     1차 일반 슬롭 정리
→ moai-writer:korean-spell-check     2차 맞춤법 — 제안 수집 (미공개 정보가 섞였으면 건너뜀)
→ moai-writer:korean-humanize        3차 정밀 윤문 + 맞춤법 반영 + Phase 6 최종 검수
```

- **[HARD] 감사가 승인보다 앞이다.** 승인 뒤에 문장을 고치면, 사용자가 승인한 글과 발행되는 글이 달라집니다. 사용자는 **발행될 바로 그 문장**을 보고 승인해야 합니다.
- **[HARD] `korean-humanize`가 마지막이다.** Phase 6 최종 검수가 의미 보존을 판정한 **바로 그 산출물**이 발행됩니다. 검수 뒤에 문장을 고치는 단계를 두지 않습니다.
- **[HARD] 장르는 `카피`다.** SNS 게시글은 산문이 아니라 카피입니다. `장르: 카피`(모드도 카피로 자동 추론)로 호출하세요. 산문 기준을 들이대면 정상적인 헤드라인 리라이트가 변경률 게이트에 걸려 중단됩니다.
- **[HARD] 판정이 `hold_and_report`면 발행하지 않는다.** 사유를 사용자에게 그대로 보여주고, 1단계로 돌아가 다시 씁니다.
- **[HARD] 감사 뒤에 바이트 수를 다시 센다.** 감사가 문장을 고치므로 초안 시점의 바이트 수는 무효입니다. 500바이트 판정은 **최종본** 기준입니다.

**`korean-spell-check`의 외부 전송에 관하여**: 이 단계는 원문을 외부 서비스(`nara-speller.co.kr`)로 보냅니다. Threads 게시글은 어차피 공개될 글이므로 보통은 문제가 없습니다. 다만 초안에 **아직 공개되지 않은 정보**(미발표 출시일·비공개 실적 수치·계약 상대방 등)가 섞였다면 이 단계를 건너뜁니다 — 생략해도 `korean-humanize`가 맞춤법을 함께 봅니다.

비텍스트(이미지·링크 자체)는 감사 대상이 아닙니다.

### 3단계: 최종본 확인 (승인 게이트)

감사를 통과한 **최종본**을 사용자에게 보여드리고 승인을 받습니다. **승인 없이는 발행하지 않습니다** ("자동 아닌 자율").

- **[HARD] 승인은 사용자에게 승인서를 그대로 보여주고 명시적 응답을 받는다.** 산문으로 "괜찮으세요?"라고 묻지 않습니다 — 발행은 되돌릴 수 없으므로 사용자가 명시적으로 고르게 합니다.
- **[HARD] 요약이 아니라 발행될 문장 그대로를 보여준다.** 최종본 전문 + 최종 바이트 수 + 토픽 태그/링크를 함께 제시하고, 감사 3단에서 무엇이 바뀌었는지 한 줄로 알려드립니다.
- 사용자가 수정을 요청하면 1단계로 돌아가 다시 쓰고, **감사 3단을 다시 통과시킨 뒤** 재승인을 받습니다.
- 사용자가 승인하면 4단계로 갑니다.

선택지는 이렇게 구성합니다:

| 선택지 | 뜻 |
|--------|-----|
| 이대로 발행 (권장) | 최종본 그대로 `threads_publish_text` 호출 |
| 수정 요청 | 1단계로 복귀 → 감사 3단 재통과 → 재승인 |
| 발행 취소 | 아무것도 발행하지 않고 종료 |

### 4단계: 즉시 발행 (승인 시)

승인된 최종본을 `threads_publish_text` 도구로 **즉시** Graph API 발행합니다:

```python
threads_publish_text(text="<승인된 최종본>")
# → {media_id, container_id, permalink_hint, note}
```

- 텍스트 전용 발행만 본 스킬이 담당합니다.
- 이미지/비디오 포스트는 `threads_publish_image(text, image_url)` / `threads_publish_video(text, video_url)` 도구를 직접 호출하세요. **[HARD] 이때 승인 화면에는 감사를 마친 본문뿐 아니라 실제로 넘어가는 인자 전부**(미디어 종류·`image_url`/`video_url` 원문·발행 계정)**를 그대로 보여줍니다.** 본문만 확인시키고 미디어 URL을 요약하거나 생략하면, 사용자는 어떤 이미지가 올라가는지 모르는 채 승인하게 됩니다.
- 자격증명(`THREADS_ACCESS_TOKEN`, `THREADS_USER_ID`) 이 미설정이면 `setup_required` 에러를 반환합니다 — 서버는 크래시하지 않습니다. 발급 절차는 `mcp-servers/moai-mcp-threads-poster/CONNECTORS.md` 참조.
- **[HARD] 실패해도 자동 재시도하지 않는다.** 발행 도구가 애매하게 실패하면(타임아웃·응답 없음) **재시도하지 않고 멈춥니다.** 성공 신호가 없다는 것은 발행되지 않았다는 증거가 아니며, 확인 없는 재시도는 같은 글을 두 번 올립니다. 발행은 컨테이너 생성 → 발행 2단계라, 1단계만 성공한 상태에서 재시도하면 중복 컨테이너가 남습니다.
- **[HARD] 이 서버에는 발행 여부를 조회할 도구가 없다.** `threads_get_profile`은 `username`·`id`·`followers_count`·`profile_picture_url`만 반환합니다(`server.py:281`) — 타임라인도 게시글 상태도 없습니다. 나머지 도구도 발행·프로필·문체 저장뿐이라 게시 여부를 되물을 수단이 없습니다. 따라서 애매한 실패 시에는 **사용자에게 Threads 앱/웹에서 직접 확인해 달라고 요청**하고, 올라가지 않았다는 사용자의 확인을 받은 뒤에만 다시 발행합니다. 스킬이 혼자 판단하지 않습니다.

> 발행은 세션 안에서 즉시 일어납니다. 백그라운드 자동 발행은 없습니다. 예약이 필요하면 Claude Cowork 에게 맡기세요.

## 바이트 계산 규칙 (500 UTF-8 바이트 제한)

Threads 텍스트 제한은 **문자 수가 아니라 UTF-8 바이트 수**입니다:

| 문자 타입 | 바이트 수 | 예시 |
|----------|----------|------|
| ASCII (영문, 숫자, 공백, 일반 기호) | 1바이트 | `A`, `1`, ` `, `?` |
| 한글 (가-힣) | 3바이트 | `한`, `글`, `🇰🇷` (국기 깃발 이모지 제외) |
| 이모지 (대부분) | 4바이트 | `😀`, `🎉`, `🔥` |
| 국기 깃발 이모지 (🇰🇷, 🇺🇸) | 8바이트 | 두 개의 regional indicator로 구성 |

**계산 예시**:
- `"안녕하세요!"` = 한글 5글자 × 3바이트 + `!` 1바이트 = **16바이트**
- `"Hello! 😀"` = ASCII 7글자 × 1바이트 + 이모지 4바이트 = **11바이트**
- `"🇰🇷 Korea"` = 국기 8바이트 + 공백 1바이트 + ASCII 5바이트 = **14바이트**

**초안 작성 시 바이트 계산**:
초안을 작성한 후, 클로드에게 "이 초안 몇 바이트야?"라고 물어보면 UTF-8 바이트 수를 계산해 드립니다.

## 출력 형식

감사 3단을 마친 뒤, 승인 요청은 이 형식으로 냅니다 (선택은 `AskUserQuestion`):

```markdown
## 발행 최종본 (승인 요청)

<감사를 통과한 최종본 — 발행될 문장 그대로>

**바이트 수**: N / 500  ← 감사 후 다시 센 값
**토픽 태그**: (선택사항) #태그이름
**링크**: (선택사항) URL

**감사 3단 결과**: 슬롭 N건 정리 · 맞춤법 N건 반영(또는 미공개 정보로 생략) · 윤문 판정 pass
```

승인 후 발행이 끝나면:

```markdown
## 발행 완료

**media_id**: ...
**permalink**: https://www.threads.net/@<username>/post/<media_id>
```

## 주의사항

| 상황 | 대응 |
|------|------|
| 500바이트 초과 시 | 초안을 줄이거나 두 개의 포스트로 분할 제안 |
| 토픽 태그 2개 이상 요청 시 | 1개만 권장 (Threads 알고리즘) |
| 링크 6개 이상 요청 시 | 5개로 제한 (Threads 규격) |
| 이미지/비디오 포함 요청 시 | `threads_publish_image`, `threads_publish_video` 도구 직접 호출 제안 |
| 브랜드 톤 미지정 시 | 업종·타겟 기반 캐주얼 톤 초안 제안 후 확인 |
| `setup_required` 에러 | `THREADS_ACCESS_TOKEN`, `THREADS_USER_ID` 환경변수 설정 (CONNECTORS.md 참조) |
| 예약·정기 발행 요청 시 | Claude Cowork 에게 맡길 것을 안내 (본 스킬은 즉시 발행만) |
| 감사 3단에서 `hold_and_report` 판정 | 발행하지 않음. 사유를 그대로 보여주고 1단계로 복귀 |
| 초안에 미공개 정보가 섞임 | `korean-spell-check` 생략 (외부 전송) — 생략 사실을 결과에 적음 |
| 감사 후 500바이트 초과 | 최종본 기준으로 다시 판정 — 줄이거나 두 포스트로 분할 제안 |
| 발행 도구가 애매하게 실패 | 자동 재시도 금지. 실제 발행 여부를 먼저 확인한 뒤 판단 |
| "감사 건너뛰고 바로 올려줘" 요청 | 건너뛰지 않음. 되돌릴 수 없는 공개 발행이라는 점을 알리고 감사 진행 |

## References

| 파일 | 로드 조건 |
|------|-----------|
| references/threads-spec.md | Threads 규격·바이트 계산·토픽 태그·링크 제한 확인 시 |

## 관련 스킬

| 스킬 | 사용 시점 |
|------|----------|
| `threads-style-learn` | 문체 분석·저장 (이 스킨이 초안 작성 시 자동 적용) |
| `threads-multichannel` | 초안을 Threads/Facebook/X 용으로 멀티 채널 포맷 |
| `moai-marketer:content-sns-content` | 브랜드 톤 가이드·채널별 최적화 패턴 |
| `moai-coworker:ai-slop-reviewer` | 감사 3단 1차 — 일반 AI 슬롭 정리 (발행 전 필수) |
| `moai-writer:korean-spell-check` | 감사 3단 2차 — 맞춤법·띄어쓰기 (미공개 정보 시 생략) |
| `moai-writer:korean-humanize` | 감사 3단 3차 — 정밀 윤문 + 최종 검수 (`장르: 카피`, 발행 전 필수·마지막) |

## 이 스킬을 사용하지 말아야 할 때

- 이미지/비디오 포스트 발행: MCP 도구 `threads_publish_image`, `threads_publish_video` 직접 호출
- Facebook/X 용 텍스트 포맷: `threads-multichannel` 스킬
- 문체 분석·저장: `threads-style-learn` 스킬
- 예약·정기 발행: Claude Cowork (본 플러그인은 즉시 발행만)

---

## 발행 전 설정 (최초 1회)

이 스킬을 사용하려면 Threads OAuth 자격증명이 필요합니다. 최초 1회 설정:

**토큰은 `.mcp.json`에 직접 쓰지 마세요.** `.mcp.json`은 저장소에 커밋되는 파일이라,
값을 그대로 넣으면 토큰이 git 이력·diff·배포 패키지에 남습니다. 이 파일에는 **참조만** 둡니다
(저장소의 `.mcp.json`이 이미 이 형태입니다).

```json
{
  "env": {
    "THREADS_ACCESS_TOKEN": "${THREADS_ACCESS_TOKEN}",
    "THREADS_USER_ID": "${THREADS_USER_ID}"
  }
}
```

실제 값은 **운영체제 환경변수**로만 넣습니다. 셸에 따라 형식이 다릅니다.

**macOS / Linux** (bash·zsh):

```bash
export THREADS_ACCESS_TOKEN="<장기 토큰(60일)>"
export THREADS_USER_ID="<Threads 사용자 ID>"
export THREADS_PUBLISH_DELAY="30"   # 선택: 발행 전 대기 시간(초), 기본 30초
```

**Windows** (PowerShell):

```powershell
$env:THREADS_ACCESS_TOKEN = "<장기 토큰(60일)>"
$env:THREADS_USER_ID = "<Threads 사용자 ID>"
$env:THREADS_PUBLISH_DELAY = "30"   # 선택: 발행 전 대기 시간(초), 기본 30초
```

발급 절차: `mcp-servers/moai-mcp-threads-poster/CONNECTORS.md` 참조 (브라우저 인가 → 단기 토큰 → 장기 토큰 교환)

**동작 확인**: `threads_get_profile` 도구 호출 → 프로필 정보 반환되면 연동 성공.

