# MindPocket: a bookmark system that runs entirely on four Cloudflare resources

> A TypeScript monorepo where one Cloudflare Worker serves both a Next.js static export and a Hono API, backed by D1, Vectorize and R2, with an npm CLI and a repository-scoped agent skill on top. The README's own command lists have drifted from package.json, and the clone command still points at a placeholder.

**jihe520/mindpocket** — Open-source, free, multi-platform, one-click deploy, AI Agent–integrated personal bookmarking system｜完全开源、免费、多端、一键部署、AI Agent 集成的个人收藏夹系统

- Repository: https://github.com/jihe520/mindpocket
- Website: https://mindpocket.top
- Stars: 352 · Forks: 178
- Language: TypeScript
- License: not declared
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/jihe520-mindpocket

## Four Cloudflare products stand in for a database and an object store

The architecture is one Worker plus three storage products, and the substitutions are named rather than hidden. Workers plus Static Assets serve the Hono API and the Next.js static export from the same deployment, with a free tier of 100k requests a day. D1 holds the relational data as SQLite at 5 GB. Vectorize does the vector search and is described as replacing pgvector, at 30M queried dimensions a month. R2 stores files and replaces MinIO, at 10 GB.

Those replacement notes are aimed at people arriving from elsewhere. A full guide exists at docs/CLOUDFLARE.md, including migrating data from a previous self-hosted Postgres and MinIO setup, so the two backends named in the table are the ones an existing installation would have had.

The RAG part is what the storage is for. Bookmarks are organised with AI powered content summarisation and automatic tag generation, so the vector index is not decoration: it is how a saved page becomes searchable by what it says rather than by its title. The Vercel AI SDK is in the API stack for those model calls, Better Auth handles accounts, and Drizzle ORM sits on top of D1 as the schema layer. The web side is a Next.js 16 static export with Radix UI, Tailwind CSS 4 and Zustand, and the mobile and extension clients are Expo with React Native and Expo Router, and WXT with Vite.

One Worker means there is no separate frontend deployment to secure or fund. The static export and the API share one origin, so the page that lists a bookmark and the request that saved it are served from the same hostname, which is also why NEXT_PUBLIC_APP_URL is one of the three values you hand-edit in wrangler.jsonc.

## Four resources get created before any of your code runs

The quick start is one block of wrangler commands, and each line creates something you will later have to name in a config file:

```bash
# 1. One-time resource setup (D1 / Vectorize / R2), see docs/CLOUDFLARE.md
cd apps/api
pnpm exec wrangler d1 create mindpocket
pnpm exec wrangler vectorize create mindpocket-embeddings --dimensions=1024 --metric=cosine
pnpm exec wrangler vectorize create-metadata-index mindpocket-embeddings --property-name=userId --type=string
pnpm exec wrangler r2 bucket create mindpocket
pnpm exec wrangler secret put BETTER_AUTH_SECRET

# 2. Fill database_id / R2_PUBLIC_URL / NEXT_PUBLIC_APP_URL in apps/api/wrangler.jsonc

# 3. Apply migrations & deploy (from repo root)
pnpm --filter api db:migrate:r
```

Two details in there are worth reading twice. The vector index is created at 1024 dimensions with cosine metric, and then a separate metadata index is created on userId as a string, which is how per-user filtering happens without scanning every vector. And the auth secret is set through wrangler secret rather than written into wrangler.jsonc, while three other values, database_id, R2_PUBLIC_URL and NEXT_PUBLIC_APP_URL, do go into that config file by hand.

Compare that with the feature list, which calls the project serverless and one-command deployable. For the day-to-day case that is true, since deploy:cf rebuilds and pushes the Worker in one step. For the first run it is not: there are four resources to create, a secret to set, a metadata index to define, three config values to paste and a migration to apply, in that order, before a single request can be served. The gap between those two claims is the cost of the free tier, not a contradiction, but it is the difference between a five minute setup and a half hour one.

## The local setup block still clones from a placeholder

Local development needs Node.js 18 or newer and pnpm 10.9.0, and the installation block starts like this:

```bash
# Clone repository
git clone https://github.com/yourusername/mindpocket.git
cd mindpocket

# Install dependencies
pnpm install

# Local secrets
echo "BETTER_AUTH_SECRET=dev-secret" > apps/api/.dev.vars

# Initialize local D1 database
pnpm --filter api db:migrate:local

# Start the API worker (serves static assets + /api/*)
pnpm --filter api dev
```

The clone URL is https://github.com/yourusername/mindpocket.git, with yourusername where the owner should be. Every other command in the block is concrete, so the one that fails is the first one, and it fails by cloning something that does not exist. Replacing it with the jihe520 owner is a one-line edit.

The rest of the local loop is coherent: .dev.vars holds the local secret, db:migrate:local applies migrations to the local D1 simulation, and wrangler dev serves both the static assets and the /api paths on http://127.0.0.1:8787. Frontend hot reload is a second process, pnpm --filter web dev on port 3000.

Two ports for one product is the cost of splitting the frontend from the API worker, and it only applies to development: in production pnpm deploy:cf builds the types package, then the web export, then deploys the API, and the static export ends up inside the same Worker.

## The CLI opens with three commands that all diagnose

MindPocket ships an npm package called mindpocket, installed globally with npm install -g mindpocket or pnpm add -g mindpocket. The client is aimed at agents, scripts and developers talking to a server from a terminal.

The order of the quick start is the design. Three of the early commands are diagnostics rather than actions:

```bash
mindpocket version
mindpocket schema
mindpocket doctor
mindpocket --help
mindpocket config set server https://your-domain.com
mindpocket auth login
mindpocket user me
mindpocket bookmarks list
```

version reports the build, schema exposes what the server supports, and doctor checks readiness, so an agent can find out what it is allowed to call before it calls anything. The recommended agent flow repeats the first three and then logs in with auth login --no-open, which is the same command as auth login with browser opening suppressed, the difference that matters when nobody is sitting at the terminal.

Server URL and credentials are set explicitly with config set server and auth login, so the CLI is not implicitly bound to the deployment it was installed from.

The package is built from inside the monorepo rather than written as a standalone project. The root scripts handle it: cli:build runs pnpm --filter mindpocket build, cli:pack does npm pack --dry-run inside apps/cli to preview the contents, and cli:publish:dry-run runs npm publish --dry-run against the same directory. So what lands on npm is previewable before anyone publishes it.

## The agent skill is guidance, and it still needs the binary

There is a second interface on top of the CLI: a repository-scoped agent skill named mindpocket. It is installed with skills.sh pointing at this repository:

```bash
npx skills add https://github.com/jihe520/mindpocket --skill mindpocket
```

and from a local checkout with npx skills add ./skills/mindpocket. What it teaches is procedural: discover commands with schema, verify readiness with doctor, configure the server, handle auth safely, and drive bookmark and folder workflows through the published CLI.

The limitation is stated on the page and is worth repeating here. The skill is procedural guidance layered on top of the npm CLI, so users still need the mindpocket command available locally. Installing the skill does not install the package, which means an agent following it on a fresh machine still has to find a binary, and the two can drift apart in version without anything noticing.

The example prompts are correspondingly narrow: list the latest ten bookmarks, or help configure the server and log in.

The repository is itself configured for coding agents. Alongside skills/ and skills-lock.json at the top level there are .claude/, .agents/, AGENTS.md and CLAUDE.md, which is a stronger statement about how this project expects to be worked on than any line of documentation would be: instructions for agents are versioned next to the code.

## One feature written by hand and 26,256 lines of generated code

The project describes itself as a vibe coding project and says so in a section of its own. The claim is that the author implemented one core feature and the rest was built by Claude Code, with 26,256 lines of pure code counted in docs/codeinsight.md, and the acknowledgements thank Claude Code for the contribution.

Two companion documents sit next to that line count: docs/experience.md for the vibe coding experience and docs/vibe-coding.md, the Chinese write-up of the same. Pull requests are explicitly welcomed in that section, including pull requests carrying vibe coding experiences rather than code.

For a reader, this is the most useful paragraph in the repository and also the least verifiable from outside. A line count and a generation log are self reported, so treat them as a description of how the code arrived rather than as a measure of its quality. What you can check yourself is smaller: the platform list claims a web app, an iOS and Android app, and a browser extension for Chrome, Firefox and Edge, and the feature list names one external integration target, external agents like OpenClaw, which is what the CLI and the skill are there to serve. The docs directory holds the promised detail in five files, codeinsight.md, experience.md, vibe-coding.md, CLOUDFLARE.md and todo.md.

## package.json and the README command list have drifted

The root package.json names itself mindpocket-monorepo, is marked private, pins packageManager to pnpm@10.9.0 and requires node >=18. Its scripts are the authority on what the repo can do, and the README's Commands block is a subset of them.

The block in the README covers root dev, build, deploy:cf, cli:build, cli:pack, format and check, then the API scripts dev, db:generate, db:migrate:local, db:migrate:remote and deploy, and it ends on a bare # with nothing after it. Missing from that list but present in package.json are the test scripts, test:watch, test:coverage, test:e2e, test:web and test:web:e2e, plus clean, lint, fix, lint-staged, and cli:publish:dry-run, which runs npm publish --dry-run against apps/cli.

That last group is the informative one. Every test script filters to web, so the web app is where tests are wired up and the API has no test script at all. Quality tooling is Biome plus Ultracite, with lint-staged running biome check --write on ts, tsx, js, jsx, json and css files, husky wired in through prepare, and pnpm overrides holding react and react-dom at 19.1.0 with the matching type packages and lightningcss pinned to 1.30.1. Turborepo fans dev, build and clean out across the workspace.

## The README links a LICENSE file the top level does not contain

The License section says MIT License and points at ./LICENSE, and the top level of the repository lists .agents/, .claude/, .github/, .husky/, .vscode/, AGENTS.md, CLAUDE.md, README.md, README_CN.md, apps/, docs/, packages/, skills/, biome.json, package.json, pnpm-lock.yaml, pnpm-workspace.yaml, skills-lock.json and turbo.json. No LICENSE file appears in that list.

That is a one-line fix in a fork, but it matters if you were planning to redistribute or vendored part of this. A licence that only exists as a link is not a grant until the target exists.

The roadmap tells you what is not built yet, and the boxes are all unchecked: more UI settings options, support for more bookmark platforms, improving the AI agent experience, and optimising RAG, with detail in docs/todo.md. There are no GitHub releases, so there is no version to pin, and the last push is dated 28 July 2026 on main. Contribution runs through issues and pull requests, plus a QQ group numbered 682827415, and the Chinese README_CN.md sits alongside the English one and is linked from the top of the page as the 中文文档.

None of the roadmap items is about the storage layer, which is where the constraints bite. If your list is heading past the 5 GB of D1 or the 10 GB of R2, or past 100k requests a day once the mobile app and extension are also polling, nothing in the current design absorbs that, and no item on the list proposes to.

## Conclusion

MindPocket is a reasonable choice if your bookmark list fits inside a Cloudflare free tier and you want AI summarisation and tagging without paying for a database, and the four resource ceilings are stated plainly enough to check before you commit. It is a poor choice if you need your own server, a Postgres instance or an object store you control, since each of those has been swapped for a Cloudflare equivalent. Before deploying, fix the clone URL in the local setup block, check that the LICENSE file the README links to actually exists in your fork, and read the roadmap, because support for bookmark platforms beyond your current one is listed as unchecked.

## FAQ

### What does MindPocket need to deploy?

Four Cloudflare resources: Workers plus Static Assets for the Hono API and Next.js static export, D1 for relational data, Vectorize for vector search, and R2 for file storage. Quick start creates them with wrangler, sets BETTER_AUTH_SECRET, fills apps/api/wrangler.jsonc and runs migrations.

### How do I run MindPocket locally?

You need Node.js 18 or newer and pnpm 10.9.0. Run pnpm install, put BETTER_AUTH_SECRET in apps/api/.dev.vars, apply migrations with pnpm --filter api db:migrate:local, then start the worker with pnpm --filter api dev on port 8787. The web hot reload runs separately on port 3000.

### What is the MindPocket agent skill and does it replace the CLI?

It is a repository-scoped skill named mindpocket, installed with npx skills add, that teaches agents to use schema, doctor, the server config and the bookmark workflows. It is guidance layered on the npm CLI, so the mindpocket command still has to be installed locally.

### Does MindPocket need a database or object store I pay for?

No. The design swaps in Cloudflare equivalents: D1 replaces a relational database, R2 replaces MinIO and Vectorize replaces pgvector. Everything runs on the free tier, with ceilings of 100k requests a day, 5 GB of D1, 30M queried dimensions a month and 10 GB of R2.

## Sources

- [Issues](https://github.com/jihe520/mindpocket/issues)
- [jihe520/mindpocket on GitHub](https://github.com/jihe520/mindpocket)
- [Project website](https://mindpocket.top)
- [README](https://github.com/jihe520/mindpocket/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jihe520-mindpocket
