Version
DESTRUCTIVE

start_next_season

Duplicate a finished pass series into its next season — a new inactive pass_series plan with the same settings, an empty slate, and the old season linked to it. Not idempotent.

The plan list's "start next season" button, for agents. It creates a new plan of kind pass_series copied from the one you name — same price, currency, description, eligibility, linked resources, overlap rule, sales cutoff and seat cap — with two deliberate differences: it is created inactive, and its slate is empty. A season that went straight on sale with last year's dates in it would be selling something that has already happened.

The step a hand-built successor forgets is the link: the old season's successor_plan_id is pointed at the new plan (and a presale window is set if the old season had none), which is what lets current holders be offered the next season first. Rules are copied forward with their date bounds shifted by the length of the finished season, so "every pass in September" becomes next September; the slate itself and any blackouts are not copied, because both name specific windows that have run.

Not idempotent — call it once per season

Every call creates another plan, named after the source with a season number appended — Match Day Season (Season 2), then (Season 3), and so on — and re-points the old season's successor at the newest one. Check pass_series.successor_plan_id on the source with get_plan before calling; if it is already set, the next season exists.

Emits plan.created for the new plan. The new season is then composed and published like any other: add dates with update_plan — pass_series.window_ids from list_pass_windows, or pass_series.rules — and put it on sale with publish_plan.

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Fires one event

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveOpen world

A client that honours annotations asks a person before running it. It reaches beyond Subscriby: a connector, a provider or a member.

Arguments

plan_id*string

UUID of the finished pass_series plan to duplicate into its next season.

What it returns

{  "data": {    "id": "9e12f0b4-7c3a-4d58-b2e6-0a5f81c4d739",    "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",    "name": "Match Day Season (Season 2)",    "description": "Every home match this season",    "price": "180.00",    "currency": "USD",    "kind": "pass_series",    "cadence": "For all 0 passes",    "active": false,    "created_at": "2026-12-01T09:00:00+00:00",    "pass_series": {      "timezone": null,      "window_count": 0,      "starts_at": null,      "ends_at": null,      "seat_cap": 50,      "seats_remaining": 50,      "successor_plan_id": null    }  }}

The row is the new plan's, in the get_plan shape. active is false and window_count is 0 until you compose it; starts_at, ends_at and timezone are null because a slate with no dates has no span. Its own successor_plan_id is null — it is the source plan whose successor_plan_id now points here.

How it fails

VALIDATION_FAILED

plan_id names a plan whose kind is not pass_series

RESOURCE_NOT_FOUND

unknown plan_id, a plan on another team's project, one outside the

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks project-subscription-plan:create.

How is this guide?

Last updated on