← Work

active · 2026

bobby.menu

A personal restaurant notebook turned into a public map, a set of shareable menus, and an interface an AI assistant can query.

My role: Creator, curator, and developer

Why it exists

Restaurant recommendations are easy to collect and surprisingly hard to retrieve at the moment they matter. Notes become stale. Group chats disappear. A saved map can tell me what is nearby, but not whether I loved a place, would recommend it with a caveat, or simply want to remember it for later.

I built bobby.menu as the version of a restaurant list I wanted to keep: personal enough to be opinionated, structured enough to search, and public enough to send to a friend without an explanation.

The site deliberately avoids pretending to be a universal ranking. One curator maintains the list. Every restaurant sits in one of three plainly defined tiers: Loved, Recommended, or On My Radar. The first two reflect a visit; the last is a pre-vetted possibility. That distinction matters because “I have been there” and “someone trustworthy mentioned it” are not the same claim.

What I built

The public experience is a responsive React and TypeScript application centered on a Google Map. Visitors can move between map and list views, search by restaurant name, filter by cuisine, tier, distance, tags, city, or whether a place is open, and share a link to an individual restaurant.

The list is stored in Supabase. Row-level security and Google OAuth separate public reading from curator actions. The private curation tools support adding and editing restaurants, enriching records with Google Places details, reviewing visitor suggestions, recording visits, and arranging named collections. Those collections become public, ordered menus with stable links—useful for something like “Visiting Phoenix? Start here” without creating a second copy of the underlying restaurant data.

There is also an MCP server at bobby.menu/mcp. It exposes the same curated data to compatible AI clients, including tools for searching, finding a random option from a filtered pool, and reading named collections. Administrative tools are authenticated; public discovery stays read-only.

Decisions that shaped it

The map is the hero, but not the only interface. A map is excellent for answering “what is near me?” and poor at scanning names or comparing a short list. Keeping map and list views connected lets each do the job it is good at.

Curation is data, not decoration. Tiers, notes, tags, and collection order live in the data model. They can be filtered, shared, tested, and reused by the MCP server instead of being trapped in prose on a card.

Public suggestions do not become public facts automatically. A visitor can submit a place, but approval creates a separate curator-owned restaurant record. The suggestion is a nudge, not a draft review.

Third-party enrichment is helpful but not authoritative. Ratings, hours, prices, and photos can make a card more useful. Curator-supplied names, notes, and classifications take precedence when an external provider disagrees or matches the wrong branch.

The privacy posture should match the scale of the product. The site uses a self-hosted, cookieless Umami instance with manual pageviews that omit query strings. There is no advertising profile hiding behind a restaurant recommendation.

What changed along the way

The first version was a static data file and a map. It grew only when a real use case created pressure: Supabase became the live store; OAuth protected curation; filters became faceted and responsive; list view gained a split layout on wide screens; collections turned recurring recommendations into durable URLs; the MCP endpoint made the same list useful from a conversation.

The visual system evolved too. The current “Wine & Paper” palette gives the product a quiet food-editorial character while reserving distinct colors for the three tier meanings. This was not cosmetic polish added at the end. It clarified which colors communicate product state and which carry brand personality.

What I learned

A personal tool becomes more useful when its opinionated parts are explicit. “Loved” has a definition. “On My Radar” does not masquerade as a review. A collection has an intentional order. An external rating is context, not the verdict.

I also learned that an AI interface is much better when it shares a model with the human interface. The MCP server did not need a parallel restaurant universe. It needed careful, permission-aware access to the same one.

The project is still active because the list is alive. Restaurants change, my experience changes, and the best interface is the one that keeps making those edits easier without diluting what the list means.

Start a conversation

Have a question, idea, or useful tangent?

I read every message. Even the delightfully specific ones.