Back to skills
SKILL.md
Mod Actions Nocp
ASecurityComprehensive moderation toolkit: user actions (ban/mute/DM), strike system, image moderation, report handling, generation moderation, content/training moderation, NCMEC/CSAM reporting, and Creator Shop purchase refunds. All via Civitai tRPC API.
- 4 stars
- 0 votes
- 0 copies
- 0 views
- Added November 11, 2026
Works with
Security analysis
100/100npx -y skills add Frank-Masciopinto/ironheights --skill mod-actions-nocp --agent claude-codeAre you the author of Mod Actions Nocp?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/frank-masciopinto-mod-actions-nocp)---
name: mod-actions
description: "Comprehensive moderation toolkit: user actions (ban/mute/DM), strike system, image moderation, report handling, generation moderation, content/training moderation, NCMEC/CSAM reporting, and Creator Shop purchase refunds. All via Civitai tRPC API."
---
# Moderator Actions
Comprehensive moderation toolkit for Civitai. Covers user actions, strike management, image moderation, report handling, generation moderation, content/training moderation, NCMEC/CSAM reporting, and Creator Shop purchase refunds.
All scripts use the Civitai tRPC API with Bearer token authentication, ensuring actions go through the proper service layer with full side effects.
## Setup
1. Copy `.env-example` to `.env` in this skill directory
2. Add your Civitai API key (must belong to a moderator account)
3. Optionally set the API URL (defaults to production)
```bash
# Edit .env and add your API key
```
**Important:** The API key must belong to a user with moderator privileges.
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `CIVITAI_API_KEY` | Yes | - | Your Civitai API key |
| `CIVITAI_API_URL` | No | `https://civitai.com` | API base URL |
---
## Skill Files
| File | Domain | Commands |
|------|--------|----------|
| `query.mjs` | User moderation | user, ban, mute, leaderboard, remove-content, dm, inbox, thread, creator-program-ban, end-buzz-membership |
| `strikes.mjs` | Strike system | get-user, standings, list, create, void |
| `images.mjs` | Image moderation | review-queue, review-counts, moderate, tos-violation, rescan, report-csam, poi-tags, user-images, rating-requests, ingestion-errors, resolve-ingestion, downleveled, pending-ingestion, toggle-flag |
| `reports.mjs` | Report handling | list, set-status, bulk-status, update, appeals, appeal-details, resolve-appeal |
| `generation.mjs` | Generation moderation | flagged-consumers, flagged-reasons, consumer-strikes, review-strikes, user-generations, restrictions, resolve-restriction, allowlist-add, debug-audit, todays-counts, suspicious-matches |
| `content.mjs` | Content moderation | models, flagged-models, resolve-flagged, model-versions, rescan-model, restore-model, toggle-cannot-promote, toggle-cannot-publish, articles, mod-rule |
| `model3ds.mjs` | 3D Models moderation | list, get, files, unpublish, delete, restore, set-nsfw-level, toggle-tos, toggle-poi, toggle-minor, toggle-nsfw, toggle-unlisted |
| `csam.mjs` | NCMEC/CSAM reporting | reports, stats, image-resources, create-report |
| `shop.mjs` | Creator Shop | refund |
---
## query.mjs — User Moderation
```bash
node .claude/skills/mod-actions/query.mjs <command> [options]
```
| Command | Description |
|---------|-------------|
| `user <id\|username>` | Look up user info |
| `ban <id\|username>` | Toggle ban status |
| `mute <id\|username>` | Toggle mute status |
| `leaderboard <id\|username> <true\|false>` | Set leaderboard eligibility |
| `remove-content <id\|username>` | Remove all user content (DESTRUCTIVE) |
| `dm <id\|username>` | Message the user as the shared **Civitai Moderation** account (requires `--message`; needs the `user.message.asCivitai` permission). The user sees only that account and can reply; you are recorded as the sender. Prints an idempotency key first: if the response is lost, rerun with `--key <key>` and it sends at most once. Refused while another moderator holds the thread's claim, or when the user already has several unanswered messages from the account in 24 h. `--as-self` sends from your own account instead (the old behaviour). |
| `inbox` | Civitai Moderation threads whose last message is the user's, oldest first (`--all`: every thread, newest first) |
| `thread <id\|username>` | A user's Civitai Moderation thread, naming the moderator behind each message, and who holds its claim |
| `creator-program-ban <id\|username> <set\|clear>` | Ban from / unban from the Creator Program (requires `--internal <reason>`; optional `--gate <ref>`; needs the `user.creatorProgram.ban` permission). Use this, never a raw `onboarding` UPDATE. |
| `end-buzz-membership <id\|username>` | End the account's Buzz-purchased membership now: `canceled`, `canceledAt`/`endedAt` = now, so the tier's perks stop (requires `--internal <reason>`; needs the `user.membership.code` permission). Stripe and code memberships are untouched. Moves no Buzz: refund the purchase separately. |
**Options:** `--json`, `--dry-run`, `--reason <code>`, `--message <text>`, `--internal <text>`, `--gate <ref>`, `--key <key>`, `--as-self`, `--all`
**Ban Reason Codes:** SexualMinor, SexualMinorGenerator, SexualMinorTraining, SexualPOI, Bestiality, Scat, Nudify, Harassment, SpamBot, LeaderboardCheating, BuzzCheating, RRDViolation, Other
```bash
node .claude/skills/mod-actions/query.mjs user 3879899
node .claude/skills/mod-actions/query.mjs ban 3879899 --reason Other --message "ToS violation" --dry-run
node .claude/skills/mod-actions/query.mjs dm 3879899 --message "Please review our guidelines"
node .claude/skills/mod-actions/query.mjs inbox
node .claude/skills/mod-actions/query.mjs thread 3879899
node .claude/skills/mod-actions/query.mjs creator-program-ban 12345 set --internal "Counterparty farming" --gate hub:request:abc
node .claude/skills/mod-actions/query.mjs end-buzz-membership 12345 --internal "Buzz refunded by support" --dry-run
```
---
## strikes.mjs — Strike System
```bash
node .claude/skills/mod-actions/strikes.mjs <command> [options]
```
| Command | R/W | Description |
|---------|-----|-------------|
| `get-user <userId>` | READ | Strike history for a user |
| `standings` | READ | User standings (filter: active/muted/flagged) |
| `list` | READ | Paginated strike list with filters |
| `create <userId>` | WRITE | Issue a strike (requires `--reason`, `--description`) |
| `void <strikeId>` | WRITE | Void a strike (requires `--reason`) |
**Strike Reasons:** BlockedContent, RealisticMinorContent, CSAMContent, TOSViolation, HarassmentContent, ProhibitedContent, ManualModAction
**Options:** `--reason`, `--description`, `--points <1-3>`, `--entity-type`, `--entity-id`, `--report-id`, `--expires-days`, `--status <Active,Expired,Voided>`, `--sort <points|score|lastStrike|created>`, `--sort-order <asc|desc>`, `--flagged-for-review`, `--has-active-strikes`, `--page`, `--limit`, `--json`, `--dry-run`
```bash
node .claude/skills/mod-actions/strikes.mjs get-user 3879899
node .claude/skills/mod-actions/strikes.mjs standings --has-active-strikes --limit 10
node .claude/skills/mod-actions/strikes.mjs create 3879899 --reason BlockedContent --description "Uploaded prohibited content" --points 1 --dry-run
node .claude/skills/mod-actions/strikes.mjs void 42 --reason "False positive from scanner"
```
---
## images.mjs — Image Moderation
```bash
node .claude/skills/mod-actions/images.mjs <command> [options]
```
| Command | R/W | Description |
|---------|-----|-------------|
| `review-queue` | READ | Image review queue |
| `review-counts` | READ | Queue tab counts |
| `moderate <ids> <action>` | WRITE | Block/unblock images |
| `tos-violation <imageId>` | WRITE | Flag as TOS violation |
| `rescan <imageId>` | WRITE | Re-ingest/rescan image |
| `report-csam <imageIds>` | WRITE | Report images as CSAM |
| `poi-tags` | READ | Person-of-interest tags |
| `user-images <userId>` | READ | All images for a user |
| `rating-requests` | READ | NSFW rating review requests |
| `ingestion-errors` | READ | Images with ingestion errors |
| `resolve-ingestion <id>` | WRITE | Resolve ingestion error |
| `downleveled` | READ | Downleveled images |
| `pending-ingestion` | READ | Pending ingestion images |
| `toggle-flag <imageId>` | WRITE | Toggle image flag |
**Options:** `--ids`, `--action`, `--review-type`, `--cursor`, `--page`, `--limit`, `--json`, `--dry-run`
```bash
node .claude/skills/mod-actions/images.mjs review-counts
node .claude/skills/mod-actions/images.mjs review-queue --limit 20
node .claude/skills/mod-actions/images.mjs moderate 12345,67890 block --dry-run
node .claude/skills/mod-actions/images.mjs user-images 3879899 --json
node .claude/skills/mod-actions/images.mjs rescan 12345
```
---
## reports.mjs — Report Handling
```bash
node .claude/skills/mod-actions/reports.mjs <command> [options]
```
| Command | R/W | Description |
|---------|-----|-------------|
| `list` | READ | Reports by entity type (requires `--type`) |
| `set-status <reportId> <status>` | WRITE | Set report status |
| `bulk-status <status>` | WRITE | Bulk update statuses (requires `--ids`) |
| `update <reportId>` | WRITE | Update report with status/notes |
| `appeals` | READ | Recent appeals |
| `appeal-details <id>` | READ | Appeal details |
| `resolve-appeal` | WRITE | Resolve appeal (requires `--ids`, `--entity-type`, `--status`) |
**Report Entity Types:** model, comment, commentV2, commentV3, image, resourceReview, article, post, reportedUser, collection, bounty, bountyEntry, chat, comicProject
**Report Statuses:** Pending, Processing, Actioned, Unactioned
**Appeal Statuses:** Pending, Approved, Rejected
**Options:** `--type`, `--status`, `--ids`, `--entity-type`, `--internal`, `--message`, `--user-id`, `--start-date`, `--page`, `--limit`, `--query`, `--json`, `--dry-run`
```bash
node .claude/skills/mod-actions/reports.mjs list --type image --limit 20
node .claude/skills/mod-actions/reports.mjs set-status 456 Actioned --dry-run
node .claude/skills/mod-actions/reports.mjs bulk-status Actioned --ids 1,2,3
node .claude/skills/mod-actions/reports.mjs appeals # the signed-in account's own recent appeals
node .claude/skills/mod-actions/reports.mjs resolve-appeal --ids 10,11 --entity-type Image --status Approved
```
---
## generation.mjs — Generation Moderation
```bash
node .claude/skills/mod-actions/generation.mjs <command> [options]
```
| Command | R/W | Description |
|---------|-----|-------------|
| `flagged-consumers` | READ | Flagged generation consumers |
| `flagged-reasons` | READ | Flagging reasons |
| `consumer-strikes <userId>` | READ | Consumer's generation strikes |
| `review-strikes <userId>` | WRITE | Mark strikes as reviewed |
| `user-generations <userId>` | READ | User's generated images |
| `restrictions` | READ | All generation restrictions |
| `resolve-restriction <id>` | WRITE | Resolve restriction (Upheld/Overturned) |
| `allowlist-add` | WRITE | Add prompt trigger to allowlist |
| `debug-audit <prompt>` | READ | Test prompt auditing |
| `todays-counts` | READ | Today's prohibited request counts |
| `suspicious-matches` | READ | Saved suspicious audit matches |
**Options:** `--status <Pending|Upheld|Overturned>`, `--reason`, `--start-date`, `--message`, `--trigger`, `--category`, `--negative-prompt`, `--user-id`, `--username`, `--restriction-id`, `--page`, `--limit`, `--json`, `--dry-run`
```bash
node .claude/skills/mod-actions/generation.mjs flagged-consumers
node .claude/skills/mod-actions/generation.mjs consumer-strikes 3879899
node .claude/skills/mod-actions/generation.mjs restrictions --status Pending
node .claude/skills/mod-actions/generation.mjs resolve-restriction 42 --status Upheld --message "Confirmed violation" --dry-run
node .claude/skills/mod-actions/generation.mjs debug-audit "some prompt text"
node .claude/skills/mod-actions/generation.mjs allowlist-add --trigger "girl" --category "age" --reason "False positive"
```
---
## content.mjs — Content Moderation
```bash
node .claude/skills/mod-actions/content.mjs <command> [options]
```
| Command | R/W | Description |
|---------|-----|-------------|
| `models` | READ | Models for mod review |
| `flagged-models` | READ | Flagged models |
| `resolve-flagged` | WRITE | Resolve flagged models (requires `--ids`) |
| `model-versions` | READ | Model versions for mod |
| `rescan-model <id>` | WRITE | Re-ingest a model |
| `restore-model <id>` | WRITE | Restore deleted model |
| `toggle-cannot-promote <id>` | WRITE | Toggle promotion eligibility |
| `toggle-cannot-publish <id>` | WRITE | Toggle publish ability |
| `articles` | READ | Articles for mod review |
| `mod-rule <id>` | READ | Get moderation rule |
**Options:** `--ids`, `--page`, `--limit`, `--json`, `--dry-run`
Training moderation (list / approve / deny training data) moved to the moderator spoke
(`/audit/training-models`, `/audit/training-data`) in the moderator-app migration and is no
longer reachable via tRPC — see `docs/moderator-app/page-migration-checklist.md`.
```bash
node .claude/skills/mod-actions/content.mjs flagged-models --limit 10
node .claude/skills/mod-actions/content.mjs resolve-flagged --ids 1,2,3 --dry-run
node .claude/skills/mod-actions/content.mjs rescan-model 789
```
---
## model3ds.mjs — 3D Models Moderation
```bash
node .claude/skills/mod-actions/model3ds.mjs <command> [options]
```
| Command | R/W | Description |
|---------|-----|-------------|
| `list` | R | List Model3Ds (`--status`, `--username`, `--limit`, `--cursor`) |
| `get <id>` | R | Get a Model3D by id |
| `files <id>` | R | List files attached to a Model3D |
| `unpublish <id>` | W | Set status -> Unpublished |
| `delete <id>` | W | Soft-delete (status -> Deleted, sets deletedAt/deletedBy) |
| `restore <id>` | W | Restore (Deleted -> Unpublished, Unpublished -> Published) |
| `set-nsfw-level <id>` | W | Override nsfwLevel (`--level <n> [--lock]`) |
| `toggle-tos <id>` | W | Toggle tosViolation (locks the field) |
| `toggle-poi <id>` | W | Toggle poi (locks the field) |
| `toggle-minor <id>` | W | Toggle minor (locks the field) |
| `toggle-nsfw <id>` | W | Toggle nsfw (locks the field) |
| `toggle-unlisted <id>` | W | Toggle unlisted (locks the field) |
Strikes against a Model3D use the existing `strikes.mjs` (the strike system is entity-type-agnostic):
```bash
node .claude/skills/mod-actions/strikes.mjs create <userId> \
--entity-type Model3D --entity-id <model3dId> --reason TOSViolation --points 1
```
Common flags:
- `--json` — raw JSON output
- `--dry-run` — preview without making changes (write commands only)
Examples:
```bash
node .claude/skills/mod-actions/model3ds.mjs list --status Draft --limit 100
node .claude/skills/mod-actions/model3ds.mjs get 42
node .claude/skills/mod-actions/model3ds.mjs unpublish 42
node .claude/skills/mod-actions/model3ds.mjs set-nsfw-level 42 --level 16 --lock
node .claude/skills/mod-actions/model3ds.mjs toggle-tos 42 --dry-run
node .claude/skills/mod-actions/model3ds.mjs restore 42
```
---
## csam.mjs — NCMEC/CSAM Reporting
```bash
node .claude/skills/mod-actions/csam.mjs <command> [options]
```
| Command | R/W | Description |
|---------|-----|-------------|
| `reports` | READ | Paginated CSAM reports |
| `stats` | READ | CSAM report statistics |
| `image-resources <imageIds>` | READ | Resources used to generate flagged images |
| `create-report <userId>` | WRITE | Create NCMEC CyberTipline report |
**CSAM Report Types:** Image, TrainingData, GeneratedImage
**Options:** `--type <CsamReportType>`, `--image-ids <id1,id2,...>`, `--minor-depiction <real|non-real>`, `--page`, `--limit`, `--json`, `--dry-run`
```bash
node .claude/skills/mod-actions/csam.mjs stats
node .claude/skills/mod-actions/csam.mjs reports --limit 10
node .claude/skills/mod-actions/csam.mjs image-resources 12345,67890
node .claude/skills/mod-actions/csam.mjs create-report 3879899 --type GeneratedImage --image-ids 111,222 --dry-run
```
---
## shop.mjs — Creator Shop
```bash
node .claude/skills/mod-actions/shop.mjs refund <buzzTransactionId...> --reason <text> (--clawback | --no-clawback) [--writable]
```
| Command | R/W | Description |
|---------|-----|-------------|
| `refund <ids...>` | WRITE | Refund purchases: Buzz back to the buyer, payouts reversed with `--clawback`, cosmetic revoked, purchase marked refunded (`creatorShop.refundPurchases`) |
Dry run unless `--writable` (the server's dry run lists each purchase's ledger legs). Re-running is safe.
`--no-clawback` means Civitai pays the refund, `--clawback` the creator. Choose per case: an agent's
`--writable` run needs Justin's approval card, and the card must name the clawback value.
Refusals and behaviour: `docs/features/creator-shop.md` → "Refunding a purchase by hand".
---
## Global Options
All scripts except `shop.mjs` (dry run by default; `--writable` writes) support:
| Flag | Description |
|------|-------------|
| `--json` | Output raw JSON (for agent/scripting consumption) |
| `--dry-run` | Preview WRITE actions without executing |
| `--page <n>` | Page number for paginated results (default: 1) |
| `--limit <n>` | Page size for paginated results (default: 20) |
## Safety Notes
- **Always use `--dry-run` first** for destructive/write actions (`shop.mjs`: omit `--writable` first)
- All actions are logged in the ModActivity table
- Ban actions invalidate user sessions immediately
- CSAM reports are submitted to NCMEC — use with extreme care
- Document reasons with `--reason` and `--message` flags
- API key must have moderator privileges
- Use `--json` for programmatic consumption by agent daemons
Attribution
Related skills
View all in ai-agents →Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.