I bookmark too many things on X.
Some of them are useful. Most of them turn into a second inbox I never process.
That is the exact kind of workflow I want Build Lean SaaS to cover: small, practical, slightly scrappy automations that turn attention into something operational. Not a giant product. Not a month-long platform build. A real workflow that can run every morning and put saved ideas where work actually happens.
If you want this to run every day without depending on your laptop, start with Codex on a VPS: Set Up an Always-On AI Development Box, then Connect Hermes to Discord. The bookmark sync stores OAuth tokens and processed tweet IDs locally, and the Discord channel gives Hermes somewhere to report what it captures.
Follow the Always-On Agents course path
Follow the complete public course path, install the skills as you go, and use DevelopJoy when you want the workflow wired into your actual VPS.
The project is simple:
- Read my X bookmarks once per day.
- Skip anything already processed.
- Create raw capture issues in Linear Triage.
- Post the reviewable captures into Discord so a human can discuss what deserves real work.
I also turned it into a small installable skill:
The public page explains the workflow. The repo folder contains the actual SKILL.md and script.
This is intentionally a raw capture bot. It is not a posting bot, not a general X automation system, and not an AI task generator. The job is to move saved source material into the place where work gets triaged.
The first version is free on purpose. The paid opportunity is not hiding the source. It is helping people install it, keep their agent workspace current, and adapt the workflow to their own tools through pair-programming support and done-for-you focus sprints from DevelopJoy.
Who this is for
This is for builders who already use X bookmarks as a research inbox and Linear as the place where work gets triaged.
It is a good fit if:
- You want saved posts to become reviewable Linear Triage items.
- You are comfortable creating an X Developer app and a Linear API key.
- You want a cron-friendly script instead of a hosted product.
- You want a deterministic capture step before any AI agent starts rewriting tasks.
It is not a good fit if you want a posting bot, a social media automation suite, or a fully hosted bookmark manager.
Why X bookmarks are a good automation target
Bookmarks are usually not finished tasks. They are sparks.
That makes them a bad fit for a project backlog and a good fit for an inbox. I do not want every saved post to become a committed task. I want it to become a reviewable item with source context, so I can decide later whether it is an idea, a note, a content angle, a bug, a feature, or noise.
Linear Triage is a good default target because it is built for incoming work. The sync creates raw issues. I can accept, decline, merge, label, or rewrite them later.
That distinction matters. The first version should capture bookmarks, not pretend every bookmark is already a clear task.
What the X API gives you for bookmarks
The endpoint we care about is:
For a personal automation, you authenticate with OAuth 2.0 and ask for these scopes:
The offline.access scope matters because the cron job needs a refresh token. Without it, the script can work once and then fail when the access token expires.
The useful request shape is:
Use max_results=100. That is enough for the daily run if you add fewer than 100 bookmarks per day, and it keeps the request count low during a backlog import.
What does this cost?
Last verified on May 9, 2026: X API access is mostly pay-as-you-go through credits. For your own account data, X documents Owned Reads pricing, and owned reads are currently priced at $0.001 per returned resource.
For this workflow, the cost is driven by the number of bookmarks returned.
If you have about 500 existing bookmarks:
If your daily sync reads one full page:
That is roughly $3/month if the first page is always full.
| Scenario | API shape | Estimated X API cost |
|---|---|---|
| First backlog clear | 500 returned bookmarks | About $0.50 |
| Normal daily run | Up to 100 returned bookmarks | Up to about $0.10/day |
| Full month at one full page/day | 3,000 returned bookmarks | About $3/month |
In practice, if you add fewer than 100 bookmarks per day, the cost is still tiny compared with the value of not losing the ideas. The important thing is to treat X as a paid dependency and keep the sync boring: one daily run, one page by default, explicit backfill when you need it.
Before production use, check the X Developer Console for your own app's current prices, credits, and endpoint access. X API pricing and access rules change often enough that your console should be treated as the source of truth.
Should the script delete bookmarks after syncing?
Not in v1.
Deleting bookmarks would make the X bookmark list behave more like an inbox queue. It could also reduce future read cost because the first page would stay smaller.
But deletion changes the trust model. It requires bookmark.write, and a bug could remove saved posts you expected to keep.
So the first version is read-only against X. It stores processed tweet IDs locally and leaves your bookmarks alone. Once the read-only version has proven itself, an opt-in delete mode can be a separate change.
The actual workflow
The sync is intentionally small.
The local state file stores two things:
- X OAuth token data.
- Processed tweet IDs.
- Linear issue identifiers and URLs for bookmarks already captured.
That is enough for a personal cron job. No database. No queue. No hosted service.
Linear issue shape
Each bookmark becomes a raw capture issue.
The title is short:
The description includes:
- Source marker:
x-bookmark-capture-sync - X URL
- Author
- Tweet text
- Tweet ID
- Posted date when available
The script omits stateId when creating the Linear issue. With Linear Triage enabled for the team, that lets the item land in Triage instead of pretending it belongs in a committed workflow state.
Install the skill
The installable source lives in:
To install from the public Build Lean SaaS skill files:
For OpenClaw-style usage, keep the folder shape and point the agent at the SKILL.md.
Want help getting this running in your agent workspace?
The source is free. Pair with DevelopJoy when you want guided setup, or use a focus sprint when you want the workflow implemented for you.
Build it with us
Pair-programming lab
$100/moHave us build it
Done-for-you focus sprint
Starts at $500/moRequirements before you start
You need a few pieces in place before the commands below will work:
| Requirement | Why it matters |
|---|---|
| X Developer account and app | Creates the OAuth client used to read your own bookmarks. |
| X API credits | Bookmark reads are paid owned reads under the current pricing model. |
| OAuth 2.0 callback URL | Lets you approve access and receive the code and state values. |
| Linear API key | Lets the script create issues through Linear's GraphQL API. |
| Linear team ID | Tells Linear which team's Triage inbox receives the captures. |
| Node.js | Runs the bundled .mjs script. |
| cron or another scheduler | Runs the sync once per day after the manual test works. |
The script intentionally stores state locally. If you run it on a server, keep the state file on persistent storage so processed bookmarks and OAuth refresh tokens survive deploys.
Configure it
Create an X API app with OAuth 2.0 enabled. Add your local callback URL in the X Developer Console.
Then export:
Optional:
Verify before creating issues
Start with help output:
Then run a dry run:
Dry run fetches bookmarks and prints the Linear issues it would create. It does not call Linear, does not create issues, and does not mark bookmarks as processed.
I tested the script locally with these checks before publishing:
The expected behavior is boring: help prints, invalid page counts fail clearly, exchange requires --state, and dry runs avoid Linear writes.
Authorize X
From the skill folder:
Open the printed URL, approve access, and copy the code value from the callback URL.
Then copy both code and state from the callback URL and run:
That stores the refresh token in the local state file.
Run the daily sync
For normal daily use:
That fetches the first page of bookmarks.
If your local state is already warm, you can stop once the script sees a bookmark it already processed:
If you want a smaller paid read on the daily run, lower the page size:
If you want the daily job to inspect more than one page:
For the initial backlog:
If you want to keep the first test small:
For a safe first backlog test:
Add the cron job
Use a daily cron once the manual run works.
That gives you a daily Linear Triage inbox item for each new bookmark without turning X into another place you have to remember to process.
Troubleshooting
OAuth says the code verifier is missing.
Run auth-url again from the same environment where you will run exchange. The script stores the PKCE verifier in the local state file.
OAuth says the state is missing or mismatched.
Copy both code and state from the same callback URL. If you opened multiple authorization URLs, use the newest one and rerun auth-url if needed.
The cron job works manually but fails overnight.
Cron often runs with a smaller environment than your shell. Use absolute paths, export the required environment variables inside the cron context, and send logs to a file.
Linear issues are created but not landing in Triage.
Confirm Triage is enabled for the target team. The script intentionally omits stateId; Linear decides whether that becomes a Triage item for the team.
The daily run costs more than expected.
Lower --page-size, use --stop-after-seen, and avoid unnecessary backfills. The script dedupes Linear issues locally, but X can still charge for resources returned by the API.
You want to delete bookmarks after syncing.
Do not bolt that onto the read-only flow casually. Deletion requires bookmark.write and should be a separate opt-in mode after the capture workflow has proven itself.
What I would add next
The useful next version is not a bigger dashboard.
I would add:
- Optional bookmark deletion after successful Linear creation.
- A second agent skill that turns raw bookmark captures into scoped tasks.
The first version should stay boring. Capture the thing. Put it where work happens. Process it later.
That is the whole point of this Build Lean SaaS experiment: build content around small automations we actually use, then ship the reusable artifact alongside the article.
The follow-up: agent triage
The next workflow is where Hermes, Codex, or another agent runner becomes useful inside the Discord review room.
The capture bot should stay deterministic. Then a separate heartbeat can process the raw Linear Triage items:
- Read new issues created by
x-bookmark-capture-sync. - Score each bookmark for usefulness, novelty, implementation value, documentation value, and actionability.
- Ask clarifying questions in Discord when a bookmark looks promising but underspecified.
- Convert standout items into documentation tasks, implementation tasks, research tasks, or product notes.
- Leave low-value captures alone or label them for later cleanup.
That separation keeps the first workflow cheap and trustworthy. The agent only enters once the source material is already captured and visible in the Discord/Linear review loop.
I shipped that follow-up as the companion skill:
The full walkalong implementation is here:
References
- X API pricing
- X bookmarks endpoint
- X API rate limits
- X OAuth 2.0 authorization code flow
- Linear GraphQL API
- Linear Triage
Use the skill
Start with the install page:
Then run it manually once before trusting cron.
