uplayground-events
v0.3.0
Published
CLI and MCP server for live UPlayground event discovery.
Maintainers
Readme
EventChat Events CLI and MCP
Quick Start
Easiest — add the hosted endpoint to any MCP client (claude.ai, Claude Desktop, ChatGPT dev mode, Cursor). No install, no auth:
https://eventchat-events-mcp-production.up.railway.app/mcpStep-by-step per client: https://eventchat-events-mcp-production.up.railway.app/install
One-line client setup from a terminal (writes the config for you):
npx -y uplayground-events install claude-desktop # or: cursor | claude-code | claude-ai | chatgptLocal stdio server snippet for any MCP client config:
{ "command": "npx", "args": ["-y", "uplayground-events", "mcp"] }Claude Desktop one-click bundle: npm run build:mcpb produces dist/uplayground-events-<version>.mcpb — double-click to install.
This package exposes UrbanPlayground's UPlayground live event inventory to agents and humans:
uplayground-events(aliaseventchat-events): a CLI for quick searches, ranked recommendations, night plans, client install, and diagnostics.uplayground-events mcp(aliaseventchat-events-mcp): a stdio MCP server for local developer clients.uplayground-events serve(aliaseventchat-events-http): an HTTP MCP server for hosted connectors/apps.- Agentic ticket tools for ticket offers, locked quotes, written confirmation, checkout handoff, and future Hermes/OpenClaw/UPlayground purchase adapters.
Why This Beats Normal Chat
General chat can describe likely events, but it does not reliably know current inventory. This tool gives an agent:
- Live structured results from UrbanPlayground's
/eventsAPI. - Deterministic filters for city, date, genre, vibe, venue, price, attendance, neighborhood, and artist.
- Explainable ranking so recommendations include reasons instead of opaque taste guesses.
- Ticket links and UPlayground event links for verification.
- A planning tool that returns primary options plus fallbacks in a compact machine-readable shape.
- Consent-based preference learning: onboarding questions, saved taste profiles, post-event feedback, note-derived signals, and learned ranking signals.
- Negative feedback becomes learned avoid signals, so future recommendations can steer away from disliked genres, vibes, event types, or venues.
- Ticket purchase safety rails: agents can quote and prepare ticket orders, but autonomous purchase requires a locked quote, explicit written confirmation, and an integrated purchase provider.
The agent can still write conversational prose, but its event facts come from the tool.
CLI
Run without installing:
npm exec --yes --package uplayground-events -- uplayground-events search --city "Los Angeles" --when week --limit 5
npm exec --yes --package uplayground-events -- uplayground-events recommend --city "New York" --when tonight --vibe underground,intimate --max-price 30Or install the early-access developer package:
npm install -g uplayground-events
eventchat-events search --city berlin --when weekend --genres techno --limit 5From this repository:
node ./bin/eventchat-events.js search --city berlin --when weekend --genres techno --limit 5
node ./bin/eventchat-events.js recommend --city new-york --when tonight --vibe underground,intimate --max-price 30
node ./bin/eventchat-events.js plan --city london --when weekend --event-types party --avoid mainstream
node ./bin/eventchat-events.js cities
node ./bin/eventchat-events.js doctordoctor checks DNS resolution, the API health endpoint, the hosted MCP endpoint (health, metadata, tools/list), and one small live search, reporting the underlying cause of any failure. Run it first whenever a search fails.
Environment (all surfaces — CLI, stdio MCP, hosted MCP, smoke test, and monitor — resolve endpoints through the same src/config.js):
EVENTCHAT_API_BASE_URL=https://backend-production-958d.up.railway.app
EVENTCHAT_WEB_BASE_URL=https://urbanplayground.xyz
EVENTCHAT_MCP_URL=https://eventchat-events-mcp-production.up.railway.app/mcp
EVENTCHAT_API_TIMEOUT_MS=8000
EVENTCHAT_API_RETRIES=2 # transient network/5xx failures retry with backoff + jitter
EVENTCHAT_API_RETRY_BASE_DELAY_MS=250
EVENTCHAT_MCP_ALLOWED_ORIGINS=https://chatgpt.com,https://chat.openai.com,https://claude.aiTransient network failures (EAI_AGAIN, ETIMEDOUT, ECONNRESET, ENOTFOUND, temporary 5xx) are retried automatically and reported as retryable: true with the underlying cause, code, hostname, and target URL when they persist.
MCP For Local Developer Clients
Run the stdio MCP server from npm:
npm exec --yes --package uplayground-events -- eventchat-events-mcpOr from this repository:
node ./bin/eventchat-events-mcp.jsExample MCP client config:
{
"mcpServers": {
"eventchat-events": {
"command": "node",
"args": ["/Users/zakkrevitt/EventChat/ios/EventChat/agent-tools/eventchat-events/bin/eventchat-events-mcp.js"],
"env": {
"EVENTCHAT_API_BASE_URL": "https://backend-production-958d.up.railway.app"
}
}
}
}Example MCP client config using npm:
{
"mcpServers": {
"uplayground-events": {
"command": "npm",
"args": ["exec", "--yes", "--package", "uplayground-events", "--", "eventchat-events-mcp"],
"env": {
"EVENTCHAT_API_BASE_URL": "https://backend-production-958d.up.railway.app"
}
}
}
}Tools:
get_preference_onboarding: returns the questions the assistant should ask before saving preferences.create_event_preference_profile: creates an opaque saved-preference profile after consent and returns a profile id plus private profile secret the assistant can remember.save_event_preferences: saves user preferences only after explicit consent and profile-secret access.get_event_preferences: reads saved and learned preferences with profile-secret access.delete_event_preferences: deletes a profile's saved preferences and feedback with profile-secret access and explicit user confirmation.record_event_feedback: stores post-event liked/disliked signals, ratings, or notes and updates learned signals with profile-secret access. Notes about music, crowd, price, timing, or venue can become learned preference or avoid signals. It rejects empty feedback.get_event_feedback_prompt: returns short post-event follow-up questions for a specific event before feedback is saved.get_event_search_followups: returns only the missing current-context questions before a tonight/week/weekend search.search_events: live structured event search.recommend_events: live search plus explainable taste ranking.recommend_events_for_user: live recommendations using saved preferences and learned feedback with profile-secret access.plan_night: compact plan with fallbacks.get_event: detail lookup by event id.get_ticket_purchase_policy: explains current purchase modes, hard safety rules, and provider requirements.get_ticket_offers: returns ticket options for an event, including checkout URL and whether autonomous purchase is supported.quote_ticket_order: creates a locked quote with quantity, max total, ticket type, expiration, and stop conditions.purchase_ticket_order: accepts explicit written confirmation and either executes an integrated provider purchase or returns the required external checkout handoff.
Annotation note: search and recommendation tools read live event data, and preference tools write only private connector memory protected by profile_id plus profile_secret. Only purchase_ticket_order is marked destructive/open-world because it is the bounded action point for ticket purchases or checkout handoff.
Ticket note: purchase_ticket_order is intentionally marked destructive and open-world because it is the future action boundary for autonomous ticket purchase. In the default npm/hosted build, third-party ticket links return requires_external_checkout; the tool does not scrape checkout pages, bypass CAPTCHAs, or charge cards. True autonomous purchase requires a provider adapter such as Hermes, OpenClaw, UPlayground Checkout, a partner ticketing API, or an approved delegated-payment flow.
Auth note: the public hosted connector submits as noauth for basic event discovery. Saved preference, feedback, personalized recommendation, read, update, and deletion tools still require the user's opaque profile_id plus private profile_secret. Tool descriptors include securitySchemes: [{ "type": "noauth" }] and mirror it in _meta.securitySchemes for ChatGPT compatibility.
Deletion safety note: delete_event_preferences also requires confirm_delete: true, which should only be sent after the user confirms they want to delete UPlayground connector preferences and feedback history.
Retention note: saved preference profiles are automatically pruned after the configured inactivity window, defaulting to 730 days, matching the published 24-month retention policy.
Hosted MCP For ChatGPT And Claude
For normal users, publish a hosted MCP endpoint rather than asking them to run a local command.
PORT=8787 node ./bin/eventchat-events-http.jsEndpoints:
POST /mcp: JSON-RPC MCP endpoint.GET /health: deployment health check.GET /: basic service metadata.GET /privacy-policy.html: public privacy policy for saved preferences, feedback, retention, and deletion.GET /support.html: public support, deletion, and security-contact page.GET /terms.html: public connector terms and acceptable-use page.GET /user-guide.html: public normal-user guide with prompts, preference memory, feedback, and deletion behavior.GET /.well-known/security.txt: vulnerability-reporting contact metadata.GET /logo-512.png: 512px connector logo for submission metadata.
Current deployed endpoint:
https://eventchat-events-mcp-production.up.railway.app/mcpTo become a ChatGPT app/plugin:
- Deploy this HTTP server on a public HTTPS domain.
- Test it in ChatGPT Developer Mode by creating a connector with that URL.
- Validate tool calls on web and mobile.
- Submit the app through the OpenAI dashboard with the public MCP URL, privacy/support URLs, logo, screenshots, test prompts, and tool descriptions.
Claude users can add the same public MCP URL as a custom connector where their plan/workspace supports remote MCP.
See plugin-submission.md and submission-fields.json for the working submission copy.
See OPENAI_SUBMISSION_PACKET.md for the final dashboard handoff packet.
See SCREENSHOT_CHECKLIST.md for exact ChatGPT Developer Mode screenshot prompts and filenames.
See SUBMISSION_AUDIT.md for requirement-to-evidence mapping and remaining external review gates.
See USER_GUIDE.md for normal-user prompts, preference-memory behavior, and support/privacy links.
See DEPLOYMENT.md for Railway, Docker, custom-domain, and review steps.
See OPERATIONS.md for health checks, logs, rollback, preference-data handling, and resubmission triggers.
See golden-prompts.md for direct, indirect, and negative prompt tests for connector discovery and tool routing.
See SECURITY.md for vulnerability reporting and operational safeguards.
Live smoke test:
npm run monitor:live
npm run smoke:livemonitor:live is read-only and suitable for uptime checks. smoke:live also exercises temporary preference profile creation and deletion.
Submission evidence:
npm run verify:submission
npm run verify:submission:write
npm run verify:submission:bundle
npm run verify:submission:fields
npm run submission:status
npm run review:demo
npm run preflight:submissionThe bundle command saves submission-evidence/latest.json and submission-evidence/latest-summary.md for dashboard review prep while keeping generated evidence out of git. The evidence includes the verified endpoint, current Railway deployment id, image digest, public-page checks, tool metadata, live search, and preference-memory flow.
The fields command validates submission-fields.json, the stable dashboard-copy artifact, against the latest live evidence, including deployment metadata.
The preflight command runs local tests, live smoke, live submission evidence generation, and dashboard-field validation in one pass.
The status command gives a final go/no-go for OpenAI dashboard submission, names the endpoint to submit, and keeps unresolved custom-domain status separate from Railway endpoint readiness.
The review-demo command writes a sanitized submission-evidence/review-demo.md transcript from live MCP calls for dashboard prompt/response prep.
Support deletion utility:
npm run preferences:delete -- --profile-id upg_... --profile-secret ups_... --preferences-path /data/preferences.jsonThis is for support deletion requests when the user cannot call delete_event_preferences through their MCP client.
Personalization flow:
- User asks for personalized event help.
- Assistant calls
get_preference_onboardingand asks what events, genres, vibe, budget, locations, and avoidances the user generally likes. - Assistant asks whether UPlayground may save those preferences.
- If yes and there is no existing profile, assistant calls
create_event_preference_profileand privately remembers the returnedprofile_idandprofile_secret. - The creation response also includes
access_instructions, a user-facing access card for clients that cannot persist connector state across sessions. - If a profile already exists, assistant calls
save_event_preferenceswith bothprofile_idandprofile_secret. - For tonight/week/weekend searches, assistant calls
get_event_search_followups, asks lightweight current-context questions, then callsrecommend_events_for_user. - After the event, assistant calls
get_event_feedback_prompt, asks whether the user went and liked it, then callsrecord_event_feedbackonly after the user provides liked/disliked, rating, or notes.
Ticket purchase flow:
- User asks to buy or reserve tickets for an event.
- Assistant calls
get_ticket_offerswith the event id. - Assistant explains whether the offer supports autonomous purchase or only external checkout.
- Assistant calls
quote_ticket_orderwith quantity, ticket type, max total, currency, and refund constraints. - Assistant asks for explicit written confirmation, for example:
Yes, buy 2 ticket(s) for Ostbahnhof XL, max total USD240. Stop if price, date, venue, ticket type, quantity, or refund terms change. - Assistant calls
purchase_ticket_orderonly after that confirmation. - If the quote uses
external_checkout, the tool returnsrequires_external_checkoutand a checkout URL. The assistant must not claim it purchased the ticket. - If Hermes, OpenClaw, UPlayground Checkout, or another integrated provider is configured, the provider can execute the bounded purchase and return order/receipt/ticket delivery status.
Provider adapter contract:
{
canPurchase(event, summary) {
return true;
},
async purchase({ quote, confirmation_text, user_payment_profile_id, idempotency_key }) {
return {
purchased: true,
status: "purchased",
order_id: "...",
receipt_url: "...",
ticket_delivery_status: "pending_delivery",
provider_response: {}
};
}
}Distribution Notes
The public ChatGPT user surface is the hosted MCP endpoint plus OpenAI app submission. The npm package is a day-zero developer distribution path for local agents, Claude Desktop-style MCP clients, Cursor/Windsurf setups, and technical testers who can run a command. It remains marked UNLICENSED because this is a proprietary early-access package, not an open-source release.
Before publishing a new npm version:
npm test
npm pack --dry-run --json
npm publish --access public