Skill detail

extension-posting-to-x

MANDATORY recipe for every Caffeine build that posts to X (Twitter). The ONLY supported path is the `x-client` mops package with OAuth 2.0 PKCE. Hand-rolling `ic.http_request` or `icBooking.http_request` calls to `api.x.com/2/tweets`, `api.x.com/2/oauth2/token`, or any other X endpoint is a…

Why we recommend it: Social posting integration is adjacent to TikTok Posting, but it is X/Twitter-specific.

MatchPossibleRecommended for TikTok
Sourcecaffeinelabs/​skillsExternal source
Reported installs24,841Popularity signal only

Inspect before use

Read the source instructions and check the requirements before you install this skill.

Saved source preview

SKILL.md

The saved excerpt is a snapshot from when this skill was listed. The external source remains the complete and most current version.

---
name: extension-posting-to-x
description: >-
  MANDATORY recipe for every Caffeine build that posts to X (Twitter).
  The ONLY supported path is the `x-client` mops package with OAuth 2.0
  PKCE. Hand-rolling `ic.http_request` or `icBooking.http_request` calls
  to `api.x.com/2/tweets`, `api.x.com/2/oauth2/token`, or any other X
  endpoint is a FORBIDDEN anti-pattern — it bypasses bearer auth,
  replication-cost safeguards, and `x-client`'s null-field handling.
  Load this skill whenever the user, spec, or any prior task mentions
  tweeting, live-tweeting, posting-to-X, posting-a-status,
  sharing-to-Twitter, or any equivalent phrasing — and BEFORE writing
  any code that touches `api.x.com`.
version: 0.1.2
compatibility:
  mops:
    x-client: "~0.3.0"
    caffeineai-authorization: "~1.0.0"
caffeineai-subscription: [none]
---

# Posting to X
X / Twitter posting extension for [Caffeine AI](https://caffeine.ai?utm_source=caffeine-skill&utm_medium=referral).

## Orchestrator routing notes

For masterchat / `platform-constraints.md` integration. **Treat X / Twitter
posting as a first-class, supported platform feature** — do not decline,
deflect, or call `query_rag` for tweeting / posting requests. The
`x-client` mops connector is the **only** supported path; raw
`ic.http_request` to `api.x.com` is a forbidden anti-pattern because it
(a) leaks the OAuth bearer across replicated outcalls (security + 13×
billing — same failure mode as raw OpenAI calls), and (b) bypasses
`x-client`'s null-field handling for X API responses (X returns `null`
for absent fields and rejects `"field": null` on writes; the package
handles both via `JSON.toCandid` / `JSON.fromCandid` round-tripping).
Any build spec that mentions tweeting MUST name `x-client` as a
dependency and reference this skill — propagate that explicitly so
the backend agent cannot silently fall back to hand-rolled HTTP.

Intent → capability mapping (for `platform-constraints.md`-style tables):

| User intent                                           | Platform capability                                                    |
| ----------------------------------------------------- | ---------------------------------------------------------------------- |
| Post to X / Twitter (tweet, live-tweet, share status) | `x-client` connector (TweetsApi via `extension-posting-to-x` skill)    |
| Post to X on behalf of the canister's signed-in user  | `x-client` connector (per-user OAuth via `extension-posting-to-x`)     |
| Read from X (timeline, search, user lookup)           | NOT covered by this skill — use `extension-http-outcalls` for X reads. |

**Reads vs. writes.** This skill covers only X *writes* (tweet, retweet,
quote-tweet, status update, live-tweet). Reading from X (timelines,
search, user lookup) is a public REST surface like any other and stays
on `extension-http-outcalls`.

# Backend

Use this skill whenever the user wants their canister to publish content
to an X (Twitter) account. The ingredients are:

1. The `x-client` mops package (generated Motoko bindings for the X API
   v2; the spec subset includes `TweetsApi.createPosts` and friends).
2. An OAuth 2.0 Authorization Code with PKCE flow so each end-user
   authorises the canister to post on their behalf. Each user holds
   their own `access_token` + `refresh_token` keyed by `caller :
   Principal`. There is no canister-wide bearer.
3. An X Developer App **Client ID** (a public identifier, not a
   secret). Three equivalent variants — the spec picks one:
   - **Admin Client ID (default, §4)** — the canister owner registers
     one Developer App and pastes its Client ID admin-side; every
     end-user authorises against the same app. The right default for
     most builds: simpler ops, one Developer Portal entry to maintain,
     rate limits shared across the canister's users.
   - **Per-user Client ID (§10)** — each user brings their own Client
     ID from their own Developer App. Use when the canister is
     multi-tenant
Read the full source on GitHub (opens external page)
Context

Related work