---
name: pp-x-twitter
description: "Offline-searchable X/Twitter CLI and MCP surface for archiving posts, resolving links, monitoring mentions, composing threads, publishing Articles, and searching synced bookmarks. Trigger phrases: `search X for`, `archive tweets about`, `show me the X thread for`, `monitor my X mentions`, `post a thread to X`, `use x-twitter`, `run x-twitter-pp-cli`."
author: "Cathryn Lavery"
license: "Apache-2.0"
argument-hint: "<command> [args] | install cli|mcp"
allowed-tools: "Read Bash"
metadata:
  openclaw:
    requires:
      bins:
        - x-twitter-pp-cli
    install:
      - kind: go
        bins: [x-twitter-pp-cli]
        module: github.com/mvanhorn/printing-press-library/library/social-and-messaging/x-twitter/cmd/x-twitter-pp-cli
---
<!-- GENERATED FILE — DO NOT EDIT.
     This file is a verbatim mirror of library/social-and-messaging/x-twitter/SKILL.md,
     regenerated post-merge by tools/generate-skills/. Hand-edits here are
     silently overwritten on the next regen. Edit the library/ source instead.
     See the repository agent guide, section "Generated artifacts: registry.json, cli-skills/". -->

# X (Twitter) — Printing Press CLI

## Prerequisites: Install the CLI

This skill drives the `x-twitter-pp-cli` binary. **You must verify the CLI is installed before invoking any command from this skill.** If it is missing, install it first:

1. Install via the Printing Press installer. It defaults binaries to `$HOME/.local/bin` on macOS/Linux and `%LOCALAPPDATA%\Programs\PrintingPress\bin` on Windows:
   ```bash
   npx -y @mvanhorn/printing-press-library install x-twitter --cli-only
   ```
2. Verify: `x-twitter-pp-cli --version`
3. Ensure the reported install directory is on `$PATH` for the agent/runtime that will invoke this skill.

If the `npx` install fails (no Node, offline, etc.), fall back to a direct Go install (requires Go 1.26.6 or newer). This installs into `$GOPATH/bin` (default `$HOME/go/bin`), so add that directory to `$PATH` instead:

```bash
go install github.com/mvanhorn/printing-press-library/library/social-and-messaging/x-twitter/cmd/x-twitter-pp-cli@latest
```

If `--version` reports "command not found" after install, the runtime cannot see the binary directory on `$PATH`. Do not proceed with skill commands until verification succeeds.

Mirrors the official X v2 API and adds what no other X tool has: a local SQLite store you can sync once and query many times with FTS5 search and group-by analytics, agent-native --json/--select output, and an MCP server that exposes the whole surface to AI agents through token-efficient orchestration plus named multi-step intents. Start pasted-link workflows with `post resolve`, use `thread context` when a post needs parent/quote/reply context, save durable source material with `collection save/list/export`, track ongoing searches with `monitor create/run/list`, package saved activity with `brief`, snapshot accounts with `account snapshot`, find launch or repo links with `url mentions`, track post metrics with `performance snapshot/backfill/analyze`, export account/query timelines with `timeline export`, reconstruct synced conversation threads offline with `thread show`, compose self-reply threads from markdown with `thread compose`, author long-form X Articles from markdown with `articles-publish-md`, and rescue your bookmark graveyard with `users bookmarks find` — keyword and author search over your synced bookmarks, which X itself gives you no way to search.

## When to Use This CLI

For a ranked readout of recent posts, run `x-twitter-pp-cli top-posts --metric engagement --limit 10 --max-fetch 100 --json`. It reads the live X timeline, so each page may use paid API credits. `--max-fetch` accepts 1 to 1000 posts, with a small extra-page budget for sparse responses. A leaderboard returned at that budget is partial and has `truncated: true` in every JSON row. `--user-id` selects a numeric account ID without a separate username lookup; without it, the command uses the authenticated user. JSON rows name the effective `score_metric`, and missing impression scores are `null` rather than zero. `--dry-run` makes no request.

Reach for this CLI when a task involves reading, searching, or archiving X (Twitter) data and you want the results queryable offline rather than re-fetched each time — building a searchable corpus of posts, reconstructing a conversation thread, snapshotting a user's recent posts with engagement, or monitoring mentions incrementally. It is also the right choice when an AI agent needs an X surface with read-only/destructive safety hints and named multi-step intents rather than a pile of raw endpoint calls. Prefer it over raw API calls whenever the same data will be queried more than once, since the local store avoids re-spending per-read credits.

## Unique Capabilities

These capabilities aren't available in any other tool for this API.

