Utilizes Supabase to store and manage nightlife event discovery data, venue and performer information, and VIP booking submissions including availability and status tracking.
nightlife-mcp
MCP server for nightlife event discovery backed by Supabase.
Quick Start
Production endpoint: https://api.nightlife.dev/mcp
Get a free API key at nightlife.dev
Add to Claude Desktop config (
claude_desktop_config.json):
{
"mcpServers": {
"nightlife": {
"url": "https://api.nightlife.dev/mcp",
"headers": {
"x-api-key": "YOUR_API_KEY"
}
}
}
}For curl, TypeScript SDK, and other clients, see CLIENT_SETUP.md.
Implemented (v0.3)
search_eventsget_tonightget_event_detailssearch_venuesget_venue_infosearch_performersget_performer_infolog_unmet_requestcreate_vip_booking_requestget_vip_booking_statusget_vip_table_availabilityget_vip_table_chartget_recommendations(v0.2, behindMCP_ENABLE_RECOMMENDATIONS=true)Streamable HTTP endpoint with API-key middleware
Structured tool output schemas (
outputSchema)Deterministic tool error payloads with stable error codes
Runtime request/tool metrics exposed at
/health
Prerequisites
Node.js 18+
Supabase project URL + service role key
Setup
cp .env.example .env
npm installSet env vars in .env:
SUPABASE_URLSUPABASE_SERVICE_ROLE_KEY
Optional:
DEFAULT_CITY(default:tokyo)MCP_TOP_LEVEL_CITIES(default example:tokyo,san-francisco; controlsavailable_citiesin unsupported-city responses)DEFAULT_COUNTRY_CODE(default:JP)NIGHTLIFE_BASE_URL(default:https://nightlifetokyo.com)MCP_HTTP_REQUIRE_API_KEY(default:true)MCP_HTTP_USE_DB_KEYS(default:true)MCP_HTTP_ALLOW_ENV_KEY_FALLBACK(default:true)MCP_HTTP_API_KEYS(comma-separated legacy fallback keys)MCP_ENABLE_RECOMMENDATIONS(default:false; enablesget_recommendations)
DB API Key Mode (Recommended)
HTTP authentication can use persistent API keys from Supabase plus quota tracking.
Run SQL migration in your Supabase SQL editor:
-- copy file contents from:
-- supabase/migrations/20260219094000_mcp_api_keys.sqlEnsure DB auth flags are enabled in
.env:
MCP_HTTP_REQUIRE_API_KEY=true
MCP_HTTP_USE_DB_KEYS=true
MCP_HTTP_ALLOW_ENV_KEY_FALLBACK=trueCreate an API key record:
npm run key:create -- --name claude-desktop --tier starter --daily-quota 1000 --minute-quota 60This prints the raw api_key once. Save it securely and use it in MCP HTTP calls.
If the DB RPC is unavailable, fallback to MCP_HTTP_API_KEYS works only when MCP_HTTP_ALLOW_ENV_KEY_FALLBACK=true.
Concierge Unmet Request Backlog
Public concierge flows can log unsupported user intents to Supabase.
Run migration:
-- copy file contents from:
-- supabase/migrations/20260226_concierge_unmet_requests.sqlThen call MCP tool log_unmet_request when no good answer exists from available nightlife data.
VIP Booking Phase 1
VIP table booking submission and status tracking are backed by Supabase.
Run migration:
-- copy file contents from:
-- supabase/migrations/20260227143000_vip_phase1_requests_and_queue.sql
-- supabase/migrations/20260228124500_add_vip_booking_enabled_to_venues.sql
-- and if already deployed before 2026-02-28:
-- supabase/migrations/20260228111000_vip_outward_language_defaults.sql
-- supabase/migrations/20260301010000_vip_table_availability_chart.sql
-- supabase/migrations/20260301114000_vip_table_chart_storage_bucket.sql
-- supabase/migrations/20260303093000_vip_dashboard_admin_edits.sqlThen call MCP tools:
create_vip_booking_requestget_vip_booking_statusget_vip_table_availability(read per-day table availability by venue/date range)get_vip_table_chart(read structured table chart with optional per-date status overlay and optionallayout_image_url)
Conversation policy for create_vip_booking_request:
Confirm booking date/time in venue local time before submitting.
Use dual-date confirmation wording, especially for late-night arrivals (
00:00-05:59).Required confirmation template:
Just to confirm: you want a table for [Night Day] night ([Night Date]), arriving around [Time] on [Arrival Day], [Arrival Date] ([Timezone]). I'll submit that as [Night Day] night with [Time] arrival. Is that correct?
If the user gives a time like
2amwithout a day, ask:Do you mean 2:00 AM after Thursday night (Friday morning), or after Friday night (Saturday morning)?
If the user changes day, regenerate confirmation before submission.
Ops-tier sessions also have internal queue tools:
list_vip_reservations(all outstanding reservations; default statuses:submitted,in_review,confirmed)list_vip_requests_for_alerting(due alerts only)mark_vip_request_alert_sentclaim_vip_request_after_ackupdate_vip_booking_status(setconfirmed/rejected/cancelledwith audit event)upsert_vip_venue_tables(write venue table definitions + chart coordinates + optional table notes + optionallayout_image_url)upsert_vip_table_availability(write per-date table statuses)upload_vip_table_chart_image(upload chart image to storage and attachlayout_image_urlto venue table metadata)
To discover bookable venues first, use:
search_venueswithvip_booking_supported_only=trueor
get_venue_infoand checkvip_booking_supported
For internal venue-booking workers, claim queue tasks via DB function:
public.claim_next_vip_agent_task(p_agent_id text)
VIP Ops Dashboard
Internal dashboard routes:
GET /ops/loginPOST /ops/loginPOST /ops/logoutGET /ops/vip-dashboard
Internal admin API routes (cookie-session protected):
GET /api/v1/admin/vip-bookingsGET /api/v1/admin/vip-bookings/:idPATCH /api/v1/admin/vip-bookings/:id
Required env vars:
VIP_DASHBOARD_ADMINS(comma-separatedusername:passwordpairs)
Optional env vars:
VIP_DASHBOARD_SESSION_TTL_MINUTES(default:720)VIP_DASHBOARD_SESSION_COOKIE_NAME(default:vip_dashboard_session)
Run
Stdio (local desktop clients):
npm run devStreamable HTTP:
npm run dev:httpFor production build:
npm run build
npm startFor HTTP in production:
npm run start:httpAuthenticated production smoke check:
NLT_API_KEY=... npm run smoke:prod:authOptional env overrides:
NLT_MCP_URL(default:https://api.nightlife.dev/mcp)NLT_REST_BASE_URL(default:https://api.nightlife.dev/api/v1)NLT_SMOKE_CITY(default:tokyo)
Debug web UI for recommendations:
MCP_ENABLE_RECOMMENDATIONS=true npm run dev:http
# open http://127.0.0.1:3000/debug/recommendationsNotes
Date handling supports
tonight,this_weekend,YYYY-MM-DD, andYYYY-MM-DD/YYYY-MM-DD.get_recommendationsreturns up to 10 diverse modal slots with dynamic city-aware fallback.Venue and performer tools include upcoming events snapshots.
log_unmet_requestwrites unresolved user asks topublic.concierge_unmet_requests.VIP phase 1 writes booking submissions to
public.vip_booking_requestsand worker queue tasks topublic.vip_agent_tasks.VIP inventory writes table definitions to
public.vip_venue_tablesand date-specific statuses topublic.vip_table_availability.search_venuesandget_venue_infoincludevip_booking_supportedso clients can show exactly which venues accept VIP booking submissions.vip_booking_supportedis sourced frompublic.venues.vip_booking_enabled(separate fromguest_list_enabled).create_vip_booking_requestonly accepts venues wherevip_booking_supported=true.City handling is backed by
public.cities(slug, timezone, and service-day cutoff).Supported top-level cities are environment-configurable (for example
tokyoandsan-francisco) while Tokyo can remain the default.Stdio transport: no API key check.
HTTP transport (
/mcp): API key required by default (MCP_HTTP_REQUIRE_API_KEY=true).API key headers:
Authorization: Bearer <key>x-api-key: <key>
HTTP responses include key tier/source and rate-limit headers when DB-backed auth is active:
X-API-Key-TierX-API-Key-SourceX-RateLimit-Daily-LimitX-RateLimit-Daily-RemainingX-RateLimit-Minute-LimitX-RateLimit-Minute-Remaining
Health endpoint:
/health.Debug page for manual tool testing:
/debug/recommendations.Tool errors are returned as JSON text payloads in
result.content[0].text:INVALID_DATE_FILTERINVALID_EVENT_IDUNSUPPORTED_EVENT_IDEVENT_NOT_FOUNDINVALID_VENUE_IDVENUE_NOT_FOUNDINVALID_PERFORMER_IDPERFORMER_NOT_FOUNDINVALID_BOOKING_REQUESTBOOKING_REQUEST_NOT_FOUNDBOOKING_STATUS_UPDATE_FAILEDVIP_TASK_NOT_AVAILABLEVIP_ALERT_UPDATE_FAILEDVIP_CLAIM_FAILEDINVALID_REQUESTREQUEST_WRITE_FAILEDDB_QUERY_FAILEDINTERNAL_ERROR
Resources
Looking for Admin?
Admins can modify the Dockerfile, update the server description, and track usage metrics. If you are the server author, to access the admin panel.