<img src="https://github.com/ahmadawais/typefully-cli/blob/main/.github/cover.png?raw=true" alt="Typefully CLI" />
# Typefully CLI
A TypeScript CLI and AI agent skill for drafting, scheduling, and managing social media posts across X, LinkedIn, Threads, Bluesky, and Mastodon.
Built on the [Typefully API](https://typefully.com/docs/api). [Typefully](https://typefully.com) is a writing and scheduling app used by 200k+ top creators and teams to grow on X, LinkedIn, Threads, and Bluesky.
## Setup
### 1. Install
```bash
npm i -g typefully
```
Or use directly with npx:
```bash
npx typefully --help
```
or skills for your AI agent:
```bash
npx skills add ahmadawais/typefully-cli
```
### 2. Copy your API Key
You'll need a Typefully API key. Copy an existing key or create a new one at https://typefully.com/?settings=api
### 3. Run the setup command
This configures your API key and default social set:
```bash
typefully setup
```
> [!TIP]
> You can also set the API key as an environment variable: `export TYPEFULLY_API_KEY=your_key_here` but not needed if you run `typefully setup` which saves it to a config file.
### 4. Start using it
```bash
tfly # interactive — pick text, platform, schedule
tfly "Hello, world!" # instant draft from text
tfly schedule # interactive — browse drafts and schedule one
tfly rm # interactive — pick drafts to delete
tfly rm <draft_id> # delete a specific draft
tfly drafts list --status scheduled
tfly drafts list --json # raw JSON for scripts/pipes
```
#### Aliases (short forms)
| Alias | Equivalent |
|-------|-----------|
| `tfly "text"` | `typefully drafts create --text "text"` |
| `tfly create-draft "text"` | same, with full flag support |
| `tfly update-draft <id> "text"` | `typefully drafts update` |
| `tfly rm [draft_id]` | `typefully drafts delete` |
<img src="https://github.com/ahmadawais/typefully-cli/blob/main/.github/image.png?raw=true" alt="Typefully CLI" />
## Output Modes
By default the CLI prints human-readable output with colored formatting. Pass `-j` / `--json` (or pipe stdout) to get raw JSON instead — useful for scripting and automation.
```bash
typefully me # human-readable
typefully me --json # raw JSON
typefully me -j # same, short flag
typefully drafts list | jq '.results[0]' # auto JSON when piped
```
In JSON mode the banner and spinners are suppressed — stdout contains only the JSON payload.
## Commands
### Global flags
| Flag | Description |
|------|-------------|
| `-v, --version` | Show version |
| `-j, --json` | Output raw JSON instead of human-readable text |
### Setup & Configuration
```bash
typefully setup # interactive
typefully setup --key typ_xxx --location global # non-interactive
typefully setup --key typ_xxx --scope local # --scope is an alias for --location
typefully setup --key typ_xxx --default-social-set 123
typefully setup --key typ_xxx --no-default
typefully config show
typefully config set-default # interactive
typefully config set-default 123 --location global
typefully config set-default 123 --scope local # --scope is an alias for --location
typefully config set-platforms # interactive multiselect
typefully config set-platforms --platforms x,linkedin,threads
typefully config set-timezone # interactive — pick from common IANA timezones
typefully config set-timezone --timezone America/New_York
```
### User & Social Sets
```bash
typefully me
typefully social-sets list
typefully social-sets get [social_set_id]
```
### Interactive Scheduler
```bash
tfly schedule
```
Browse all drafts and schedule one with a keyboard-only flow:
- **Happy path** — `↑↓ Enter` pick draft → `Enter` next free slot → `Enter` confirm → `Enter` open in browser
- **Custom time** — select "Custom date & time", enter date (`YYYY-MM-DD`) and time (`HH:MM`), confirm
Timezone defaults to PST. Change it with `tfly config set-timezone`.
### Drafts
```bash
# List
typefully drafts list
typefully drafts list --status scheduled
typefully drafts list --tag product --limit 20
typefully drafts list --sort -created_at
# Get
typefully drafts get <draft_id> --use-default
typefully drafts get <social_set_id> <draft_id>
# Create
tfly "Post content" # alias for `typefully drafts create --text "Post content"`
typefully drafts create --text "Post content"
typefully drafts create -f ./post.txt # -f is short for --file
typefully drafts create --text "..." --platform x,linkedin
typefully drafts create --text "..." --all # all connected platforms
typefully drafts create --text "..." --schedule next-free-slot
typefully drafts create --text "..." --notes "Draft notes" # --notes = --scratchpad
# Update
typefully drafts update <draft_id> --text "New text" --use-default
typefully drafts update <draft_id> -a --text "New post" --use-default # -a = --append
typefully drafts update <draft_id> -f ./updated.txt --use-default
# Delete / Schedule / Publish
typefully drafts delete <draft_id> --use-default
typefully drafts schedule <draft_id> --time next-free-slot --use-default
typefully drafts publish <draft_id> --use-default
```
### Aliases (agent-friendly)
`create-draft` and `update-draft` are top-level aliases with positional text — useful for agents and scripts where flags feel verbose.
```bash
# create-draft: positional text + --social-set-id
typefully create-draft "Hello, world!"
typefully create-draft "Big announcement!" --platform x,linkedin
typefully create-draft "Thread post" --schedule next-free-slot
typefully create-draft --file ./post.txt --platform x
# update-draft: positional draft_id + optional positional text
typefully update-draft <draft_id> "Updated text"
typefully update-draft <draft_id> --append "New thread post"
typefully update-draft <draft_id> -f ./updated.txt
```
Both aliases support all the same options as their `drafts create` / `drafts update` equivalents, plus `--social-set-id <id>` to override the default.
### Tags
```bash
typefully tags list
typefully tags list <social_set_id>
typefully tags create --name "Product"
```
### Media
```bash
typefully media upload ./image.jpg # waits for processing
typefully media upload ./image.jpg --no-wait # returns immediately
typefully media upload ./image.jpg --timeout 120 # custom timeout (seconds)
typefully media status <media_id>
```
## Thread Syntax
Use `---` on its own line to split a draft into a thread:
```bash
typefully drafts create --text "First post
---
Second post in the thread
---
Third post"
```
## Config File Format
Config files are stored as JSON with `0600` permissions:
```json
{
"apiKey": "typ_xxxx",
"defaultSocialSetId": 12345,
"defaultPlatforms": ["x", "linkedin"],
"defaultTimezone": "America/Los_Angeles"
}
```
**Priority order** (highest wins):
1. `TYPEFULLY_API_KEY` environment variable
2. `./.typefully/config.json` (project-local)
3. `~/.config/typefully/config.json` (user-global)
## AI Agent Skill
This package also includes an AI agent skill for use with Claude Code, Cursor, and other AI coding assistants.
### Install the skill
**CLI** (works with Claude Code, Cursor, Windsurf, and many other agents):
```bash
npx skills add ahmadawais/typefully-cli
```
## Supported Platforms
| Platform | `--platform` value |
|----------|-------------------|
| X (Twitter) | `x` |
| LinkedIn | `linkedin` |
| Threads | `threads` |
| Bluesky | `bluesky` |
| Mastodon | `mastodon` |
## Links
- [Typefully](https://typefully.com)
- [API Documentation](https://typefully.com/docs/api)
- [CLI Spec](./skills/spec.md)
## License
MIT