Self-hosted service
steipete/birdclaw avatar
steipete/birdclaw

birdclaw: a local SQLite memory for your Twitter/X archive

Stores all your tweets nicely claw-able for agents. It makes no network requests; run birdclaw serve afterward to browse the demo.

1,663 stars160 forksTypeScriptMIT

At a glance

What is it?
birdclaw imports a Twitter/X archive into local SQLite, searches it with FTS5, and serves it through a web app, CLI and read-only MCP server. It is for people who want their own history without a cloud backend, and it is honest about where the local-only boundary ends.
Who is it for?
Adopt birdclaw if you already have a Twitter/X archive zip and want searchable tweets, DMs, likes, bookmarks and follow edges on your own disk, with the demo and CLI giving you a zero-credential way to check the shape of the data first. Skip it if you need a hosted service, a full X API client, or write access from an agent: the MCP endpoint is read-only and live sync delegates to xurl or an existing private bird install.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 8 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem birdclaw solves: your own tweets, not X's copy

A Twitter/X archive download gives you a zip of JSON and media files. It is complete and it is nearly unusable. There is no query language, no full-text index, and no way to ask which accounts you followed in 2019 or which DM thread mentioned a specific project. The archive is a backup, not a memory.

birdclaw targets that gap. The README describes it as a tool for people who want their own searchable history, DMs, saved posts and follow graph without a cloud backend. That sentence defines the audience precisely: someone who has already requested their archive, or is willing to, and who would rather run a local process than hand their DM history to another service.

It is not a Twitter client. It does not try to replace the timeline. The framing in VISION.md, which the README points to for product boundaries, is the place to check whether your use case is in scope before you invest time in an import.

How birdclaw works: archive and live transports converging on SQLite

SQLite is the canonical store. That is the single most important architectural fact in the README, and it explains most of the tool's behaviour. Archive imports and live transports converge on the same tables, so a tweet that arrived from a zip file and a tweet that arrived from a live sync are the same kind of row. FTS5 powers local tweet and DM search.

The data flow has two entry points. The first is an archive zip, which establishes the account identity for a new real database and imports tweets, DMs, likes, bookmarks, profiles, media and follow edges. The second is live sync, which the README says delegates to xurl or an existing private bird installation and only runs when requested. Import an archive before the first live sync on a new database; that ordering is stated in the README, not optional advice.

Around that store sit four surfaces: a web app with home, mentions, saved posts, DMs, inbox, moderation and network views; a CLI with search, sync, moderation, research, JSON output and scheduled jobs; deterministic JSONL backup shards that round-trip through Git; and an MCP server exposing read-only cached tweet search and thread tools behind a dedicated token.

The privacy model is layered rather than absolute. Local reads do not trigger network traffic by default, the web server listens on loopback, live writes can be disabled with BIRDCLAW_DISABLE_LIVE_WRITES=1, and the MCP endpoint stays off until its token and public URL are configured. Each of those is a separate switch, which is good for control and mildly annoying if you assume one setting covers everything.

Installing birdclaw and running a first search

Homebrew is the shortest path on macOS and Linux, and the formula lives in the author's tap:

bash
brew install steipete/tap/birdclaw

The package is also on npm, which is the route to take if you already manage global Node tooling:

bash
npm install -g birdclaw

The README states that both installs retain a public Node.js contract of `>=26.5.1 <27`. That is a narrow window, and it is worth checking `node --version` before you install rather than after. Source development is a different story: it uses one checksum-pinned Bun `1.4.0-canary.1` build, with Node kept as a tested compatibility lane.

The fastest way to see whether the data model matches your expectations is the demo, which seeds sample tweets, DMs, profiles and links without credentials or network requests:

bash
birdclaw init --demo
birdclaw search tweets "local-first" --limit 3 --json
birdclaw serve

The search command returns JSON, so you can inspect the shape of a result before writing anything against it. The serve command starts the web app, and the README says to open <http://localhost:3000>. When you are ready for real data, point the importer at your archive zip:

bash
birdclaw import archive ~/Downloads/twitter-archive.zip --json

Imports are idempotent and merge destination-only rows by default. Selected re-imports and exact replacement are documented separately in the archive guide. Everything lives under `~/.birdclaw` unless you set `BIRDCLAW_HOME` to another root.

Where birdclaw stops: live sync, write access and the Node version window

The local-first claim is accurate for archive import and search, which work without an X login. Live sync is the exception. It delegates to xurl or an existing private bird installation, and the README says it only runs when requested. If you do not already have xurl set up, live sync is not a feature you get out of the box; the sign-in guide covers xurl setup and transport selection, and the sync guide covers caching, pagination and rate limits. Read both before assuming a sync command will work on a fresh machine.

The MCP server is read-only. It exposes cached tweet search and thread tools behind a dedicated token. If your goal is an agent that posts, replies or moderates on your behalf, birdclaw is the wrong layer, and the README does not present it as anything else.

The Node constraint is a real adoption cost. `>=26.5.1 <27` means the npm and Homebrew packages will refuse to run on an older LTS line, and it will also refuse a future major. Teams that pin Node centrally should verify the pin before adding birdclaw to a workflow.

Finally, the README does not document rollback for an import. Imports merge destination-only rows by default and are idempotent, which limits the damage of a repeated import, but exact replacement is a separate documented path. Test on a copy of the archive first if the database already holds data you care about.

birdclaw compared with a general archive viewer

The obvious alternative is any tool that reads a Twitter/X archive zip and presents it as a browsable timeline. Those tools typically stop at rendering: you get a chronological view and maybe a search box over the raw JSON. The difference in approach is where the data lives and what can query it.

birdclaw writes the archive into SQLite with FTS5 indexes, which means search is a database query rather than a scan over files, and it means the same store can hold rows that arrived from a live sync. That is what makes the CLI's JSON output, the scheduled jobs and the MCP tools possible on top of one dataset. A viewer that never builds an index cannot offer those surfaces without rebuilding them.

The cost of that design is that birdclaw owns a database. You get a schema, a home directory, a config file and a backup format to think about. If you only ever want to read your old tweets in order, a simpler viewer is less machinery. If you want to query your history, correlate DMs with tweets, or hand a read-only slice to an agent, the SQLite layer is the point.

Maintenance, licensing and what an upgrade actually costs

birdclaw is MIT licensed and published by Peter Steinberger. The README states plainly that it is not affiliated with X Corp. MIT terms are permissive, but the repository also ships a Bun canary toolchain and a Homebrew tap, and the README directs readers to the installation guide and the Bun canary reference for exact checksums, constraints and rollback boundaries. If you redistribute or vendor the project, those are the documents to read rather than assuming the npm package is the whole story. This is a description of what the repository states, not legal advice.

The last push was on 2026-08-08, and the most recent release listed is v0.12.1 on the same date. The version in package.json is 0.14.0, which is ahead of the release list, so the published tags and the repository state are not identical. That is normal for this project's cadence but worth knowing if you pin by version.

Upgrade cost concentrates in two places. The Node contract `>=26.5.1 <27` means a Node major bump is a breaking event for the npm install until the project widens the range. The source-development path depends on one checksum-pinned Bun canary, and the wrapper script refuses a newer rolling canary with a different checksum or revision. That pinning is deliberate, and it means contributors cannot casually move to the latest Bun. For users of the packaged CLI, the practical upgrade question is whether your Node version still falls inside the window.

Editorial conclusion

Adopt birdclaw if you already have a Twitter/X archive zip and want searchable tweets, DMs, likes, bookmarks and follow edges on your own disk, with the demo and CLI giving you a zero-credential way to check the shape of the data first. Skip it if you need a hosted service, a full X API client, or write access from an agent: the MCP endpoint is read-only and live sync delegates to xurl or an existing private bird install. Before committing, run birdclaw init --demo, then birdclaw import archive on a copy of your zip and confirm the row counts in the tables you actually care about, because the README does not document rollback for an import.

Frequently asked questions

Does birdclaw need an X login to work?

No. The README says archive import and local search work without an X login, and the demo seeds sample data without credentials or network requests. Live sync is the part that needs a transport, and it delegates to xurl or an existing private bird installation.

Where does birdclaw store its database and media?

The README states that birdclaw stores its database, configuration and media under `~/.birdclaw`, and that you can set `BIRDCLAW_HOME` to use another root.

Which Node.js version does birdclaw require?

The npm and Homebrew installs retain the public Node.js contract `>=26.5.1 <27`, according to the README. Source development instead uses a checksum-pinned Bun `1.4.0-canary.1` build, with Node kept as a tested compatibility lane.

Can an agent write to birdclaw through MCP?

No. The README describes the MCP server as exposing read-only cached tweet search and thread tools behind a dedicated token, and the endpoint remains off until its token and public URL are configured.

What happens if I import the same archive twice?

Imports are idempotent and merge destination-only rows by default, per the README. Selected re-imports and exact replacement are documented separately in the archive import guide.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/steipete-birdclaw.svg)](https://hysenlabs.com/projects/steipete-birdclaw)