bird is for X. knit is for Threads — and it's actually agent-safe.
An agent-friendly CLI for Instagram's Threads, built on the official API. Read-only by default, posting gated in the binary, prompt-injection-fenced, machine-readable.
Conforms to Agent CLI Guidelines v0.4.0 (Full).
Plenty of Threads CLIs exist. None is built for an autonomous agent to drive safely. knit is:
- 🛑 Read-only by default. Every mutation is blocked unless you pass
--allow-mutations— enforced in the binary, returning a structuredMUTATION_BLOCKED(exit 12), not an interactive "type y" prompt that deadlocks a headless agent. - 🧵 Reviewed-artifact publishing.
post create --dry-runemits the exact plan + a hash;--apply <hash>publishes only that plan — no blind--yeson an irreversible public post. - 🤖 Machine-readable.
knit schemadumps the command tree, exit codes, and live safety state;knit agent(orKNIT_HELP=agent) prints the embedded usage contract — no repo, no network. - ✂️ Token-bounded. Reads return
{schemaVersion, data, nextCursor?};--limit/--selectkeep responses inside an agent's context window. - 🔒 Prompt-injection-aware. It's a public feed — post/reply/search/mention text and bios are fenced as untrusted data, never instructions.
- ✅ Official API. Low breakage risk and ToS-compliant — unusual for the agent-CLI crop.
brew install rnwolfe/tap/knit # Homebrew (macOS / Linux) — best for humans
go install github.com/rnwolfe/knit/cmd/knit@latest # go install — best for agents (pinnable)Or grab a prebuilt binary from Releases (linux · macOS · windows, amd64 · arm64).
# 1. Authenticate (headless) — token never touches argv:
printf '%s' "$THREADS_TOKEN" | knit auth login --token-stdin
# ...or browser: `knit auth login` then paste the redirected URL. (How to get a token: docs.)
knit auth status --json # account, token expiry, publish quota
knit post list --json # your recent posts (stable envelope)
knit search posts "ai agents" # ⚠️ scope:self until advanced access is granted
# Publishing is gated — preview, then apply:
knit post create --text "hello from knit" --dry-run # plan + hash, nothing posted
knit post create --text "hello from knit" --allow-mutationsknit --help is example-led; knit schema is the machine-readable contract.
knit wraps a Threads access token (full read + publish to your account — treat it like a
password).
- Headless / agent:
KNIT_TOKENenv, or… | knit auth login --token-stdin. - Browser: set
KNIT_CLIENT_ID/KNIT_CLIENT_SECRET(your Threads app), runknit auth login, open the printed URL, approve, paste the redirected URL back. No local server or cert. knit auth statustests the token and redacts it;knit auth refreshextends the 60-day token;knit auth logoutclears local creds (revoke upstream in Threads settings — see SECURITY.md).- Token storage: OS keyring →
0600file fallback (perms-warned). Secrets never via argv.
Getting a token (Meta app + tester setup) is walked through in the docs.
knit post list --json | jq '.data[] | {id, text}'
knit post list --select id,permalink --format tsv
knit search posts ai --json | jq -r '.scope' # "public" or "self"
knit insights account --json | jq '.data.followersCount'
knit reply hide <reply-id> --allow-mutations # idempotent
knit post delete <media-id> --allow-mutations # idempotent (gone == ok)
knit doctor --for-agent --json # config / token / connectivity0 ok · 2 usage · 3 empty · 4 auth required · 5 not found · 6 permission
(scope/advanced-access) · 7 rate limited (250/24h publish, 2200/24h search) · 12 mutation
blocked · 13 input required. Full table: knit schema.
knit ships an embedded usage contract: knit agent (or KNIT_HELP=agent knit) prints it;
knit schema is the structured command tree + exit codes + live safety state. Driving it from a
coding agent? See AGENTS.md.
PRs welcome — see CONTRIBUTING.md. For vulnerabilities, do not open a public issue: see SECURITY.md (private reporting + the secret-handling threat model).
MIT © Ryan Wolfe
