@craveup/mcp
v0.6.0
Published
MCP server that lets AI agents create and manage Crave menus and implement Crave storefronts
Readme
Crave Up MCP Server
A Model Context Protocol (MCP) server that lets AI agents onboard restaurant brands and manage Crave menus, storefronts, and mobile releases — entirely from natural language in chat
Quick Start | Available Tools | Authentication | Documentation
Overview
This MCP server provides Crave platform integration for Claude Code, Cursor, and other MCP-compatible clients. It covers the full merchant lifecycle: creating an organization, wiring a repo, importing menus, configuring locations, going live with subscriptions and payments, managing discounts, and dispatching guarded Expo/EAS mobile releases.
Key Features
- 37 Tools in 9 Categories — browser auth, onboarding, go-live, location settings, menus, discounts, readiness checks, mobile releases, sandbox data
- Natural-Language Onboarding — "hook up this repo for Demo Bistro" → login → create org → wire
.env→ import menu → run iOS - Idempotent Writes — menu imports, discount creation, and sandbox seeding are safe to re-run
- Guarded Mobile Releases — internal TestFlight only; paid EAS work requires a scoped Expo token plus explicit confirmation, and public App Store release remains human-controlled
- TypeScript — full type safety with Zod validation
- Tested — Vitest suite (63 tests) covering tools, clients, config, auth, and readiness logic
Note: this is a local MCP server. It runs as a stdio subprocess on the developer's machine. An agent can start secure Crave Up browser sign-in/sign-up through
start_crave_auth; the resulting session is shared with the CLI.
After rebuilding
packages/mcp/dist, restart the MCP server in your client (or reload the window) so new tools appear.
Quick Start
Installation
# From npm (published package)
npx -y @craveup/mcp
# Or from the monorepo
pnpm --filter @craveup/mcp build # compiles to dist/Configuration
Claude Code. Register separate sandbox and production processes at user scope so the environment boundary remains visible in every tool call. This is a local stdio server, so there is no hosted MCP URL:
claude mcp add -s user craveup-sandbox \
-e CRAVEUP_ENVIRONMENT=sandbox \
-- npx -y @craveup/mcp
claude mcp add -s user craveup-production \
-e CRAVEUP_ENVIRONMENT=production \
-- npx -y @craveup/mcpRun /mcp in Claude Code to inspect the registration. Start a new Claude Code
session if the current session does not refresh its tool inventory.
Do not switch an already-running server between environments. Use the
craveup-sandbox tools while building and testing, then explicitly select the
craveup-production tools when preparing to launch. Each process has its own
dashboard host, API-key prefix, Clerk configuration, and stored browser session.
Option A — Full NL development bootstrap (recommended for new brands). Register the MCP server without an API key. No repo checkout is needed:
{
"mcpServers": {
"craveup": {
"command": "npx",
"args": ["-y", "@craveup/mcp"],
"env": {
"CRAVEUP_ENVIRONMENT": "sandbox"
}
}
}
}The agent calls start_crave_auth, opens the returned Crave Up URL, and then calls
complete_crave_auth. The user can sign in or create a free account in that browser flow. The
server stores the resulting shared CLI/MCP session in the macOS keychain (or
~/.config/craveup/credentials.json). Alternatively set CRAVEUP_ACCESS_TOKEN in the MCP env.
To exercise tools that are on main but not yet published, swap the command for the local build:
"command": "node", "args": ["/path/to/craveup-turborepo/packages/mcp/dist/cli.js"].
Option B — Menu-only (existing location + API key). Create a merchant API key in Crave Business Manager → Settings → Developer → API Keys:
{
"mcpServers": {
"craveup": {
"command": "npx",
"args": ["-y", "@craveup/mcp"],
"env": {
"CRAVEUP_ENVIRONMENT": "sandbox",
"CRAVEUP_API_KEY": "crv_test_…",
"CRAVEUP_LOCATION_ID": "<default location id>"
}
}
}
}CRAVEUP_ENVIRONMENT is required. The environment selects all dashboard, API, and Clerk hosts
together. CRAVEUP_LOCATION_ID is optional; every menu tool also accepts an explicit locationId.
Mobile releases. To dispatch mobile release workflows, also set a scoped Expo robot-user token in the MCP env:
{
"env": {
"EXPO_TOKEN": "<scoped Expo robot-user token>"
}
}Example chat flow
"This demo-bistro repo — hook it up to Crave for Demo Bistro. Login if you need to, create the org, import the menu, and run it on the iOS simulator."
Agent sequence:
whoami— confirm the shared session- If needed:
start_crave_auth→ open its URL →complete_crave_auth create_organization({ name: "Demo Bistro", mintApiKey: true })connect_project({ projectPath: "…/demo-bistro", apiKey, locationId })import_menu(…)from the restaurant source- Run the storefront or iOS app locally
- Place sandbox test orders immediately; no merchant Stripe Connect account or subscription is required
- Only when the merchant chooses to launch: switch to production and complete subscription and payment onboarding
Available Tools
Entities
CRUD-style operations are available for the following entity types:
| Entity | Create | Get | Update | Delete | List | |--------|:------:|:---:|:------:|:------:|:----:| | Organization | ✅ | - | - | - | - | | Location | ✅ | - | ✅ | ✅ | ✅ | | Store Settings | - | ✅ | ✅ | - | - | | Menu | ✅ | - | ✅ | - | ✅ | | Product | ✅¹ | ✅ | ✅ | ✅ | - | | Discount | ✅ | - | - | - | ✅ | | Order | - | - | - | - | ✅ | | Customer | - | - | - | - | ✅ | | Subscription | ✅² | - | - | - | ✅ | | Mobile Release | ✅³ | ✅ | - | - | - |
¹ Products are created in bulk via import_menu. ² start_subscription_checkout opens a Stripe Checkout session; plans themselves are read-only. ³ start_mobile_release dispatches an EAS workflow run; deletion/cancellation stays in EAS.
Checks & Guides
| Check | Tool Name | Description |
|-------|-----------|-------------|
| Go-live Status | get_onboarding_status | The dashboard's 6 go-live steps with completion state + next actions |
| Storefront Readiness | check_storefront_readiness | Sandbox: menu, ordering, and platform test checkout. Production: menu, ordering, and merchant Stripe chargesEnabled |
| Mobile Release Readiness | check_mobile_release_readiness | Read-only Expo/EAS preflight for internal releases |
| Onboarding Flow | get_onboarding_flow | NL checklist: login → create org → connect repo → import menu → run |
| Session | whoami | Verify the craveup login session is readable |
| Integration Guide | get_integration_guide | Crave.js implementation guidance: storefront, menu display, checkout |
Tool Reference
| Tool | Description |
|------|-------------|
| start_crave_auth | Return a hosted Crave Up sign-in/sign-up URL for the agent to open |
| complete_crave_auth | Finish the loopback callback and persist the shared CLI/MCP session |
| cancel_crave_auth | Abandon a pending sign-in and release its loopback listener |
| Tool | Description |
|------|-------------|
| get_onboarding_flow | NL checklist: login → create org → connect repo → import menu → run |
| whoami | Verify the craveup login session is readable |
| create_organization | Create merchant + location; mintApiKey: true returns a storefront key |
| connect_project | Write EXPO_PUBLIC_CRAVEUP_* into an Expo app's .env (validates the project path is a real directory) |
| Tool | Description |
|------|-------------|
| get_onboarding_status | The dashboard's 6 go-live steps with completion state + next actions |
| create_location | Create a location (restaurantDisplayName + optional address PATCH) |
| delete_location | Soft-archive a location (frees slug; hides from dashboard) |
| list_locations | Dashboard locations-stats for the merchant |
| get_location_orders | Active orders for a location |
| list_customers | Customers page for a location |
| set_location_address | Set the street address; the server geocodes (no lat/lng needed) |
| set_fulfillment_methods | Enable pickup / table service / delivery / room service |
| list_subscription_plans | Production-only plans with price, interval, and trial info |
| start_subscription_checkout | Production-only Stripe Checkout URL for the user to pay in the browser |
| Tool | Description |
|------|-------------|
| get_location_settings | Read store hours, scheduled-order flag, tax, takeout |
| update_store_hours | Set hours (always_open, business_9am_10pm, or custom 7-day schedule) |
| set_scheduled_orders_enabled | Toggle order-ahead when closed |
| set_takeout_enabled | Enable/disable takeout pickup |
| open_location_for_orders | One-shot fix for "Restaurant is closed. Scheduled orders are not allowed." |
| Tool | Description |
|------|-------------|
| import_menu | Idempotent full menu import; forces menu.isActive=true by default |
| set_menu_active | Explicitly activate/deactivate a menu (use when list_menus shows inactive) |
| list_menus | Read back menus exactly as the storefront API serves them |
| get_product | Fetch one product with its modifier group ids |
| update_product | Partial edits: name, description, price, availability |
| set_product_availability | Sold-out toggles |
| delete_product | Remove a product (category references cleaned up) |
| get_integration_guide | Implementation guidance: storefront setup, menu display, checkout, import format |
| Tool | Description |
|------|-------------|
| list_discounts | List location promo codes and their current configuration |
| create_order_discount | Idempotently create an order-level fixed or percentage promo code (percentage capped at 100) |
| Tool | Description |
|------|-------------|
| check_storefront_readiness | Environment-aware gate: platform test checkout in sandbox; merchant Stripe chargesEnabled in production |
Run craveup apps configure in the Expo/React Native project and commit the generated workflows before using these tools. EAS builds consume plan minutes.
| Tool | Description |
|------|-------------|
| check_mobile_release_readiness | Read-only local preflight for EAS project identity, workflow, credentials, and internal target |
| start_mobile_release | Dispatch the fixed internal TestFlight workflow after exact confirmation |
| get_mobile_release_status | Read the EAS workflow run, build jobs, and submission jobs |
start_mobile_release cannot publish publicly. iOS always goes to internal TestFlight first; public App Store review remains an explicit App Store Connect action. Use craveup apps publish play-internal for Android; the CLI blocks submission unless the local EAS submit profile targets Google Play's internal track.
| Tool | Description |
|------|-------------|
| seed_sandbox_analytics | Idempotently create customers, orders, ratings, and funnel events for the dev test organization. Requires CRAVEUP_ENVIRONMENT=sandbox and a sandbox Clerk session. |
Authentication
This server authenticates to Crave with a merchant API key (menu, discount, and readiness tools), a shared CLI/MCP browser session (organization, onboarding, go-live, and location-settings tools), and optionally an Expo token (mobile release tools). The agent starts browser authentication with start_crave_auth; the user can sign in or create an account on the Crave Up-hosted page.
Important: Sandbox vs production
| Environment | Dashboard | API | Clerk issuer | API key |
|---|---|---|---|:---:|
| sandbox | sandbox.dashboard.craveup.com | dev-api-43233223.craveup.com | refined-mosquito-31.clerk.accounts.dev | crv_test_… |
| production | dashboard.craveup.com | api.craveup.com | clerk.craveup.com | crv_live_… |
Set CRAVEUP_ENVIRONMENT explicitly in the MCP server configuration. The server derives the whole
profile from that value and rejects a test/live key or endpoint mismatch before sending a request.
Sandbox and production sessions are stored separately.
For daily development, register two named MCP servers instead of mutating one server's environment in-process:
craveup-sandbox: build the storefront, configure menus and locations, and place test orders through Crave's platform Stripe test account without merchant Connect onboarding or a subscription.craveup-production: use the live dashboard and live API-key namespace. Dashboard and setup tools remain usable before onboarding is complete, but accepting real payments still requires the subscription, Stripe Connect KYC, and banking steps shown byget_onboarding_status.
Browser authentication is explicit: call start_crave_auth, open the returned Clerk authorization
URL, then call complete_crave_auth. Normal MCP calls reuse that persisted session and do not open a
browser again.
Test Setup (recommended for first run)
- Sign in to Crave Business Manager → Settings → Developer → API Keys
- Create a key for the location you want to work with — copy the
crv_test_…value - Set
CRAVEUP_ENVIRONMENT=sandbox,CRAVEUP_API_KEY, and optionallyCRAVEUP_LOCATION_IDin the MCP server env - For session-authenticated tools, use
start_crave_authandcomplete_crave_auth, or runcraveup login; both paths use the same secure local session
Live Setup
- Start a separate MCP process with
CRAVEUP_ENVIRONMENT=production; do not reuse sandbox credentials - Open the production dashboard and continue configuring the organization even if the commercial checklist is incomplete
- When the business is ready to accept real payments, complete the go-live checklist —
get_onboarding_statusshows the six steps and what's missing - Verify payments with
check_storefront_readiness— production requires merchant StripechargesEnabled - Mint a
crv_live_…key in Business Manager
Once you have credentials
CRAVEUP_ENVIRONMENT=sandbox # required: sandbox or production
CRAVEUP_API_KEY=crv_test_… # prefix must match the environment
CRAVEUP_LOCATION_ID=<location id> # optional default; every tool also accepts locationId
CRAVEUP_ACCESS_TOKEN=<session token> # optional alternative to the keychain session
EXPO_TOKEN=<scoped robot-user token> # only for mobile release toolsEndpoint overrides are normally unnecessary. Sandbox loopback URLs are allowed for local
development. Other custom deployments require CRAVEUP_ALLOW_CUSTOM_ENDPOINTS=true, and the
environment remains visible in whoami and mutating responses.
Credential safety
Do not paste Apple passwords, 2FA codes, App Store Connect keys, or Google service-account JSON into chat. Bootstrap interactive credentials in a visible terminal; EAS stores the reusable submission credentials. EXPO_TOKEN must be a scoped Expo robot-user token, never a personal account token.
Common pitfalls
- New tools not appearing. After rebuilding
packages/mcp/dist, restart the MCP server in your client (or reload the window) — clients cache the tool list per process. - Keys are location-scoped. The API rejects requests for locations the key cannot access; use the key minted for the location you're targeting, or pass an explicit
locationId. - Session tools failing while key tools work. The two auth modes are independent — a valid
CRAVEUP_API_KEYdoes not log you in. Callstart_crave_auth, open the returned URL, then callcomplete_crave_auth. - "Restaurant is closed. Scheduled orders are not allowed." Not an auth problem: run
open_location_for_orders({ locationId })for the one-shot fix, then retry. - Sandbox seeding refuses to run.
seed_sandbox_analyticsis guarded by design: it requiresCRAVEUP_ENVIRONMENT=sandbox; there is no production override.
Development
Building
pnpm --filter @craveup/mcp build # compile to dist/Testing
pnpm --filter @craveup/mcp test # vitest — 58 tests across 5 filesProject Structure
src/
├── clients/ # Crave + Expo/EAS API clients
├── tools/ # MCP tool definitions (9 categories)
├── handlers/ # Business logic (readiness, onboarding, guides)
├── helpers/ # Zod schemas, session, env config
├── cli.ts # stdio entry point (craveup-mcp bin)
└── index.ts # Server assembly + tool registration
tests/
└── unit/ # Vitest suites (63 tests)
docs/
├── ARCHITECTURE.md # Layers, auth modes & design decisions
└── TESTING.md # Testing patterns & conventionsDocumentation
| Document | Description |
|----------|-------------|
| CHANGELOG.md | Version history and all changes |
| docs/ARCHITECTURE.md | Layers, authentication modes, and design decisions |
| docs/TESTING.md | Testing strategy, in-memory MCP transport pattern, conventions |
| docs.craveup.com | Hosted Crave Up MCP server guide + Crave.js integration docs (also served at runtime via get_integration_guide) |
| modelcontextprotocol.io | MCP specification |
Error Handling
Tools return structured MCP error results (isError: true) rather than throwing: missing or invalid auth reports which credential is needed (session vs API key vs EXPO_TOKEN), and the API rejects keys that cannot access the requested location. Paid EAS dispatch requires an exact confirmation phrase, location deletion is a recoverable soft-archive, and sandbox seeding refuses to run unless all dev-environment guards are set.
Contributing
Note: development happens in the private Crave Up monorepo; the public craveup/craveup-mcp repo is a read-only mirror synced automatically from
packages/mcp. Bug reports and feature requests are welcome as issues on the mirror; direct pushes and PRs there will be overwritten by the next sync.
Tool naming convention
get_*/list_*/check_*— read-onlycreate_*/update_*/set_*/delete_*— writes, idempotent where possiblestart_*— kicks off an external process (checkout, EAS workflow) and returns a handle
Add tests in tests/unit/ for every new tool; pnpm --filter @craveup/mcp test must pass before publishing (prepublishOnly runs build + tests).
License
MIT — see LICENSE.