### Local state that compounds
- **`post resolve`** — Normalize any X post URL or raw post ID into a canonical structured record. It prefers local data in auto mode, falls back to public v2 reads when needed, includes provenance (`live`, `local`, or `mixed`), and emits suggested next workflow commands.

  _Use this as the first command when an agent starts from a pasted X link. It avoids brittle URL parsing and returns stable fields for downstream workflows._

  ```bash
  x-twitter-pp-cli post resolve https://x.com/user/status/123 --agent
  x-twitter-pp-cli post resolve 123 --include author,media,links,refs,metrics --agent
  ```
- **`thread context`** — Resolve a post URL or ID, include parent and quoted posts when available, and optionally include bounded replies from the local store and/or recent search.

  _Use this before summarizing or drafting around a post. `thread show` is still the pure offline conversation reconstruction command; `thread context` is the URL-first workflow that can mix local and live data._

  ```bash
  x-twitter-pp-cli thread context https://x.com/user/status/123 --agent
  x-twitter-pp-cli thread context 123 --replies --depth 3 --limit 100 --agent
  ```
- **`collection save/list/export`** — Save resolved X posts into durable named local collections, then list or export them as markdown, JSON, JSONL, or CSV. This never writes to X; it only writes the local SQLite store.

  _Use collections for research libraries, launch mentions, examples, recruiting/source material, and anything an agent should reuse offline after the first API read._

  ```bash
  x-twitter-pp-cli collection save https://x.com/user/status/123 --collection ai-agents --note "Good framing" --agent
  x-twitter-pp-cli collection list ai-agents --agent
  x-twitter-pp-cli collection export ai-agents --format markdown
  ```
- **`monitor create/run/list`** — Create named query, URL, or account monitors, then run them repeatedly with local watermarks and dedupe. `monitor create` and `monitor run` write only local SQLite state; they never post, like, reply, follow, or mutate X.

  _Use monitors for launch mentions, product/customer feedback, account tracking, and recurring agent jobs. `--since last` uses the saved watermark; `--preview` fetches without updating local state._

  ```bash
  x-twitter-pp-cli monitor create ai-labs --query 'from:openai OR from:anthropic' --agent
  x-twitter-pp-cli monitor create product-mentions --url https://example.com --agent
  x-twitter-pp-cli monitor run ai-labs --since last --agent
  x-twitter-pp-cli monitor list --agent
  ```
- **`brief`** — Build a deterministic source-backed JSON or markdown brief from monitor results, collections, or explicit post IDs. It packages links, authors, text, and available metrics; it does not invent conclusions or run LLM summarization.

  _Use this when an agent needs a daily/weekly X activity packet or a collection summary that can be pasted into notes, docs, or a CRM._

  ```bash
  x-twitter-pp-cli brief --monitor ai-labs --since 24h --agent
  x-twitter-pp-cli brief --collection launch-feedback --format markdown
  ```
- **`account snapshot`** — Capture profile basics, public metrics, pinned post, and recent posts for a username or user ID. It is read-only toward X and uses local data first unless `--live` or `--data-source live` is set.

  ```bash
  x-twitter-pp-cli account snapshot @username --recent 20 --agent
  x-twitter-pp-cli account snapshot 12345 --include recent,profile,metrics,pinned --format markdown
  ```
- **`url mentions`** — Search for recent posts mentioning a URL, domain, repo, article, or product page. It can optionally save results into a local collection or create/update a local monitor for future runs.

  ```bash
  x-twitter-pp-cli url mentions https://example.com --since 7d --agent
  x-twitter-pp-cli url mentions github.com/org/repo --collection launch-feedback --monitor repo-links --agent
  ```
- **`performance snapshot/backfill/analyze`** — Store timestamped post metrics locally, backfill recent account posts when auth allows, and analyze saved snapshots by type, hour, media, link presence, or label. Missing metrics stay nullable/absent; the CLI does not treat unavailable fields as zero. Snapshot output includes `public_metrics`, available non-public/organic metrics, `metric_source`, and `metric_availability`.

  ```bash
  x-twitter-pp-cli performance snapshot --ids 123,456 --label 24h --agent
  x-twitter-pp-cli performance backfill --mine --days 90 --agent
  x-twitter-pp-cli performance analyze --since 90d --group-by type,hour,has_media,has_link --agent
  ```
- **`timeline export`** — Export an account or query timeline as markdown, JSON, or JSONL. Account exports use local synced tweets when available and fetch live only when needed or requested.

  ```bash
  x-twitter-pp-cli timeline export @username --since 30d --format markdown
  x-twitter-pp-cli timeline export --query 'ai agents' --since 7d --format jsonl
  ```
