Skip to content

Investigate vrc.tl public API + add Timeline tools #1

@BASIC-BIT

Description

@BASIC-BIT

Background

vrc.tl ("Timeline") is a public, unauthenticated site that aggregates VRChat club events (timeline view, club pages, event detail pages). Since it works without VRChat auth, we can likely integrate it as an optional, read-only data source in this MCP server.

I did a quick Playwright/network pass and confirmed it uses a small set of JSON endpoints under https://vrc.tl/api/v1/.

API endpoints observed (no auth)

  • GET https://vrc.tl/api/v1/events

    • Response shape: { lastUpdates, eventData, live, range }
    • range: { firstLoadedDay: "YYYY-MM-DD", lastLoadedDay: "YYYY-MM-DD" } (seems to default to a small window around “now”; query params like from/to and start/end were ignored in my tests)
    • eventData: { events, organizers, performers }
      • events[] item keys (sample): id, name, description, category, tags, organizers, hostOrganizer, start, end, duration, urls, poster, isHighlighted, extensions, promoted, eventSlots, showSlots
      • Important: category is numeric; tags is an array of numeric IDs; event organizers are referenced by numeric IDs.
  • GET https://vrc.tl/api/v1/events/{eventId}

    • Response shape: { events, organizers, performers }
    • events is an array (observed events.length === 1) and includes the detailed event object.
    • Event object includes eventSlots[] with per-slot start/duration/performers/flag.
  • GET https://vrc.tl/api/v1/organizers

    • Returns an array of organizer/club objects (observed ~852).
    • Keys (sample): id, name, shortCode, slug, vrcGroup, discordInv, twitter, blueSky, instagram, twitch, mixcloud, logo, banner, isSupporter, providesInstances, ...
  • GET https://vrc.tl/api/v1/organizer/{organizerId}/events?page={n}

    • Response shape: { page, hasMorePages, data }
    • data: { organizers, events, performers } (dataset pattern again)
  • GET https://vrc.tl/api/v1/organizer/{organizerId}/collaborators

    • Response shape: { organizers: [...] }

Proposed MCP tools

Name bikeshed, but roughly:

  • vrctl_events_current
    • Calls /api/v1/events
    • Returns compact list of events in the returned range window, with resolved organizer names + key links.
  • vrctl_event_get
    • Calls /api/v1/events/{eventId}
    • Returns event details + resolved organizers/performers + slot schedule.
  • vrctl_organizers_search
    • Calls /api/v1/organizers (cached), filters by name/slug/shortCode.
    • Returns small summaries + IDs for follow-ups.
  • vrctl_organizer_get
    • Uses cached organizers list (or a future /api/v1/organizer/{id} if it exists) and returns details.
  • vrctl_organizer_events
    • Calls /api/v1/organizer/{id}/events?page={n}.
  • vrctl_organizer_collaborators
    • Calls /api/v1/organizer/{id}/collaborators.

Notes / open questions

  • Category + tag ID mapping: API exposes numeric IDs; the website has human labels (Music/Podcast/etc and tags like Windows/Android/flashing lights). We need a mapping strategy:
    • Option A: ship a mapping table (derived from vrc.tl frontend) and keep it updated.
    • Option B: return numeric IDs + “best-effort” labels only for a small stable subset.
  • Events range expansion: /api/v1/events appears to return a limited window; need to determine how the site loads more days (if it does) and whether there’s an undocumented endpoint/param for requesting arbitrary ranges.
  • Caching: organizers list is large; should be cached with TTL and invalidation.

Acceptance criteria

  • New read-only tools added behind a clear namespace/prefix (e.g. vrctl_*).
  • Tool outputs are curated (compact lists by default, include IDs for follow-ups).
  • Add basic tests (mock responses) to lock response parsing + tool output shape.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions