A new open-source project on GitHub lets developers run a full personal AI agent on Cloudflare's free tier, with no paid infrastructure required. The agent handles chat, long-term memory, deep research, and scheduled tasks, all while measuring every platform limit it hits and writing those numbers down.
The project, called workers-personal-agent, comes from developer Dom Wane. It ships a one-click deploy button and a complete CLI setup path. Cloudflare clones the repo, creates the R2 bucket and Durable Objects, wires up Workers AI, and redeploys on every push. The committed configuration needs nothing beyond a Cloudflare account and two secrets.
One Durable Object per conversation
Each thread runs in its own Durable Object, which owns the tool loop, the message history, and the connection to the model. The browser client connects over a WebSocket and holds no state of its own. When the Durable Object calls setState, the change persists and broadcasts automatically, so the thread, research cards, and finished reports all arrive without any delivery code on the client side.
This architecture means conversations survive browser clears and can be listed in a sidebar from the vault. A route that answers with HTML instead of JSON usually means the path is missing from run_worker_first in wrangler.jsonc, a common tripping point the project documents.
Memory as markdown in R2, recall over embeddings
Long-term memory lives as markdown files in an R2 bucket. The agent records which conversation turn each memory came from, and any write that deletes something must cite the user turn that triggered it. Semantic recall runs over an embedding index stored in Durable Object SQLite, with a keyword fallback when embeddings miss.
A nightly reflection pass runs as a Durable Object alarm, reconciling the memory index and reading an append-only archive. The project measured dense retrieval (bge-m3) against BM25 on 673 real exchanges with graded relevance, finding dense retrieval ahead by +0.200 nDCG@10 with a confidence interval of 0.070 to 0.326. Hybrid fusion, a reranker, a larger ingest window, and averaged word vectors were all tested and rejected, with the rejection decisions documented before the results came in.
Deep research that fans out across child Durable Objects
Deep research mode lets the user toggle a research flag in the composer and type a topic. The agent proposes a plan with Start, Revise, and Drop buttons. On start, it fans out one child Durable Object per angle, each with its own budget of fifty subrequests. A wall clock bounds the entire run, and the finished report counts the pages it could not open.
During a walkthrough test, the agent lost 14 of 30 page reads to the Browser Rendering rate limit (one request every ten seconds on the free plan) and completed anyway, noting the loss in the report. The deep-research wave draws from the Static-DRA paper's approach to narrowing a research wave, adapted without copying code.
History compacts instead of truncating
When conversation history hits 80% of the selected model's context window, the oldest turns fold into a rolling summary. The original turns go to an append-only archive first, so nothing is lost. This compaction threshold and the archive-before-trim pattern were taken from deepseek-harness. Tool results also outlive their round: a fetched page stays whole in the thread's SQLite, and only the copy inside the current request is trimmed, so a later turn can read the rest.
Skills the agent writes for itself
When a workflow takes several tool calls, the agent offers to save it as a skill. Skills are stored as markdown in the vault and listed in every system prompt. The model reads the procedure when a request matches, and a /slug command invokes one by hand. Unused skills archive after 90 days. A reminder like "Remind me at nine tomorrow to send the invoice" uses a Durable Object alarm, keeping scheduled work outside the chat turn.
MCP servers and boundary guards
The settings dialog lets users add MCP servers with OAuth or a bearer token. Their tools appear in every chat from the next message on. The project added support for Cloudflare's own MCP endpoint, turning Workers API tools into callable functions inside the agent.
Every outbound call goes through a subrequest counter with a reserve, and each tool's zod schema serves as both the JSON Schema the model sees and the parser its reply passes through. On the free plan, the agent counts every subrequest and stops before hitting the 51-call limit, reporting the stop to the user.
Stack and configuration
The stack is Cloudflare Workers, the Agents SDK, Durable Objects, R2, Workers AI or any OpenAI-compatible API, zod, Vue 3, Vite, Tailwind, shadcn-vue, and vitest. The UI model picker reads the provider's catalogue and shows price, context window, and tool support per model. Tool calling is required: the agent is a tool loop. Verified free-plan models include glm-4.7-flash, gpt-oss-120b, qwen3-30b-a3b-fp8, and llama-3.3-70b-instruct-fp8-fast.
Setting LLM_BASE_URL points the agent at any OpenAI-compatible endpoint (OpenRouter, OpenAI, Groq, local Ollama) with an LLM_API_KEY secret. The project also supports Tavily and Firecrawl as search vendors, both usable without keys at reduced rate limits.
Free plan limits, measured and documented
The project documents four key free-plan limits. External subrequests cap at 50 per invocation. Browser Rendering allows one request every ten seconds and ten minutes per day. Workers AI gives 10,000 neurons daily. Search without a key hits Tavily's unpublished limit or Firecrawl's 1,000 credits per month. A normal chat turn never touches any of these. Deep research meets the first three on every run and is built to finish anyway.
The project includes a CI workflow, retrieval and prompt evals in its own vitest pool, and a manual end-to-end walkthrough for the seams no test suite covers. That walkthrough opens with three bugs found by hand that no unit test could have caught. The full repo is MIT licensed, with attribution for borrowed component source from shadcn-vue and ai-elements-vue.