360 Secure SkillHub
360 安全技能中心

myhotlunchbox-mcp

该Skill基于My Hot Lunchbox公开的OAuth2 JSON API,提供shell环境下的curl操作封装,无需安装MCP服务,适用于无MCP环境或自动化脚本场景。通过环境变量传入账号密码登录获取令牌,可查询绑定学生信息、午餐日历、购物车、订单、配送、支付记录,也支持读-改-写模式调整订单,输出为JSON或PDF报表。需注意登录失败勿重试,写操作、支付接口需谨慎调用。

chrischall
chrischall
热度 61.66
最近更新 2026-10-10 07:28:42
分类:api_integration依赖:curl / jq应用场景:school_lunch / account_management / shell

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add myhotlunchbox-mcp
Metadata
name
myhotlunchbox
description
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.

My Hot Lunchbox from the shell

ordernow.myhotlunchbox.com exposes a plain JSON API behind an OAuth2 password grant. It is reachable server-side — no browser, no extension, no bridge. Two curl calls get you data: one to sign in, one per read.

Sign in once per shell

Credentials come from the environment; never paste them into a command line (that puts them in shell history).

export MHLB_USER='you@example.com'
export MHLB_PASS='…'          # e.g. read -rs MHLB_PASS
export MHLB=https://ordernow.myhotlunchbox.com

mhlb_login() {
  local resp
  resp=$(curl -sS -X POST "$MHLB/api/auth/login" \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    -H 'Accept: application/json' \
    --data-urlencode 'grant_type=password' \
    --data-urlencode "username=$MHLB_USER" \
    --data-urlencode "password=$MHLB_PASS" \
    --data-urlencode 'scope=openid offline_access email profile roles') || return 1
  MHLB_TOKEN=$(printf '%s' "$resp" | jq -r '.access_token // empty')
  if [ -z "$MHLB_TOKEN" ]; then
    printf '%s' "$resp" | jq -r '.error_description // .error // "login failed"' >&2
    return 1
  fi
  export MHLB_TOKEN
}

# Authenticated GET.  usage: mhlb_get /parent/childrenInfo [curl args…]
mhlb_get() {
  local endpoint=$1; shift   # NOT `path`: zsh ties $path to $PATH
  curl -sS "$MHLB/api$endpoint" -H "Authorization: Bearer $MHLB_TOKEN" -H 'Accept: application/json' "$@"
}

mhlb_login && mhlb_get /auth/userinfo | jq '{name, email, students_count, pending_orders_count, parent_credit_value}'

A failed sign-in must not be retried. The server is OpenIddict and counts failed attempts; repeated failures can escalate to a CAPTCHA and remove server-side sign-in for that account entirely. If invalid_grant comes back, stop and check the credentials.

The token lasts about an hour. Re-run mhlb_login when a call starts returning 401.

The three reads that answer most questions

# Who the students are — the id feeds everything else
mhlb_get /parent/childrenInfo | jq '.[] | {id, firstName, schoolName, gradeTeacher, isInactive}'

# The lunch calendar for a date range (POST, despite being a read).
# The fields are `start`/`end`. Using `startDate`/`endDate` returns 200 with an
# EMPTY events array — a silent wrong answer, not an error.
curl -sS -X POST "$MHLB/api/calendar/studentSchoolData" \
  -H "Authorization: Bearer $MHLB_TOKEN" -H 'Content-Type: application/json' \
  -d '{"start":"2026-09-01","end":"2026-09-30"}' | jq '.events[] | {studentId, id, start, className}'

# What is in the cart but not yet paid for
mhlb_get '/event/shoppingCart' | jq .

references/endpoints.md has the rest — deliveries, transactions, subscriptions, gift cards, per-day order detail, and the printable reports.

Ordering is read-modify-write

There is no "add item X" call. To place or change an order you fetch the model, edit it, and post it back whole:

mhlb_get '/event/createOrder?eventId=123&studentId=456' > order.json
# edit quantities in order.json
curl -sS -X POST "$MHLB/api/event/createOrder" \
  -H "Authorization: Bearer $MHLB_TOKEN" -H 'Content-Type: application/json' \
  -d @order.json

Anything missing from the payload is cleared, not preserved.

The write request bodies are unverified — their paths and verbs were read out of the site's own compiled client, but no write has been exercised against a live account. Inspect what you are about to send, and re-read the resource afterwards to confirm it landed. A 200 is not proof.

/payment/checkout charges a real card. Do not call it speculatively.

Reading the errors

Status Meaning
400 + invalid_grant wrong username/password — do not retry
401 on an API call token expired; run mhlb_login again
403 the endpoint belongs to the school-admin or vendor role, not a parent
non-JSON 200 either a /parentReports/print* PDF (expected — see references) or the session lapsed into an HTML page
500 on /parentReports/printOrders usually a caller mistake: empty studentIds, or no order matching that date and status

Prefer the MCP when it is available

myhotlunchbox-mcp wraps all of this with typed tools and a confirmation step for every mutation — a prompt where the client can show one (unless the server sets MCP_CONFIRM_ELICITATION=off), otherwise a preview plus a single-use confirmToken. Use this skill when the MCP is not installed, or inside a script.