- **`thread show`** — Rebuild a full conversation thread from your locally synced posts — ordered and depth-tagged — without re-spending API read credits.

  _When an agent needs the shape of a discussion (who replied to whom, in order), reach for this instead of paginating the search API and re-assembling the tree by hand._

  ```bash
  x-twitter-pp-cli thread show 1750000000000000000 --agent
  ```
- **`users bookmarks find`** — Search your synced bookmarks by keyword and/or author, offline. X has no bookmark search and its API exposes no bookmark timestamp, so bookmarks pile up unread; this rebuilds the missing retrieval layer from the local store. Read-only and free to re-run once synced — the X read credit is spent once at sync time, not per query.

  _The "I bookmarked something about this and can't find it" rescue. Sync bookmarks once, then let an agent retrieve and act on them (summarize, draft a thread, cluster) — the offline store is the agent's working set, not a per-query API spend._

  ```bash
  # one-time populate (personal read — needs X_OAUTH2_USER_TOKEN); add author field + users for --from
  x-twitter-pp-cli sync --resources bookmarks --param tweet.fields=author_id,created_at
  x-twitter-pp-cli sync --resources users

  x-twitter-pp-cli users bookmarks find "rust async" --agent
  x-twitter-pp-cli users bookmarks find "llm" --from @karpathy --limit 20 --agent
  ```

### Authoring workflows
- **`thread compose`** — Split a markdown file into a numbered, 280-char-packed self-reply thread; prints by default and only posts with --post.

  _Compose a thread from a document deterministically; the dry-run default lets an agent preview the exact tweets before any write._

  ```bash
  x-twitter-pp-cli thread compose ./update.md
  ```
- **`articles-publish-md`** — Parse a markdown file with YAML frontmatter into the Draft.js content_state JSON X's Articles editor accepts; previews by default; --draft creates a new draft, --update edits an existing draft, --post publishes publicly.

  _The only programmatic way to author a long-form X Article from a document; preview, --draft, and --update keep it private until you explicitly --post._

  The converter supports paragraphs, `#`/`##` headers (`###` and deeper are downgraded to `##`), lists, blockquotes, fenced code blocks, tables, dividers, image lines (`![alt](path)`), standalone tweet URLs (native embedded posts: put `https://x.com/<user>/status/<id>` alone on its own line), bold/italic inline styles (including inside blockquotes; backtick `code` spans become plain text because X Articles has no inline code style), and `[text](url)` inline links, which become real LINK entities (working hyperlinks) in the article. Lines that are HTML comments (`<!-- ... -->`) are stripped and never ship as article text.

  ```bash
  x-twitter-pp-cli articles-publish-md ./post.md
  x-twitter-pp-cli articles-publish-md ./post.md --update 1750000000000000000
  ```
- **`articles update-md`** — Update an existing X Article draft in place from a markdown file: title (frontmatter), body, links, and new inline images, all in one command. Find the article id via `articles list --agent`.

  _Edit the markdown, re-run one command. No duplicate drafts: the draft keeps its id, so the edit URL and any saved state stay valid._

  ```bash
  x-twitter-pp-cli articles update-md ./post.md --article-id 1750000000000000000 --agent
  ```

  **WARNING — body replacement:** `articles update-md` replaces the ENTIRE body of the target draft. Anything added by hand in the X composer that the markdown converter cannot reproduce is destroyed by the update. The command preflights the draft's content_state and refuses when it finds entity types outside the converter's emit set (LINK, MARKDOWN, MEDIA, TWEET, DIVIDER); pass `--replace-unknown-entities` only when you genuinely want to overwrite those artifacts. Markdown-authored content round-trips cleanly; if a draft holds composer-only embeds or other manual artifacts, edit it in the composer instead.

  Draft-only by default: a published article is refused unless you pass `--republish`, which runs Unpublish -> UpdateContent -> Publish (the article is briefly unpublished). Use `--dry-run` to preview the converted payload with no API call.
- **`articles patch-md`** — Add sections, embedded posts or text fixes to an existing (even published) X Article without rewriting the rest. It reads the current body and keeps every block, image and embed as it is, then applies anchored edits from a small patch file.

  _Use this instead of `update-md` for an article that already has images or composer edits: nothing outside the patch changes, and no image is re-uploaded._

  ```markdown
  <!-- after: The other machines should appear in the list. -->
  Here is the post where I said so:

  https://x.com/cathrynlavery/status/2103588600076214414

  <!-- before: The checklist -->
  ## A new section
  Text, lists, links and fenced code work as in articles-publish-md.

  <!-- replace: I installed five apps: => I installed four apps: -->
  ```

  ```bash
  x-twitter-pp-cli articles patch-md ./edits.md --article-id 1750000000000000000 --dry-run --agent   # plan + full body, no write
  x-twitter-pp-cli articles patch-md ./edits.md --article-id 1750000000000000000 --republish --agent # published article
  ```

  An anchor is the start of an existing paragraph or heading and must match exactly one block; a replace target must appear exactly once and may not cut across a link or bold span. Any miss stops the command before it writes. `--dry-run` still reads the article (it needs the real body) but never writes. Published articles need `--republish` (the same Unpublish -> UpdateContent -> Publish sequence the composer uses; the post, its URL and its likes stay). If your cookies were captured without `twid`, set `X_TWITTER_USER_ID=<your numeric id>`.

