Using wjs-voicedrop
A Claude Code skill: read and write your VoiceDrop account with a single sentence in your terminal.
wjs-voicedrop wraps VoiceDrop's entire backend API into one Claude Code skill. Once installed, just tell Claude "list my VoiceDrop articles", "distill these into a writing style and upload it", "trigger mining", or "check my credit balance" — it handles auth, calls the APIs, and tidies up the results for you. No URLs to remember, no tokens to copy by hand.
What it can do = what VoiceDrop's backend can do: articles (list / read / write / versions), writing-style CLAUDE.md (read / write), photos (list / upload / download), recordings (list / upload / download), mining triggers, credit balance and ledger, share links, publishing drafts to WeChat Official Account. To call the HTTP API directly, see the API Reference.
Prerequisites
- Claude Code installed (
npm i -g @anthropic-ai/claude-code, orcurl -fsSL https://claude.ai/install.sh | bash). - Node ≥ 20 (for the login script — zero dependencies, built-in modules only).
Install the skill
One sentence in Claude Code is all it takes:
Install
https://github.com/jianshuo/claude-skills/tree/main/wjs-voicedrop
Claude will clone the repo and put wjs-voicedrop/ into ~/.claude/skills/wjs-voicedrop/ (all hard-coded paths later on this page assume this location). Once installed, just talk to it in plain language — "list my voicedrop articles", "distill my writing style", "trigger mining", "log in to voicedrop" — or type /wjs-voicedrop. First, let's get login working.
Step 1: Log in (6+4 phone pairing)
The skill ships with a login script, vd-login.mjs, which acts as a "new device" and pairs once with your phone (the existing device). It fetches your account credential to this machine end-to-end encrypted and stores it in ~/.config/voicedrop/credentials (chmod 600). Every call after that reads it automatically.
Requirements: your phone is online, the app is in the foreground, you're logged into the target account, and you're on a version that supports device pairing.
First, check whether you're already logged in
node ~/.claude/skills/wjs-voicedrop/vd-login.mjs status
# logged in → {"ok":true,"scope":"users/anon-…/","live":true}
# not logged in → {"ok":false,…} → follow the two steps below
The two-step handshake
In the phone app, go to Settings → Account and find the 6-character hex short code, then run:
node ~/.claude/skills/wjs-voicedrop/vd-login.mjs start <6-char code>
{"ok":true,"pairingId":…} → your phone will now pop up a 4-digit code.
{"ok":false,"error":"no_match"} → the 6-character code is wrong, or the phone is offline / backgrounded / on an old version.
Enter the 4-digit code shown on your phone:
node ~/.claude/skills/wjs-voicedrop/vd-login.mjs finish <4-digit code>
{"ok":true,"scope":"users/anon-…/"} → logged in, credential saved.
wrong_code + remaining → wrong code, run finish again with the right one (5 attempts / 2 minutes total).
Security: this copies your account's full key to disk — it is not a revocable sub-token. Anyone who gets
~/.config/voicedrop/credentialshas full access to the account, and this machine cannot be revoked individually. Keep the file private and never commit or sync it anywhere readable. To log out:vd-login.mjs logout.
What it can do
| Resource | Operations |
|---|---|
| Articles | List (newest first) · read full text · write (auto-versioned) · version history / undo & redo · delete |
| Writing style | Read / write CLAUDE.md — automatically layered into the prompt when mining articles |
| Photos | List · upload · download (public / private) |
| Recordings | List · upload (auto-triggers mining) · download |
| Actions | Trigger mining · check credit balance and ledger · generate public share links · publish drafts to WeChat Official Account |
Common examples
After logging in, just talk to Claude in plain language; below are the actual commands it runs behind the scenes, so you know what's going on. First, grab the token:
# the credential saved by the 6+4 login
CRED=~/.config/voicedrop/credentials
TOKEN=$(python3 -c "import json;print(json.load(open('$CRED'))['token'])")
List my articles (newest first)
curl -s -H "Authorization: Bearer $TOKEN" https://jianshuo.dev/files/api/articles
Distill a writing style and upload it
Pick 3–6 finished articles → Claude extracts actionable "writing-style rules" → after you preview and confirm, they're written into CLAUDE.md and automatically applied the next time articles are mined. Just say "distill my VoiceDrop writing style".
List recordings (by actual upload time, newest first)
curl -s -H "Authorization: Bearer $TOKEN" https://jianshuo.dev/files/api/list \
| python3 -c "import json,sys
recs=[f for f in json.load(sys.stdin)['files'] if f['name'].endswith('.m4a')]
recs.sort(key=lambda f:f.get('uploaded',''), reverse=True)
[print(f.get('uploaded',''),f['name']) for f in recs]"
Sort by uploaded (R2 upload time), not by filename — the timestamp baked into a filename is not necessarily a reliable clock.
Trigger mining now
curl -s -X POST -H "Authorization: Bearer $TOKEN" https://jianshuo.dev/agent/mine/trigger
Check credit balance / ledger
curl -s -H "Authorization: Bearer $TOKEN" https://jianshuo.dev/agent/usage/balance
curl -s -H "Authorization: Bearer $TOKEN" "https://jianshuo.dev/agent/usage/ledger?limit=50"
Two ways to authenticate
| Method | Whose data | How to get it |
|---|---|---|
| 6+4 device pairing | The user's own | Self-service login above (recommended) |
| App temporary token | The user's own | App Settings → Account → Copy |
Both resolve to the same user and can only access that user's own data; see the API Reference for details.