Integrations

pickuppatrol-mcp

Try it

Read and change your children's school dismissal plans on PickUp Patrol (app.pickuppatrol.net) from a shell with curl — students, weekly defaults, day-by-day changes, school cutoff times.

What it does

Read and change your children's school dismissal plans on PickUp Patrol (app.pickuppatrol.net) from a shell with curl — students, weekly defaults, day-by-day changes, school cutoff times.

The skill document

PickUp Patrol from a shell

app.pickuppatrol.net is a ServiceStack JSON API behind an Ionic/Vue SPA. It is reachable server-side with plain curl — no bot wall, no captcha, no browser bridge. Use this when you want PickUp Patrol data in a script or on a machine without the pickuppatrol-mcp server.

Full captured shapes: references/api.md.

Sign in once per shell

export PUP_USER='you@example.com'
read -rs PUP_PASS && export PUP_PASS      # never put the password in a command line
export PUP=https://app.pickuppatrol.net/api/json/reply

pup_login() {
  local jar; jar=$(mktemp -t pupjar)
  curl -sS -c "$jar" -X POST "$PUP/Authenticate" \
    -H 'Content-Type: application/json' \
    -d "$(jq -nc --arg u "$PUP_USER" --arg p "$PUP_PASS" \
          '{provider:"credentials",UserName:$u,Password:$p,RememberMe:true}')" \
    -o /tmp/pup_auth.json -w '%{http_code}' >/tmp/pup_code
  [ "$(cat /tmp/pup_code)" = 200 ] || { jq -r '.ResponseStatus.Message' /tmp/pup_auth.json >&2; return 1; }
  export PUP_JAR="$jar"
  # This deployment returns cookies only — BearerToken comes back null. The
  # JWT path exists server-side, so keep a token if one ever appears.
  PUP_TOKEN=$(jq -r '.BearerToken // empty' /tmp/pup_auth.json); export PUP_TOKEN
}

# Every call goes through this: it sends the session cookies, and the bearer
# token as well when the deployment issued one.
pup() {
  local method=$1 dto=$2; shift 2
  local -a auth=(-b "$PUP_JAR")
  [ -n "$PUP_TOKEN" ] && auth+=(-H "Authorization: Bearer $PUP_TOKEN")
  curl -sS -X "$method" "$PUP/$dto" -H 'Content-Type: application/json' "${auth[@]}" "$@"
}

Never re-run a rejected login. PickUp Patrol answers bad credentials with ResponseStatus.ErrorCode starting LOGIN-ERROR, counts the attempt against the account, and a lockout clears only through their support desk. One failure = stop and fix the credentials.

Reads

pup GET GetSession | jq '{name:.DisplayName, email:.Email, kids:[.Children[].StudentId]}'
pup GET GetChildren | jq -r '.[] | "\(.StudentId)  \(.FirstName) — \(.SchoolName)"'

# Weekly default plan for one student. DayId is 1-based, SUNDAY = 1.
pup GET GetChildren | jq '.[] | select(.StudentId==1050046) | .DefaultPlans
  | sort_by(.DayId) | map({day:.WeekDayName, option:.TransportationName, note:.Note})'

# The dismissal options a school offers, with the rules each imposes.
pup GET "GetTransportations?SchoolId=1703" | jq -r '.[] | select(.IsActive)
  | "\(.TransportationId)\t\(.Name)\tnote=\(.IsNoteRequired)\tcar=\(.UseCarNumbers)\tearly=\(.IsEarlyDismissal)"'

# GetPlanEdit returns the date's OVERRIDE, not the effective plan: a date with
# no specific plan reads back null even when a weekday default exists.
pup GET "GetPlanEdit?PlanDate=2026-08-17&StudentId=1050046" | jq '{TransportationName,Note,IsLocked}'
pup GET "GetInvalidPlanDates?SchoolId=1703" | jq 'length'   # non-school days

Writes

Writes change how a child actually leaves school. Read GetTransportations first and obey the option's rules, or the request is rejected (or worse, silently ignored):

  • IsNoteRequiredNote must be non-empty
  • UseCarNumbers → send CarNumber; otherwise omit the key
  • IsEarlyDismissal → send EarlyDismissalTime as HH:MM:SS; otherwise omit it
  • IsLimited → only usable if the id is in the student's LimitedIds

Change specific datesPlans is an array, one entry per date:

pup PUT UpdatePlans -d '{"Plans":[{
  "StudentId":1050046,"SchoolId":1703,"PlanDate":"2026-08-17",
  "TransportationId":41246,"TransportationName":"PickUp","Note":"Chris Hall"}]}'

Clear a date back to the weekly default — a null transportation:

pup PUT UpdatePlans -d '{"Plans":[{
  "StudentId":1050046,"SchoolId":1703,"PlanDate":"2026-08-17",
  "TransportationId":null,"TransportationName":"Default plan","Note":null}]}'

Change the weekly defaults — there is no default-plans endpoint. Read the whole student, edit DefaultPlans, PUT the whole record back (references/api.md has the read-modify-write recipe).

Always re-read to verify

A 2xx is not proof. The school silently ignores a change past its cutoff time.

pup GET "GetPlanEdit?PlanDate=2026-08-17&StudentId=1050046" | jq '.TransportationId'

Compare TransportationId and Note — never ModifiedDate, which advances on its own and would make every write look successful. The note matters: every option seen so far is IsNoteRequired, so a note-only edit is ordinary, and an id-only comparison would pass without observing it. After clearing a date, expect null — not the weekday default.

Related skills

Read a SchoolPass parent account directly with curl against the regional SchoolPass REST API (a busapi shard on school-pass.net), without running the MCP server. Use for a one-off shell read of your students, arrival/dismissal calendar, pending pickup changes, drivers, dismissal locations, or school info — "check SchoolPass from the terminal", "list my kids in SchoolPass", "any dismissal changes today". Requires SCHOOLPASS_EMAIL / SCHOOLPASS_PASSWORD / SCHOOLPASS_SCHOOL_CODE.

This skill should be used when the user asks about their child's school arrival/dismissal through a SchoolPass parent account. Triggers on phrases like "check SchoolPass", "when is my kid dismissed", "what's my dismissal default", "list my students in SchoolPass", "who are my pickup drivers", "any pickup changes today", "school dismissal locations", or any request to read a SchoolPass parent account.

Access AlphaPortal (AlphaRoute) school-bus data — students, stops, live bus GPS location, arrival notifications — from a shell with curl instead of running the alphaportal-mcp server. Capture the signed-in web app's refresh token ONCE (a paste-in-console one-liner, or the fpx browser bridge), then mint access tokens and curl the REST API directly. Use when you want AlphaPortal data without the MCP, in a script, or on a machine where the MCP isn't installed.

Organize child activity registrations with deadline tracking, document checklists, payments, gear, schedules, transportation, and follow-up reminders.

10 installs

Read and manage a My Hot Lunchbox school-lunch account from a shell with curl — sign in, list students, read the lunch calendar and cart, check orders, deliveries and payments. Use when you want My Hot Lunchbox data without running the MCP server, in a script, or on a machine where the MCP is not installed.

This skill should be used when the user asks about Infinite Campus (Campus Parent) data for their student(s). Triggers on phrases like "check grades", "what'...

25 installs