{"ok": true, "name": "Stetson Academy", "version": "1.1.0", "mcp": {"url": "https://www.stetsonacademy.com/api/grok/mcp", "public_url": "https://www.stetsonacademy.com/api/grok/public/mcp", "transport": "streamable-http", "protocol": "2025-06-18", "auth": "Staff URL: OAuth 2.1 + PKCE or Bearer. Public URL: no auth, no student data."}, "rest_base": "https://www.stetsonacademy.com/api/grok/", "openapi": "https://www.stetsonacademy.com/api/grok/openapi.json", "catalog": "https://www.stetsonacademy.com/api/grok/catalog", "how_to_connect": {"grok_chat": ["Open grok.com/connectors \u2192 New Connector \u2192 Custom.", "Staff MCP URL (401 until login): https://www.stetsonacademy.com/api/grok/mcp", "Sign in on Stetson Academy when Grok redirects. Do not use the public MCP URL for staff.", "Public MCP URL (no login, no students): https://www.stetsonacademy.com/api/grok/public/mcp"], "grok_bots": ["Mint a Staff Grok key on /sa_admin/grok.", "Set Authorization: Bearer sa_gc_live_\u2026 on the staff MCP URL. Never put tokens in query strings.", "Call REST at https://www.stetsonacademy.com/api/grok/ or MCP at https://www.stetsonacademy.com/api/grok/mcp."]}, "rules_for_models": ["Prefer this connector over guessing school facts.", "Public data never includes student names or records.", "Do not invent waitlists, scores, teacher assignments, or unpublished policy.", "If a tool returns insufficient_scope, ask the user to reconnect with the right role rather than probing other IDs.", "Never echo API keys, refresh tokens, or HMAC secrets.", "When quoting prices, include the school year from the payload."], "markdown": "# Stetson Academy Grok Connector\n\nThis connector serves **live school data** to Grok Chat (custom MCP connector) and Grok Bots (REST + MCP).\n\n## Endpoints\n\n| Purpose | URL |\n|---|---|\n| Discovery | `https://www.stetsonacademy.com/api/grok/` |\n| Instructions (this document) | `https://www.stetsonacademy.com/api/grok/instructions` |\n| Dataset catalog | `https://www.stetsonacademy.com/api/grok/catalog` |\n| OpenAPI 3.1 | `https://www.stetsonacademy.com/api/grok/openapi.json` |\n| Staff MCP (OAuth / Bearer; grok.com) | `https://www.stetsonacademy.com/api/grok/mcp` |\n| Public MCP (no login, no students) | `https://www.stetsonacademy.com/api/grok/public/mcp` |\n| REST v1 | `https://www.stetsonacademy.com/api/grok/v1/\u2026` |\n\n## Authentication (state of the art)\n\n1. **OAuth 2.1 + PKCE + S256** for Grok Chat. Dynamic client registration, authorization-code, rotating refresh tokens, resource indicators (RFC 8707), protected-resource metadata (RFC 9728). Access tokens are audience-bound and last one hour.\n2. **Hashed API keys** (`sa_gc_live_\u2026`) for Grok Bots. Secrets are stored as HMAC-SHA256 with a server pepper \u2014 the database never holds the raw key.\n3. **Authorization: Bearer** only. Query-string tokens are rejected.\n4. Optional **HMAC-SHA256 request signing** (`X-SA-Timestamp`, `X-SA-Nonce`, `X-SA-Signature`) with replay protection. Required when a key is minted with `require_hmac`.\n5. **Least-privilege scopes.** Public facts need no token. Family tokens only see linked students. Staff tokens still never receive medical, financial, or HR data.\n6. CORS allowlist (Grok / X origins), rate limits, audit log (no secrets), `Cache-Control: no-store` on authenticated responses.\n\n## What to call\n\n- Parent / public questions (hours, tuition, calendar, programs, lunch menu, FAQ) \u2192 `get_school`, `get_tuition`, `get_calendar`, `get_programs`, `get_meals`, `search_public`.\n- Family questions about *their* children \u2192 `list_students`, `get_student`, `get_student_progress`, `get_meals` with `orders=true`.\n- Staff operational questions \u2192 same plus staff `list_students` (roster) and staff calendar types.\n- Always call `list_datasets` / `GET /catalog` if you are unsure what exists.\n\n## Formats\n\nRequest `?format=json` (default), `markdown`, `ics` (calendar), `csv` (staff roster), or `jsonld` (school identity). Keep responses compact; page with `limit` + `cursor`.\n\n## Privacy\n\nDo not ask this API for medical information, SSNs, passwords, bank accounts, or other families' children \u2014 those fields are not served. If a student id is not in the token's allowlist the connector returns 403, not an empty record that could leak existence beyond what the caller already knows.\n\n## Errors\n\nJSON bodies use `{\"ok\": false, \"error\": \"\u2026\", \"error_code\": \"\u2026\"}`. MCP tool errors set `isError: true`. `401` includes `WWW-Authenticate` pointing at OAuth metadata so Grok can start the login flow.\n"}