The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Mahonia listing page.
A gear-list and pack-weight tracker for hikers. Make a packing list, see what it weighs, share it.
Lists need no sign-up: one is yours the moment you start typing, held by a private unguessable link. The gear vault is the one part that asks for an account, because "the gear I own" has to follow you across devices rather than living in one browser.
32.5 oz on a gram list and that row keeps ounces while the
total stays in grams.Requires Node 24 (the pinned version — see .nvmrc).
With no environment variables set, the app runs fully on your machine against a local
PGlite database. Copy .env.example to .env to
point at a real Postgres (Neon) and Redis (Upstash)
for a production deploy.
Anything that would leave the machine degrades to the console instead of being skipped, so a fresh checkout is a working app rather than a broken one:
| Unset variable | What happens locally |
|---|---|
RESEND_API_KEY | Sign-in links print to the server console instead of being emailed. |
GITHUB_FEEDBACK_TOKEN / _REPO | "Send feedback" (in the editor's actions menu) prints to the console and reports back that it wasn't filed. |
Both fail loudly in production rather than quietly accepting input that goes nowhere.
Nuxt 4 · Vue 3 · TypeScript · Drizzle ORM · deployed on Vercel.
The app serves a remote MCP server at /mcp, so an AI assistant can be handed
https://mahonia.app/mcp as a connector with nothing to install and no sign-in. Seven
tools: read a shared list as data or Markdown, search the catalog, fetch one product's
variants, and, holding an edit link, make a list, add rows and set the trip's dates and
trail. A share code is the read capability and the edit link's fragment token the write
one, hashed on arrival and passed only as a tool argument, so nothing new is trusted. The
transport is stateless JSON-RPC over POST (MCP revisions 2025-06-18 and 2025-11-25, no
sessions, no event stream, GET answers 405), hand-rolled in server/routes/mcp.post.ts
with the tools in server/utils/mcp.ts; both files carry the reasoning. My Gear is
deliberately out of reach: it would need an account token, which is a separate decision.
Add it to a client:
claude mcp add --transport http --scope user mahonia https://mahonia.app/mcpgemini mcp add --transport http mahonia https://mahonia.app/mcphttps://mahonia.app/mcp with "No Authentication".mcp.json: {"mcpServers":{"mahonia":{"url":"https://mahonia.app/mcp"}}}npx mcp-remote https://mahonia.app/mcp.The server is listed in the official MCP registry
as app.mahonia/mahonia; server.json is the listing, published with
mcp-publisher under the domain's DNS proof.
The changelog is GitHub Releases: one release
per day that ships something, tagged by date (v2026.09.12), cut by a workflow from the entries
below. When a change is user-facing, add a plain one-sentence entry as part of the same PR:
Entries are grouped Added / Changed / Fixed and describe the observable change, not the implementation.
Each run writes its own file under content/changelog.d/, so entries from PRs open at the
same time never collide — content/changelog.json is the settled
archive, and npm run changelog:compact folds fragments into it now and then. Once a day is
over (Pacific), .github/workflows/releases.yml turns it into a release; a late entry updates
its day's notes.
A PR comment reminds any user-facing PR that's missing an entry — but nothing auto-fills it,
so the entry is always hand-written (plain, curated prose). If a PR merges
without one, that day's release just omits the change until it's backfilled. For non-user-facing work,
prefix the PR title (refactor:, chore:, ci:, test:, docs:, build:) or label it
skip-changelog — perf: and style: don't count, since both are things a visitor notices.
Code is MIT. The gear catalog data under seed/ is licensed separately — see
seed/LICENSE.md.
Third-party notices for the libraries bundled into the client are in
public/licenses.txt, served at /licenses.txt. The file exists
because Mahonia bundles its dependencies instead of loading them from a CDN (a CDN
<script> could read a list's edit token out of location.hash), which makes serving the
site a redistribution of that code — and the minifier strips the banner comments those
libraries ship their copyright in. Add an entry when a dependency's code starts reaching
the browser; server-only packages aren't redistributed and aren't listed.