CLI Spec
Designed with create-cli defaults:
- humans first
- scriptable
- stable
--json - diagnostics on stderr
- prompts only on TTY
#Name
birdclaw
#One-liner
birdclaw imports, syncs, searches, and operates on a local Twitter archive.
#Usage
birdclaw [global flags] <subcommand> [args]
#Global flags
-h, --help--version--json
#Config precedence
Command flags > environment overrides > user config
User config:
~/.birdclaw/config.json
#Env vars
BIRDCLAW_HOMEBIRDCLAW_CONFIGBIRDCLAW_ACTIONS_TRANSPORTBIRDCLAW_BIRD_COMMANDBIRDCLAW_BASH_COMMANDBIRDCLAW_MCP_TOKENBIRDCLAW_MCP_PUBLIC_URLBIRDCLAW_MCP_ACCOUNT
#Command tree
birdclaw init [--demo]
birdclaw auth status
birdclaw auth use <transport>
birdclaw import archive [path]
birdclaw import tweet <tweet-id-or-url...> --fxtwitter
birdclaw sync all
birdclaw sync tweets
birdclaw sync authored
birdclaw sync dms
birdclaw sync bookmarks
birdclaw sync likes
birdclaw sync timeline
birdclaw sync mentions
birdclaw sync mention-threads
birdclaw sync followers
birdclaw sync following
birdclaw sync lists
birdclaw lists list
birdclaw lists members [name]
birdclaw import tweet <tweet-id-or-url...> --fxtwitter
birdclaw import thread <tweet-id-or-url> --fxtwitter
birdclaw import conversation <tweet-id-or-url> --fxtwitter
birdclaw import profile <handle> --fxtwitter
birdclaw search tweets <query>
birdclaw search dms <query>
birdclaw discuss <query>
birdclaw today
birdclaw digest [today|24h|yesterday|week]
birdclaw mentions export [query]
birdclaw media fetch
birdclaw dms list
birdclaw mute <handle-or-id>
birdclaw unmute <handle-or-id>
birdclaw mutes list
birdclaw blocks list
birdclaw blocks add <handle-or-id>
birdclaw blocks remove <handle-or-id>
birdclaw ban <handle-or-id>
birdclaw unban <handle-or-id>
birdclaw show tweet <id>
birdclaw show thread <id>
birdclaw show dm <conversation-id>
birdclaw inbox
birdclaw serve
birdclaw graph summary
birdclaw graph events
birdclaw graph top-followers
birdclaw graph unfollowed
birdclaw graph non-mutual-following
birdclaw graph mutuals
birdclaw compose post
birdclaw compose reply <tweet-id>
birdclaw db stats
birdclaw db vacuum
birdclaw backup export --repo <path>
birdclaw backup sync --repo <path> --remote <url>
birdclaw backup import <path>
birdclaw backup validate <path>
birdclaw debug transport
#Subcommand semantics
#today
- alias for
digest today - streams Markdown as model tokens arrive
- uses
gpt-5.5, medium reasoning, and priority service tier by default - requires
OPENAI_API_KEY - excludes DMs unless
--include-dmsis passed - supports
--refresh,--model,--language <locale-id>,--max-tweets, and--max-links - reads the default report language from
BIRDCLAW_DIGEST_LANGUAGE
#digest [period]
- period:
today,24h,yesterday, orweek - accepts explicit
--since <iso>and--until <iso>windows - caches the final structured result by local context hash, model, reasoning effort, service tier, and canonical report language
- accepts the same language tag through
GET /api/period-digest?language=zh-CN --jsonsuppresses token streaming and emits the final envelope
#init
- create app dir
- create an empty DB
- write default config if absent
--demoseeds sample tweets, DMs, profiles, and links without authentication or network access- print useful next commands for the selected setup path
Account-capable commands accept --account <username> or a stored account ID. Set accounts.default in config.json for a reversible default; an explicit flag wins.
#import tweet <tweet-id-or-url...>
- disabled unless
--fxtwitteris passed on the same invocation - sends only requested public tweet IDs to the fixed read-only
https://api.fxtwitter.comservice - rejects custom origins, redirects, noncanonical URLs, and batches larger than 20 tweets
- stores
fxtwittersource markers intweet_sourcesanddata/tweet_sources.jsonlbackups - discloses requested IDs plus ordinary network metadata such as IP address and request time to the third-party service
See Public tweet import for the full privacy and capability boundary.
#import thread|conversation <tweet-id-or-url>
- disabled unless
--fxtwitteris passed on the same invocation - imports only positively observed public tweets through the fixed FxTwitter origin
- accepts
--limit <n>up to 1,000 and always reports the collection aspartialbecause the endpoint cannot prove exhaustion - preserves the upstream reply count and next cursor as evidence, never as completeness proof
#import profile <handle>
- disabled unless
--fxtwitteris passed on the same invocation - imports the named public profile object, not its statuses or another timeline
- rejects URLs, custom origins, private/account data, and write capabilities before network access
#auth status
- show transport availability
- show active account/profile
- never print secrets
#auth use <transport>
- set preferred moderation action transport
- allowed:
auto,xurl,bird
#backup export
- writes Git-friendly canonical JSONL text shards
- removes and rewrites the
data/directory in the backup repo - validates the manifest and file hashes by default
--commitcreates a Git commit in the backup repo--pushimplies commit and pushes the backup repo
birdclaw backup export --repo ~/Projects/birdclaw-store --commit --push
#backup sync
- clones/configures the backup Git repo when needed
- pulls the backup repo before reading
- merge-imports remote backup rows into local SQLite
- exports the local union back into deterministic text shards
- commits and pushes the backup repo
birdclaw backup sync --repo ~/Projects/backup-birdclaw --remote https://github.com/steipete/backup-birdclaw.git --json
Shard contract:
- tweets:
data/tweets/YYYY.jsonl - tweet provenance:
data/tweet_sources.jsonl - FxTwitter fetch/completeness metadata:
data/fxtwitter/fetches.jsonl - FxTwitter positive item observations:
data/fxtwitter/observations.jsonl - unknown tweet dates:
data/tweets/unknown.jsonl - tweet revisions:
data/tweet_revisions.jsonl - subordinate tweet tombstones:
data/tweet_subordinate_tombstones.jsonl - profiles:
data/profiles.jsonlincludes bio, follower/following counts, profile URL, location, verification type, structured URL entities, and raw profile JSON - affiliations:
data/profile_affiliations.jsonlincludes X badge/highlighted-label organization edges - identity history:
data/profile_snapshots.jsonlanddata/profile_bio_entities.jsonlpreserve profile-change states and extracted bio identity hints - collections:
data/collections/likes.jsonl,data/collections/bookmarks.jsonl - DMs:
data/dms/conversations.jsonlplusdata/dms/YYYY.jsonl - moderation:
data/moderation/blocks.jsonl,data/moderation/mutes.jsonl - no SQLite WAL/SHM, FTS shadow tables, or transient live cache rows
Backup auto-sync config lives in ~/.birdclaw/config.json:
{
"backup": {
"repoPath": "/Users/steipete/Projects/backup-birdclaw",
"remote": "https://github.com/steipete/backup-birdclaw.git",
"autoSync": true,
"staleAfterSeconds": 900
}
}
Read commands pull + merge only when the last backup check is stale. Data-changing commands run a full backup sync afterward. Set BIRDCLAW_BACKUP_AUTO_SYNC=0 to disable backup auto-sync for one process.
#local bird command
Live local likes, bookmarks, DMs, and moderation verification use bird on PATH by default. Override it with BIRDCLAW_BIRD_COMMAND or:
{
"mentions": {
"birdCommand": "/absolute/path/to/bird"
}
}
On Windows, Birdclaw runs the redirect wrapper through Git Bash. Common Git for Windows installations are detected automatically; set BIRDCLAW_BASH_COMMAND to the full path of bash.exe for a portable or non-standard installation.
#backup import
- validates the backup first unless
--no-validateis passed - merge-imports by default so local-only rows are not deleted
--restorerestores exactly from backup and deletes local portable rows first (--replaceremains a deprecated alias)- rebuilds tweet and DM FTS from the JSONL text
birdclaw backup import ~/Projects/birdclaw-store --json
#backup validate
- checks
manifest.json - checks every listed shard hash, byte count, row count, and JSONL parseability
- exits non-zero on validation failure
birdclaw backup validate ~/Projects/birdclaw-store --json
#import archive [path]
- validate archive
- analyze contents
- merge selected slices without deleting destination-only rows
- retain explicit deleted-tweet records as source-attributed tombstones; absence alone is never a deletion
- use
--restorefor deliberate exact replacement of the imported slices - stream bundled media files from
data/tweets_media/,data/direct_messages_media/,data/community_tweet_media/,data/deleted_tweets_media/,data/profile_media/,data/moments_tweets_media/, anddata/direct_messages_group_media/into~/.birdclaw/media/originals/archive/<kind>/<id>/<filename> - extract
extended_entities.media[].video_info.variants[]onto each tweet media row for archive video and animated GIFs - parse
data/follower.jsanddata/following.jsinto the local follow graph - idempotent
- path is optional; without one, macOS archive autodiscovery picks the newest likely ZIP
Flags:
--select <kinds>— comma-separated subset oftweets,likes,bookmarks,profiles,directMessages,followers,following
--select details:
- selected re-imports preserve unselected slices
- valid aliases for
directMessages:directmessages,direct-messages,dms - duplicate names are ignored
- empty values and unknown names exit as invalid usage
- merge imports and selected restores validate that existing
acct_primarymatches the archive account before writing; only a full--restoremay replace it - selected imports preserve compatible existing profile rows unless
profilesis selected
Examples:
birdclaw import archive --json
birdclaw import archive ~/Downloads/twitter-archive.zip --json
birdclaw import archive ~/Downloads/twitter-archive.zip --select tweets --json
birdclaw import archive ~/Downloads/twitter-archive.zip --select likes,bookmarks --json
birdclaw import archive ~/Downloads/twitter-archive.zip --select dms --json
birdclaw import archive ~/Downloads/twitter-archive.zip --select followers,following --json
#sync *
- fetch deltas
- update canonical tables
- refresh cursors
- refresh FTS incrementally
sync likesandsync bookmarksuse cached live transport;autotriesxurl, thenbird;--early-stopcaps at 10 pages unless paired with--allor--max-pagessync authoredusesxurl, includes retweets, and resumes from a storedsince_idsync timelinestores the live home timeline throughbird; it defaults to the chronological Following feedsync mentionsingests recent mentions throughxurl(default) orbirdand writeskind='mention'rows into the canonical store; this is the cron-friendly ingest path that replaces relying onmentions export --refreshsync mention-threadsfetches conversation context for recent mentions throughbird threadorxurl; pass--mode xurlwhen thebirdCLI is unavailable, otherwise use--delay-msand--timeout-msto stay gentle on live Xsync followersandsync followingdefault to dry-run and require--yesfor live sync or fresh-cache merge;autoprefersbird, then falls back toxurlsync listsis an explicit read-only walk; it defaults to 20 members, one page, and 1,000 ms pacing per List, and storescomplete|inferred|partial|errormembership state
Common flags:
--since <cursor-or-id>--limit <n>--transport <kind>--dry-run--mode auto|xurl|bird--all--max-pages <n>--early-stop(onsync likesandsync bookmarks)--refresh--cache-ttl <seconds>
Examples:
birdclaw sync authored --mode xurl --limit 100 --json
birdclaw sync likes --mode auto --limit 100 --refresh --json
birdclaw sync likes --mode auto --limit 100 --max-pages 5 --early-stop --refresh --json
birdclaw sync bookmarks --mode auto --limit 100 --refresh --json
birdclaw sync bookmarks --mode auto --limit 100 --max-pages 5 --early-stop --refresh --json
birdclaw sync bookmarks --mode bird --all --max-pages 5 --limit 100 --refresh --json
birdclaw sync timeline --limit 100 --refresh --json
birdclaw sync mentions --mode xurl --limit 100 --max-pages 3 --refresh --json
birdclaw sync mention-threads --mode bird --limit 30 --delay-ms 1500 --timeout-ms 15000 --json
birdclaw sync mention-threads --mode xurl --limit 30 --json
birdclaw sync lists --mode auto --max-lists 20 --member-limit 20 --max-member-pages 1 --delay-ms 1000 --json
Follow graph examples:
birdclaw sync followers --json
birdclaw sync following --json
birdclaw sync followers --yes --json
birdclaw sync following --yes --json
birdclaw sync followers --mode bird --yes --json
birdclaw sync followers --yes --max-pages 1 --allow-partial --json
birdclaw sync followers --yes --refresh --json
Follow graph sync uses a 24-hour cache by default. Repeating the same sync command with --yes reuses fresh cache unless --refresh is passed, which prevents duplicate live reads during agent workflows.
--allow-partial acknowledges capped/incomplete snapshots and suppresses the warning. Incomplete snapshots are still recorded for audit, but they are not used for churn events.
#jobs sync-account
- refreshes home timeline, mentions, mention threads, likes, bookmarks, and DMs for one account
- appends one JSONL audit entry per run to
~/.birdclaw/audit/account-sync.jsonl - records each step independently with count, source, and error
- uses
~/.birdclaw/locks/account-sync.lockto skip overlapping runs - requires
--allow-bird-accountbefore Bird-backed steps write to a non-default--account - exits non-zero when any step failed
Examples:
birdclaw --json jobs sync-account --account acct_openclaw --limit 100 --max-pages 3 --refresh --allow-bird-account
tail -n 20 ~/.birdclaw/audit/account-sync.jsonl | jq .
#jobs install-account-launchd
- writes
~/Library/LaunchAgents/com.steipete.birdclaw.account-sync.plist - runs
jobs sync-accountevery 30 minutes by default - uses
launchctl load -wunless--no-loadis passed --steps <steps>narrows the scheduled surfaces--env-path <path>sources account-specificbirdcookies for launchd--allow-bird-accountasserts those cookies match--accountfor Bird-backed timeline, mentions, and DM steps
birdclaw --json jobs install-account-launchd --account acct_openclaw --program /opt/homebrew/bin/birdclaw --env-path ~/.config/bird/openclaw.env --allow-bird-account
#jobs sync-bookmarks
- runs a live bookmark refresh with scheduler-friendly defaults
- appends one JSONL audit entry per run
- records host, timestamps, duration, before/after bookmark counts, transport source, fetched count, backup sync result, and errors
- uses
~/.birdclaw/locks/bookmarks-sync.lockto skip overlapping runs - exits non-zero when the sync failed
Default audit log:
~/.birdclaw/audit/bookmarks-sync.jsonl
Examples:
birdclaw --json jobs sync-bookmarks --mode auto --limit 100 --max-pages 5 --refresh
tail -n 20 ~/.birdclaw/audit/bookmarks-sync.jsonl | jq .
#jobs install-bookmarks-launchd
- writes
~/Library/LaunchAgents/com.steipete.birdclaw.bookmarks-sync.plist - runs
jobs sync-bookmarksevery 3 hours by default - uses
launchctl load -wunless--no-loadis passed - writes launchd stdout/stderr to
~/.birdclaw/logs/bookmarks-sync.*.log --env-path <path>sources an export-only shell env file inside the scheduled process, useful whenbirdneedsAUTH_TOKEN/CT0outside an interactive browser session
birdclaw --json jobs install-bookmarks-launchd --program /opt/homebrew/bin/birdclaw
#search tweets <query>
Flags:
--author <handle-or-id>--account <accountId>--list <name>--list-id <id>--since <date>--until <date>--originals-only--hide-low-quality--liked--bookmarked--fxtwitter(explicit public-service opt-in)--max-pages <n>(FxTwitter only, maximum 10)--feed latest|top|media(FxTwitter only)--limit <n>
Examples:
birdclaw search tweets --liked --limit 20 --json
birdclaw search tweets --bookmarked --limit 20 --json
birdclaw search tweets "sqlite" --list Builders --limit 50 --json
birdclaw search tweets "local-first" --fxtwitter --limit 50 --max-pages 3 --json
#search dms <query>
Flags:
--participant <handle-or-id>--min-followers <n>--max-followers <n>--min-influence-score <n>--max-influence-score <n>--sort recent|followers--context <n>--resolve-profiles--expand-urls--refresh-profile-cache--refresh-url-cache--no-xurl-fallback--replied--unreplied--limit <n>
Profile resolution reads the local profile row first, then the persistent lookup cache, then bird user, then xurl unless --no-xurl-fallback is set. Failed lookups are cached briefly so repeated searches do not keep spending live calls. Resolved profile rows store bio, profile URL, location, verification type, structured X URL entities, raw profile JSON, and affiliation badge metadata when the live transport exposes it.
#discuss <query>
Fetch live keyword matches through bird or xurl, store them as local search tweets, then stream an OpenAI Markdown summary and discussion. DMs stay out unless explicitly requested.
Flags:
--account <account-id>--source all|search|home|mentions|authored|likes|bookmarks--mode auto|bird|xurl|local--include-dms--since <date>/--until <date>--question <prompt>--originals-only--hide-low-quality--refresh--model <model>--limit <n>--max-pages <n>
Examples:
birdclaw discuss "local-first" --mode bird
birdclaw discuss "sync engine" --question "what changed over time?"
birdclaw discuss "prototype" --include-dms --limit 500 --max-pages 5 --json
#whois <query>
Find likely people or orgs from local DM and optional tweet evidence. Candidates include structured profileEvidence entries for profile bio, profile URL, bio URLs, location, verified type, first-class affiliations, bio entities, profile-history snapshots, DM context, and expanded URLs. whois also searches significant terms from fuzzy prompts, so blacksmith guy can rank a match from @useblacksmith and blacksmith.sh even when the literal phrase was not stored in a DM. Query intent changes ranking: @github emphasizes handle and affiliation evidence, github.com emphasizes URL/domain evidence, and github guy emphasizes people/org affiliation evidence. Human output explains "why this person?" and buckets candidates as likely affiliated, ecosystem, profile/link-only, DM context, or other local matches.
Flags:
--account <account-id>--no-dms--tweets--no-resolve-profiles--no-expand-urls--refresh-profile-cache--refresh-url-cache--no-xurl-fallback--affiliation <query>- require current/bio/history affiliation evidence--current-affiliation <query>- require an active affiliation badge edge--exclude-domain-only- drop candidates that only matched domains or URLs--context <n>--limit <n>
Examples:
birdclaw whois blacksmith --context 4 --no-xurl-fallback --json
birdclaw whois "blacksmith guy" --context 4 --no-xurl-fallback --json
birdclaw whois "github guy" --current-affiliation github --exclude-domain-only
birdclaw whois blacksmith --tweets --no-xurl-fallback
#mentions export [query]
- export local mention tweets for scripts and agents
- always emits JSON
- supports
birdclaw, cachedxurl, or cachedbirdoutput - each item includes:
- raw
text - rendered
plainText - rendered
markdown - canonical tweet URL
- author and reply-state metadata
Flags:
--account <account-id>--mode birdclaw|xurl|bird--replied--unreplied--refresh--cache-ttl <seconds>--all--max-pages <n>--limit <n>
Examples:
birdclaw mentions export "agent" --unreplied --limit 10
birdclaw mentions export --mode bird --limit 20
birdclaw mentions export --mode xurl --limit 5
birdclaw mentions export "codex" --mode xurl --limit 5
birdclaw mentions export --mode xurl --refresh --cache-ttl 30 --limit 5
birdclaw mentions export --mode xurl --refresh --all --max-pages 9 --limit 100
Notes:
--mode xurlmirrors thexurl mentionsresponse shape:data,includes.users,meta--mode birdshells out to your localbirdCLI, normalizes the JSON to that samexurl-compatible shape, then caches it in SQLite- payload is cached in local SQLite and reused until the cache TTL expires
--refreshbypasses the cache and fetches live mentions immediately--allkeeps paginating until the retrievable mentions window is exhausted--max-pageslimits that paged xurl scan and implies--all- in paged
xurlmode,--limitis the page size, not the total returned item count - query and reply-state filters still work in
xurlmode, but the filtered response is rebuilt from the local canonical store after sync - default live source can live in
~/.birdclaw/config.jsonundermentions.dataSource
#media fetch
- fill the local originals cache for images, videos, and animated GIFs whose tweets already live in the local SQLite store
- reuse bytes already extracted by
import archivebefore falling back to the CDN; reuses are counted in JSON output asreused_from_archiveand spend zero CDN bandwidth - only fetch URLs birdclaw already has from an archive or live sync record; never enumerate, crawl, or derive CDN URLs
- skip files already present on disk; resume partial downloads with
Range: bytes=<size>- - back off on
429; cap each file at--max-bytes
Flags:
--account <accountId>--limit <n>- stop after N tweets processed--kind <kind>- tweet/collection kind, e.g.home,like,bookmark,mention--since <isoDate>- only consider tweets created at or after this date--parallel <n>- concurrent image workers, capped at 5 (default1)--pacing-ms <n>- delay between image request starts (default250)--video-pacing-ms <n>- separate delay between video request starts--retry-max <n>- retries per file after rate limiting (default3)--include-video/--no-include-video- videos and animated GIFs are on by default--max-bytes <n>- per-file size cap in bytes (default104857600)--dry-run- list what would be fetched without downloading--json
JSON output carries images_fetched, videos_fetched, gifs_fetched, reused_from_archive, skipped_cached, failed, rate_limited, per-kind byte counters, and a failures[] array. See Media for the full pipeline.
Examples:
birdclaw media fetch --json
birdclaw media fetch --dry-run --limit 20
birdclaw media fetch --include-video --video-pacing-ms 1500 --max-bytes 209715200 --json
birdclaw media fetch --no-include-video --parallel 3 --pacing-ms 250 --json
#profiles replies <handle-or-id>
- inspect a profile's recent authored replies when one mention feels borderline
- moderation-first: scans the live authored tweet timeline, excludes retweets, keeps reply tweets only
- good for spotting templated AI cadence across unrelated conversations
- supports
--json
Flags:
--account <username>— account username or stored ID--limit <n>
Examples:
birdclaw profiles replies @jpctan --limit 12 --json
#dms list
- list DM conversations or events without requiring a full-text query
- optimized for agent and operator filtering
- optionally refreshes live DMs before listing
Flags:
--refresh--mode bird|xurl|auto--cache-ttl <seconds>--participant <handle-or-id>--min-followers <n>--max-followers <n>--min-influence-score <n>--max-influence-score <n>--sort recent|followers--replied--unreplied--account <name>--limit <n>
#dms sync
- refresh live direct messages
- merge conversations/messages into the local SQLite store
- supports
--json
Flags:
--account <account-id>--mode bird|xurl|auto--limit <n>--refresh--cache-ttl <seconds>
--mode bird is the default and the only mode that can sync message requests. --mode xurl reads recent OAuth2 /2/dm_events as accepted conversations; --mode auto tries xurl first for accepted DMs and falls back to bird.
#inbox
- show AI-ranked actionable queue
- supports
--json - supports
--limit - supports
--kind mentions|dms|mixed - supports replied/unreplied filters
- supports
--scoreto refresh stored OpenAI scores before listing - supports
--min-scoreand--hide-low-signal
#blocks list
- list current local blocked profiles
- account-scoped
- supports
--json
Flags:
--account <account-id>--search <query>--limit <n>
#blocks add <handle-or-id>
- add a local block entry for one account
- accepts handle,
@handle, Twitter URL, local profile id, or numeric Twitter user id - attempts live block transport via
xurlwhen resolvable - falls back to the Twitter web cookie session if
xurlis rejected for OAuth2 block writes - still records the local block if live transport is unavailable
Flags:
--account <account-id>
#blocks import <path>
- import a blocklist file in one call
- reads newline-delimited handles, ids, or Twitter URLs
- ignores blank lines and
#comments - tolerates markdown bullets like
- @handle - returns per-entry success/failure in
--json
Flags:
--account <account-id>
#blocks remove <handle-or-id>
- remove a local block entry for one account
- attempts live unblock transport via
xurlwhen resolvable - falls back to the Twitter web cookie session if
xurlis rejected for OAuth2 block writes
Flags:
--account <account-id>
#ban <handle-or-id> / unban <handle-or-id>
- shorthand aliases for
blocks addandblocks remove - useful when you want one obvious moderation verb from the CLI
Flags:
--account <account-id>
#mutes list
- list current local muted profiles
- account-scoped
- supports
--json
Flags:
--account <account-id>--search <query>--limit <n>
#mute <handle-or-id>
- add a local mute entry for one account
- accepts handle,
@handle, Twitter URL, local profile id, or numeric Twitter user id - resolves remote targets via
bird user --jsonbefore falling back toxurl /2/users --transport autotriesbirdfirst, thenxurl- still records the local mute if live transport is unavailable
Flags:
--account <account-id>
#unmute <handle-or-id>
- remove a local mute entry for one account
--transport autotriesbirdfirst, thenxurl
Flags:
--account <account-id>
#serve
- starts local app server
- starts the built production SSR and static-asset server
- stdout prints the listening URL
Flags:
--host <host>--port <port>
birdclaw serve binds the production server to 127.0.0.1:3000 by default and enables local loopback web APIs without a token. BIRDCLAW_HOST and BIRDCLAW_PORT provide environment defaults. Remote access through a trusted private proxy requires BIRDCLAW_ALLOW_REMOTE_WEB=1. To require an app-level token too, set BIRDCLAW_WEB_TOKEN and send it as x-birdclaw-token or a birdclaw_token cookie.
The same process can expose an adapter-owned, read-only Streamable HTTP MCP endpoint at the exact path /mcp. Configure both BIRDCLAW_MCP_TOKEN and BIRDCLAW_MCP_PUBLIC_URL; the MCP token must be at least 32 bytes and must differ from BIRDCLAW_WEB_TOKEN. BIRDCLAW_MCP_ACCOUNT optionally selects one server-side account by id or handle; otherwise tools read the default account.
When MCP is configured, startup validates the configuration, selected account, and an existing initialized database at the current schema. It does not create or migrate the database for MCP. Run birdclaw init or import/migrate with a trusted CLI command before starting the server.
HTTP MCP URLs are accepted only for loopback hosts. External MCP URLs must use HTTPS on a dedicated hostname. Birdclaw reserves that configured hostname for MCP and denies every path except /mcp; the proxy and outer authentication policy must enforce the same rule. See the MCP server guide.
#graph summary
- cache-only SQLite read
- current followers/following counts
- mutuals and non-mutual following counts
- last complete and incomplete snapshot times
#graph top-followers
- cache-only SQLite read
- current followers sorted by their
public_metrics.followers_count - supports
--limit
#graph unfollowed
- cache-only SQLite read
- append-only ended follow edges since
--date - defaults to
followers; pass--direction followingfor outbound ended edges
#graph events
- cache-only SQLite read
- append-only
startedandendedfollow graph history - supports
--direction followers|following,--kind started|ended,--since,--until, and--limit
#graph mutuals
- cache-only SQLite read
- current mutuals
- sorted by follower size
#graph non-mutual-following
- cache-only SQLite read
- current following profiles that are not current followers
- supports
--sort followers|handle
Agent rule: use graph commands for analysis. Ask for explicit user approval before sync ... --yes --refresh, because that can spend live X API reads.
#I/O contract
stdout:
- primary data
- URLs
- JSON output
stderr:
- progress
- warnings
- diagnostics
- auth hints
#Output modes
- default human output
--jsonstable machine-readable envelopes--plainstable line-oriented text, no color
#Exit codes
0success1runtime failure2invalid usage / validation3auth unavailable4transport unavailable5partial sync failure
#Examples
birdclaw init
birdclaw init --demo
birdclaw auth status
birdclaw import archive ~/Downloads/twitter-archive.zip --select tweets,directMessages
birdclaw sync all --transport xurl
birdclaw search tweets "openai" --since 2024-01-01 --limit 20
birdclaw search tweets --since 2020-01-01 --until 2021-01-01 --originals-only --hide-low-quality --limit 500
birdclaw search dms "invoice" --participant @someone --min-followers 1000
birdclaw dms list --unreplied --min-followers 500 --min-influence-score 90 --sort followers
birdclaw inbox --json
birdclaw serve
birdclaw graph events --json
birdclaw compose reply 1891234567890