Skip to main content
Glama
Jayb1u3

MyAndrews MCP

by Jayb1u3

MyAndrews MCP

Local, read-only MCP access to Andrews University's Ellucian Experience portal (MyAndrews).

Tools

  • connect, status

  • academic_profile

  • classes, class_schedule

  • degree_progress

  • advisors

  • account_balances

  • tasks, notifications

  • portal_cards

  • dashboard — generates an optional interactive Hermes widget; finances and advisors are opt-in

Authentication opens Andrews SAML/Duo in a Playwright browser. The resulting browser state is stored locally as auth-state.json with mode 0600. Passwords and Duo codes are never accepted by the MCP.

Tenant requests (/api/user, tasks, notifications, Degree Works, …) run as same-origin fetch calls inside a headless Chromium page seeded from that saved state (Playwright consumes it as storage_state; cookie values are never replayed over plain HTTP). The session is validated by loading the tenant root; any redirect away from it yields session expired — reconnect required (needs a visible browser / possibly Duo). Nested tool calls (for example dashboard) share one browser.

academic_profile and account_balances use a split transport because the browser blocks their cross-origin fetch to integrate.elluciancloud.com (CORS): the browser session first mints the short-lived OAuth bearer token from the tenant /api/oauth route, then a direct httpx client calls the exact-host-allow-listed HTTPS URL with only Authorization: Bearer, Accept, Origin, and Referer headers. No cookies or saved state are ever handed to httpx (test_no_raw_cookie_replay enforces this). A 401/403 from the bearer API is reported as a rejected token with the reconnect message; other failures are bounded and never include the token.

Outputs carry provenance: status reports transport, saved_state, and checked_at; degree_progress reports source, fetched_at, card_id, audit_query, choice_count, audit_populated, and per-route errors; classes/class_schedule add _provenance distinguishing a live refresh from the cached localStorage snapshot. Degree Works uses the origin-level /api/degree-works/degrees/… and /api/degree-works/audit/… routes with the all-accounts|Ellucian|DegreeWorks|DegreeWorksAuditCard identifier.

The live degrees payload is {degrees: [{degree: {description, key}, level: {description, key}, school: {description, key}, …}], reportFormat, resDashUrl}. The audit query is ?degree=<degree.key>&level=<school.key>, raw strings percent-encoded with trailing spaces preserved. Quirk (recon-proven 2026-09-03 by live browser comparison): despite its name, the audit API's level parameter is filled by the SPA from record.school.key (12-char padded), not record.level.key (6 chars). Sending level.key returns an HTTP 200 empty list; sending school.key returns the populated audit. degree_choices() therefore prefers school.key, then falls back to nested level.key, then flat level/levelCode for legacy shapes. An HTTP 200 audit that is structurally empty ([]/{}) is never reported as success: it is recorded in errors.audit, and degree_progress raises when neither a recognised choice nor a populated audit is available. dashboard then falls back to the cached audit snapshot and reports degree_error.

The server is read-only against Ellucian. Class tools can refresh the portal's own cache; they do not change registration.

Related MCP server: Moodle Student MCP

Run

uv venv .venv
uv pip install --python .venv/bin/python -r requirements.txt
.venv/bin/playwright install chromium
.venv/bin/python server.py

Test

.venv/bin/python -m py_compile server.py test_server.py
.venv/bin/python test_server.py          # offline, deterministic, no credentials
.venv/bin/fastmcp inspect server.py:mcp
hermes mcp test ellucian                 # expects 12 tools

test_server.py uses fakes for Playwright and never reads auth-state.json. A privacy-safe live smoke prints only connection state and shapes:

.venv/bin/python .backups/smoke_live.py   # prints booleans/types/key names/errors only

Exit codes of the private recon script (~/.hermes/private/ellucian-recon/recon_browser.py): 0 verified, 2 session expired, 3 Degree Works unreachable, 4 reachable but unverified (no choice derived or empty audit).

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers