Personal Agent Template: A Vercel Labs Skeleton for One User, Many Surfaces
Open-source template for a durable personal AI agent — web chat, Slack, Linear, and long-term memory with user-approved saves. Eve, Nuxt, Better Auth, Vercel Connect.
At a glance
- What is it?
- Vercel Labs ships an MIT-licensed Nuxt plus Eve template for a single-user agent with Slack, GitHub, Linear and a model-maintained memory file. The interesting part is what it refuses to store.
- Who is it for?
- Fork this if you are one person who wants a personal agent on Slack and the web and you accept Vercel as the runtime, because the memory slot binds to Vercel Blob and the deployment splits into a web service plus an eve service that the eve/nuxt module generates at build time. Do not fork it if you need multi-tenant isolation, a non-Nuxt frontend, or a memory store you control.
- 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 13 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 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem is storage discipline, not chat UI
Most personal agent projects spend their effort on the chat surface and then improvise persistence. This template inverts that. The README states that Eve holds the transcript, so the app stores a session id and nothing else. That one sentence drives the whole repository layout: Nuxt owns identity, database rows and integrations, while the conversation state lives in the agent runtime. The audience is narrow and clearly stated. It is a template for one person. You fork it, rename the example persona (the README calls it V), and deploy your own instance. There is no organization model, no workspace switcher, no admin console in the description. If you are evaluating this for a team product, you are reading the wrong repository.
Two services, one Bearer token, and a build-time split
The architecture diagram in the README shows the flow plainly. Web chat and Slack DMs or mentions enter at the top. Below that sits the Eve agent, which owns channels, tools and skills. Eve then calls into Nuxt over /api/internal/* routes using Bearer authentication. Nuxt is the layer holding the UI, the Nitro API, Better Auth and PostgreSQL. Vercel Connect sits underneath for Linear and Slack. On Vercel the deployment becomes two services, web and eve, and the README says the eve/nuxt module generates the eve service and its /eve/v1/* route during the build, so nothing needs declaring in vercel.json. That is a real constraint disguised as convenience. Your build step is now part of your deployment topology, and the /eve/v1/* path is generated rather than written by you. When the split misbehaves, you are debugging a module's output, not a file you can read in the repository. The Bearer token tying the two halves together is INTERNAL_API_SECRET, and the README is explicit that it must be the same value on web and eve.
Memory is a bounded file the model edits, not a vector store
The memory design is the part worth studying. The README describes a bounded, model-maintained list of durable facts, scoped per user by Eve's fileMemory() provider. The profile slot in agent/memory/profile.ts binds that provider to one document per authenticated principal. Eve recalls the document before every turn and again after compaction, and exposes profile__save_memory and profile__remove_memory so the agent can maintain the list itself. Documents live in private Vercel Blob storage, and the README says to attach a Blob store before deploying. Two consequences follow. First, there is no embedding pipeline and no retrieval scoring to tune, which removes a class of failure but also removes fuzzy recall: the whole document is in context, so its size is a budget you manage by asking the agent to prune. Second, the memory is tethered to Vercel Blob. Self-hosting instructions exist, but the memory provider does not appear to have a documented local-disk equivalent in the material provided. Treat the Blob dependency as part of the product, not an implementation detail.
Getting it running locally takes four commands and three secrets
The self-hosting path requires Node.js 24 or later and pnpm. The README gives the sequence: clone the repository, cd into it, run pnpm install, copy .env.example to .env, run pnpm db:migrate, then pnpm dev, and open http://localhost:3000 to create an account. Three variables are required. BETTER_AUTH_SECRET, generated with openssl rand -base64 32. BETTER_AUTH_URL, which is http://localhost:3000 locally. INTERNAL_API_SECRET, also from openssl rand -base64 32, and the README notes it must be identical across web and eve. The full reference is in docs/ENVIRONMENT.md. If the local database gets into a bad state, the README offers rm -rf .data/db followed by pnpm db:migrate. Other scripts are pnpm typecheck, pnpm build, and pnpm db:generate, which the README says regenerates the auth schema and then the migration. The Deploy with Vercel button pre-fills the same three variables and attaches a Neon database store.
The integrations do not share a trust model
Slack, GitHub and Linear are described at different levels of detail, and the difference matters. For Slack, the README says DMs and @mentions arrive on the slack channel, and that linking your Slack account to your web profile lets memory and context follow you across channels. For GitHub, connection goes through Vercel Connect, and the agent mounts @github-tools/eve-extension with what the README calls durable approval on writes. For Linear, connection goes through Vercel Connect MCP, and the README claims the agent queries Linear tools and never guesses from memory. So writes are gated on the GitHub path, and the Linear path is framed as read-oriented, but the material does not describe an equivalent approval gate for Slack messages or for Linear mutations. If you need a uniform write-approval story across all three surfaces, you will be building it yourself. The README also mentions a daily summary skill that composes active focus from recalled memory, assigned Linear issues and a suggested next action, triggered from a home quick action or from chat.
Where this template is the wrong starting point
The single-principal assumption is the hard boundary. Memory is scoped per authenticated principal through Better Auth email and password sign-in, and the README describes no organization, role or invitation model. A multi-user product built on this fork would need its own tenancy layer above the auth schema, and the memory slot would need a scoping rule the template does not supply. The second limitation is runtime gravity. The deployment story is a Vercel split into web and eve, memory documents sit in Vercel Blob, and Linear and Slack connect through Vercel Connect. The self-hosting commands exist, but the described integration layer is Vercel-shaped, so a fork targeting another platform is replacing more than a hostname. Third, the template ships no releases according to the retrieved metadata, so there is no versioned upgrade path to follow. You track main, and you own every merge. That last point is not a criticism of the code. It is a statement about what forking costs.
What you would otherwise assemble yourself
The obvious alternative is a general agent framework such as LangGraph or the OpenAI Agents SDK, where you bring your own frontend, your own auth and your own persistence. The difference is not capability, it is the amount of plumbing you write before the first useful turn. Those frameworks give you an orchestration loop and leave session storage, identity, channel adapters and a memory store to you. This template gives you the plumbing and a fixed opinion about each piece: Better Auth for identity, PostgreSQL for rows, Eve for the transcript, a file memory provider for facts, and Vercel Connect for Linear and Slack. You can swap any of them, but each swap costs more than it would in a framework that never picked. The honest comparison is that a framework optimizes for reaching any architecture, and this template optimizes for reaching one specific architecture quickly. If that architecture matches your target, the template wins on time. If it does not, you are fighting the defaults.
Licence, maintenance and what to verify before you fork
The repository is MIT licensed, which permits commercial forks and modification, though the material here is not legal advice and you should read the LICENSE file and your own obligations. Maintenance cost is the more practical question. With no retrieved releases, upgrades mean diffing main, and the surface most likely to move is the eve/nuxt module that generates the eve service and the /eve/v1/* route, because that sits between your build and your deployment. The second volatile surface is docs/ARCHITECTURE.md, which the README treats as the authoritative description of the two-service split. Before you invest in customization, verify three things against the code you actually cloned: that the profile slot in agent/memory/profile.ts still binds fileMemory() the way the README describes, that INTERNAL_API_SECRET is the only shared secret between web and eve, and that the customization guide's list of touch points (agent name, slug, persona, model, tools, skills, Slack and Linear configuration, UI theme) covers everything you intend to change. A template is a claim about which decisions are already made. Read the code to confirm the claim still holds.
Editorial conclusion
Fork this if you are one person who wants a personal agent on Slack and the web and you accept Vercel as the runtime, because the memory slot binds to Vercel Blob and the deployment splits into a web service plus an eve service that the eve/nuxt module generates at build time. Do not fork it if you need multi-tenant isolation, a non-Nuxt frontend, or a memory store you control. Before committing, create the three secrets, attach a private Blob store, and read docs/ENVIRONMENT.md and docs/ARCHITECTURE.md to confirm the split still matches the code you cloned.
Community notes