## Command Reference

**account-activity** — Endpoints relating to retrieving, managing AAA subscriptions

- `x-twitter-pp-cli account-activity create-subscription` — Creates an Account Activity subscription for the user and the given webhook.
- `x-twitter-pp-cli account-activity delete-subscription` — Deletes an Account Activity subscription for the given webhook and user ID.
- `x-twitter-pp-cli account-activity get-subscription-count` — Retrieves a count of currently active Account Activity subscriptions.
- `x-twitter-pp-cli account-activity get-subscriptions` — Retrieves a list of all active subscriptions for a given webhook.
- `x-twitter-pp-cli account-activity validate-subscription` — Checks a user’s Account Activity subscription for a given webhook.

**activity** — Manage activity

- `x-twitter-pp-cli activity create-subscription` — Creates a subscription for an X activity event
- `x-twitter-pp-cli activity delete-subscription` — Deletes a subscription for an X activity event
- `x-twitter-pp-cli activity delete-subscriptions-by-ids` — Deletes multiple subscriptions for X activity events by their IDs
- `x-twitter-pp-cli activity get-subscriptions` — Get a list of active subscriptions for XAA
- `x-twitter-pp-cli activity update-subscription` — Updates a subscription for an X activity event

**chat** — Manage chat

- `x-twitter-pp-cli chat add-group-members` — Adds one or more members to an existing encrypted Chat group conversation, rotating the conversation key.
- `x-twitter-pp-cli chat create-conversation` — Creates a new encrypted Chat group conversation on behalf of the authenticated user.
- `x-twitter-pp-cli chat get-conversation` — Returns metadata for a Chat conversation including type, muted status, and group details. Use chat_conversation.
- `x-twitter-pp-cli chat get-conversation-events` — Retrieves messages and key change events for a specific Chat conversation with pagination support.
- `x-twitter-pp-cli chat get-conversations` — Retrieves a list of Chat conversations for the authenticated user's inbox.
- `x-twitter-pp-cli chat initialize-conversation-keys` — Initializes encryption keys for a Chat conversation.
- `x-twitter-pp-cli chat initialize-group` — Initializes a new XChat group conversation and returns a unique conversation ID.
- `x-twitter-pp-cli chat mark-conversation-read` — Marks a specific Chat conversation as read on behalf of the authenticated user.
- `x-twitter-pp-cli chat media-download` — Downloads encrypted media bytes from an XChat conversation. The response body contains raw binary bytes.
- `x-twitter-pp-cli chat media-upload-append` — Appends media data to an XChat upload session.
- `x-twitter-pp-cli chat media-upload-finalize` — Finalizes an XChat media upload session.
- `x-twitter-pp-cli chat media-upload-initialize` — Initializes an XChat media upload session.
- `x-twitter-pp-cli chat send-message` — Sends an encrypted message to a specific Chat conversation.
- `x-twitter-pp-cli chat send-typing-indicator` — Sends a typing indicator to a specific Chat conversation on behalf of the authenticated user.

**communities** — Manage communities

- `x-twitter-pp-cli communities get-by-id` — Retrieves details of a specific Community by its ID.
- `x-twitter-pp-cli communities search` — Retrieves a list of Communities matching the specified search query.

**compliance** — Endpoints related to keeping X data in your systems compliant

- `x-twitter-pp-cli compliance create-jobs` — Creates a new Compliance Job for the specified job type.
- `x-twitter-pp-cli compliance get-jobs` — Retrieves a list of Compliance Jobs filtered by job type and optional status.
- `x-twitter-pp-cli compliance get-jobs-by-id` — Retrieves details of a specific Compliance Job by its ID.

**connections** — Endpoints related to streaming connections

- `x-twitter-pp-cli connections delete-all` — Terminates all active streaming connections for the authenticated application.
- `x-twitter-pp-cli connections delete-by-endpoint` — Terminates all streaming connections for a specific endpoint ID for the authenticated application.
- `x-twitter-pp-cli connections delete-by-uuids` — Terminates multiple streaming connections by t