Compass Education for AI assistants

Ask your AI assistant questions about your school's Compass data, scoped to whatever your existing Compass permissions allow.

What it does

Compass Education for AI assistants is a Model Context Protocol connector. Once added to a supported AI assistant, the assistant can read your Compass data through natural-language questions — without you leaving the chat.

The connector is read-only: it can answer questions, but it cannot create, change or delete anything in Compass. Authentication uses your normal Compass sign-in, and the assistant only ever sees data your Compass role already lets you see.

Set up

Claude

  1. Open Claude.ai (or Claude Desktop) and go to Settings › Connectors.
  2. Click Add custom connector.
  3. Paste this server URL:
    https://mcp.compass.education/mcp
  4. Click Add. Claude opens a school picker — search for your school by name.
  5. Log in with your normal Compass credentials. Claude is now connected.

Once Compass is listed in the Anthropic Connectors Directory, you'll also be able to add it directly from Claude's connector list without pasting the URL.

Example prompts

Things you can ask once connected. Whether each prompt works depends on your Compass role — for example, chronicle questions only work for users whose Compass role grants chronicle access.

"Show me Harry Smith's attendance for the current term and flag any unapproved absences."
"List the chronicle entries logged this week for Year 9 students, grouped by category."
"When does Year 11 Business Management next meet, and who's on the roster?"
"What does Alice have due in the next fortnight across all her subjects?"

Permissions & data handling

Tool reference

This is the full set of tools the connector can advertise. The tools you actually see in your assistant depend on your Compass role — tools you don't have permission to use are hidden from your session automatically.

Check API Key Status

check_api_key_statusread-only
Re-check the user's Compass API Key and return a status with remediation instructions.
Use when: another tool returns an authorization error, or the user asks why tools aren't working.
Returns: { status, message, instructions, helpUrl, baseUrl, checkedAt } status envelope.
Scope: session-user only (the caller's own profile).
Caveats: surfaces the returned `instructions` to the user verbatim.

List Students

get_students_basicread-only
Cursor-paginated browse of every student at the school.
Use when: walking the full student list, or fetching basic identifiers for a known cursor position.
DO NOT use for name lookups (no name filter — use search), and DO NOT expect yearLevel / formGroup / page-size filters: the upstream V6 endpoint is a pure cursor browse and the only knob is `activeOnly`. For year-level / form-group cohort questions, walk the cursor and filter on the returned `yearLevel` / `formGroup` fields client-side.
Returns: items[{ compassPersonId, organisationUserId, importIdentifier, fullName, yearLevel, formGroup }], totalReturned, hasMore, nextCursor.
Scope: whole-school — all currently active students the caller can see (set activeOnly=false for alumni / on-hold).
Caveats: medical/access-restriction/contact fields are stripped on the Compass side; sensitive details are not returned.

Search Directory

searchread-only
Type-ahead search across all directory entities (staff, students, parents, subjects, activities, etc.).
Use when: resolving a name or label to its canonical id before pivoting into a richer tool.
Returns: items[{ id, role, organisationUserId?, description, additionalInfo, formGroup, firstName, lastName, preferredFirstName, preferredLastName }], totalReturned, hasMore.
  • `id` is the universal autosuggest id (string) — always present.
  • `organisationUserId` is the numeric Compass user id and is ONLY populated for user-shaped roles (staff/student/parent); null otherwise.
  • Pass `kinds` to constrain result types (e.g. ['Student'], ['Staff','Parent']) when you only want certain entity classes.
Scope: whole-school — same hits the global Compass search bar would surface to the calling service account.
Caveats: returns up to 12 results; 2+ characters required.

Get User Profile

get_user_profileread-only
Lightweight identity card for a user.
Use when: confirming who a numeric organisationUserId refers to, or fetching name + role + year level for display.
Returns: item{ compassPersonId, organisationUserId, importIdentifier, displayName, firstName, lastName, preferredFirstName, preferredLastName, yearLevel, formGroup, baseRole, hasPhoto }.
Scope: a single user identified by targetUserId (numeric organisationUserId).
Caveats: no contact PII, no medical, no addresses — use get_student_record for richer data.

Get Student Record Summary

get_student_recordread-only
Counts of items in each subsystem of a student's record.
Use when: answering 'does Harry have any medical records on file?' or 'how many emergency contacts are listed?' without exposing the underlying PII.
Returns: item{ organisationUserId, importIdentifier, displayName, yearLevel, formGroup, counts{ medicalRecords, doctors, emergencyContacts, addresses, relatedUsers, learningNeeds, identifications, debtors, rollFlags, accessRestrictions, previousSchools } }.
Scope: a single student identified by targetUserId.
Caveats: only counts are returned at the AI tier; the actual record contents are not surfaced.

Get Chronicle Summary

get_chronicle_summaryread-only
Per-category chronicle aggregate for a single student.
Use when: summarising a student's behaviour footprint by category (Awards, Negative Behaviour, Wellbeing, Medical, etc.).
Returns: items[{ category, categoryId, totalCount, totalPoints, yearCount }], totalReturned, hasMore.
Scope: a single student identified by targetUserId.
Caveats: pinned-entry bodies are dropped — use get_chronicle_entries_thin for the per-entry view.

List Chronicle Entries

get_chronicle_entries_thinread-only
Paginated, filterable chronicle entries in a thin/structured projection.
Use when: looking for behaviour patterns, recent incidents, or rated entries over a date range.
Returns: items[{ chronicleEntryId, createdTimestamp, occurredTimestamp, createdBy, category, categoryId, templateName, rating, points, needsApproval, associatedActivityId, primaryAttendeeId, attendeeNames, attendeeCount }], totalReturned, hasMore, nextCursor.
Scope: chronicle entries the calling service account is permitted to see; filter by studentFilter to narrow.
Caveats: free-text bodies are NOT returned at the AI tier; only structured fields. Timestamps are school-local naked ISO 8601 (no Z, no offset).

Get User's Chronicle Feed

get_user_chronicle_feedread-only
Per-student chronicle feed (paginated, filtered by category + date range), flattened to one row per entry.
Use when: drilling into a single student's chronicle history (the per-student variant of get_chronicle_entries_thin).
Returns: items[{ chronicleEntryId, parentEntryId, createdTimestamp, occurredTimestamp, createdBy, category, categoryId, templateName, rating, points, needsApproval, associatedActivityId, primaryAttendeeId, attendeeNames, attendeeCount, commentCount }], totalReturned, hasMore, nextCursor.
Scope: one student identified by targetUserId, over [startDate, endDate]. Pagination is `start` (skip offset, 0-indexed) + `pageSize` to mirror the upstream ChronicleV2 GetUserChronicleFeedThin contract.
Caveats: omit filterCategoryIds (or pass an empty array) for ALL categories — matches the upstream UI's default `All categories` view, which posts the `[-1]` sentinel. Pass explicit ids (resolve via get_chronicle_summary) only when narrowing. Free-text bodies are NOT returned. Timestamps are school-local naked ISO 8601 (no Z, no offset).

Get Chronicle Entry

get_chronicle_entryread-only
Drill into one full chronicle entry record (verbatim, includes free-text body and attachment metadata).
Use when: an LLM has a chronicleEntryId from get_user_chronicle_feed / get_chronicle_entries_thin and the user wants the full incident detail.
Returns: item{ ...full ChronicleEntryTransport record... }.
Scope: one chronicle entry identified by chronicleEntryId.
Caveats: response is unredacted by design; surface free-text fields to the user with care. Unlike the thin / feed chronicle tools, dates here remain in upstream UTC ISO 8601 (with trailing 'Z'). Use the thin/feed tools for bulk queries.

Get Attendance Summary

get_attendance_summaryread-only
Per-class attendance summary for one student over a date range — one row per subject/class.
Use when: answering 'is Harry's attendance OK?', 'which subjects is she missing the most?', or 'what's his class % in 9MAT?'.
Returns: items[…], totalReturned, hasMore. Mirrors the staff 'Attendance Summary' widget; payload is flat regardless of window length (term/year/since-enrolment all fine).
Priority fields (lead with these when summarising; group as in the staff widget):
  • Subject identity: subjectName + activityName (e.g. 'Year 11: Business Mgmt — 11BUSB'), formGroup
  • In Class:     present (Prsnt), lateApproved (Late Appr), lateUnapproved (Late Un'd), totalAttended (Total)
  • Out of Class: notPresentCounted (Counted), notPresentNotCounted (Non-Counted), notPresentUnapproved (NP Un'd), totalNotAttended (Total)
  • Class %:      percentageClass (0..1 — ×100 for display)
Secondary fields (approvedEducationalActivity, authorisedAbsence, unauthorisedAbsence, percentageOverall/Vce/School/AccountedFor, notPresentApproved, instancesMarked, possible) — return only on explicit ask.
Scope: one student identified by targetUserId (numeric organisationUserId), over [startDate, endDate].
Caveats: no per-day breakdown — use get_attendance_lines or get_attendance_period_lines for incident-level detail.

Get Year Level Attendance Summary

get_attendance_summary_for_year_levelread-only
Per-student attendance summary across one year-level cohort over a date range — one row per student.
Use when: answering 'how is Year 10's attendance tracking?', 'which Year 8 students are below 80% class %?', or pulling a cohort-wide attendance snapshot for a year level.
Returns: items[{ userId, userImportIdentifier, userName, firstName, lastName, formGroup, present, lateApproved, lateUnapproved, notPresentUnapproved, notPresentCounted, notPresentNotCounted, totalAttended, totalNotAttended, percentageClass }], totalReturned, hasMore. Mirrors the staff 'Year Level Attendance Summary' widget priority columns; secondary counts/percentages are intentionally omitted — use get_attendance_summary for one student's full breakdown.
Scope: every student in the cohort identified by yearLevelId, over [startDate, endDate]. Resolve yearLevelId via get_reference_year_levels. Hard-capped at 1000 students per call (hasMore=true signals overflow).
Caveats: optional percentage-band filters (inClass/okClass/vce/schl) and perspective default to the staff widget's 'no filter' position; for one student's per-class breakdown use get_attendance_summary instead.

List Attendance Notes

get_attendance_notesread-only
Whole-school attendance notes (parent-approved absences / late notes) within a date window.
Use when: auditing approval coverage, finding notes a parent left, reviewing extended-status usage across the school.
Returns: items[{ targetCompassPersonId, creatorCompassPersonId, start, finish, enteredTimestamp, details, statusId, departmentApproved }], totalReturned.
Scope: every approval/note overlapping [startDate, endDate]. Pair with search / get_student_record to resolve compass-person ids back to names.
Caveats: free-text 'details' may carry medical / pastoral commentary - surface with care. Timestamps are school-local naked ISO 8601 (no Z, no offset).

List Attendance Lines

get_attendance_linesread-only
Whole-school attendance lines (presence / absence / late) within a date window, at configurable slice granularity.
Use when: building attendance trends or daily roll summaries across the school.
Returns: items[{ compassPersonId, campusGuid, start, finish, arrivalTimestamp, departureTimestamp, updatedTimestamp, sliceCode, prevalentOverallStatusId, prevalentCountedAbsenceStatusId, prevalentNonCountedAbsenceStatusId, expectedMinutes, countedAbsenceMinutes, nonCountedAbsenceMinutes, schoolArrivalGapMinutes, schoolDepartureGapMinutes, unmarkedMinutes, unscheduledMinutes, description }], totalReturned, hasMore.
Scope: every line overlapping [startDate, endDate] at the chosen sliceType (10=PeriodByPeriod, 20=HalfDay, 30=Day default).
Caveats: high-volume endpoint - narrow your date window first. For per-incident analysis prefer get_attendance_period_lines. Timestamps are school-local naked ISO 8601 (no Z, no offset).

List Period Attendance Lines

get_attendance_period_linesread-only
Per-period attendance lines for the whole school (paginated, V4 detail).
Use when: investigating period-level patterns or stitching attendance against schedule events.
Returns: items[{ compassPersonId, campusGuid, start, finish, updatedTimestamp, periodCode, prevalentOverallStatusId, expectedMinutes, description, standardClassShadow, teachingTime, periodLineId }], totalReturned, hasMore.
Scope: every period line overlapping [startDate, endDate]. Server-side default page 100, hard cap 500.
Caveats: high-volume endpoint - narrow window first; for trend / total-day reporting use get_attendance_lines (sliceType=30). Timestamps are school-local naked ISO 8601 (no Z, no offset).

List Unapproved Attendance

get_unapprovedread-only
Per-student unapproved attendance lines (outstanding absence / late incidents).
Use when: investigating one student's outstanding attendance issues - 'what does Harry have un-approved?'.
Returns: items[{ id, activityName, start, finish, period, teacherCode, teacherName, location, status, instanceAttendanceMode, absenceType, activityType, studentId, studentForm, studentYearLevelName, studentFirstName, studentLastName, studentName, studentCode, attendanceOverride, pinnedChronicleEntries }], totalReturned, hasMore.
Scope: one student identified by targetUserId. Always renders from a staff perspective on the AI surface so the LLM sees the full record.
Caveats: optional 'filter' is a DataExt blob used to scope a date range; pass empty for 'everything outstanding'. Timestamps are school-local naked ISO 8601 (no Z, no offset).

List Learning Tasks

get_learning_tasksread-only
Per-student learning tasks (assessments, homework, projects) - paginated.
Use when: the user asks 'what's on Alice's plate this week', 'show me her recent assessments', 'is task X due?'.
Returns: items[{ id, wikiNodeId, taskId, name, activityId, subjectId, activityName, subjectName, groupName, createdTimestamp, dueDateTimestamp, hidden, isAggregateTask, studentDueDateTimestamp, submittedTimestamp, submissionStatus, result }], totalReturned, hasMore.
`result` is the headline graded value for the targetUserId (what the staff UI shows in the Result column). For grading-scheme tasks this is the option's display value (e.g. 'N', 'A+'); for free-form / decimal tasks it's the raw stored value. Multi-component / rubric tasks only surface the primary measure here.
Scope: one student identified by targetUserId; optional academicGroupId to scope to one cohort.
Caveats: server-side hard cap of 100 rows per call; for many results page through with start/limit. Heavy collections (component results, submission attachments) and low-signal flags (description, important, parentCode, categoryId, assessmentPeriodId, activityStart, isContributingTask, subjectHeader, studentCount, attachmentCount) are dropped server-side to keep payloads small. Timestamps are school-local naked ISO 8601 (no Z, no offset).

Get Calendar Events

get_calendar_eventsread-only
Combined calendar view for any user: timetabled classes (students), teaching schedule (staff), plus school-wide events.
Use when: the user asks 'what's on this week', 'when does class X meet', 'show me the calendar for staff/student Y'.
Returns: items[{ instanceId, activityId, start, finish, title, location, activityType, activityTypeName, subjectLongName, period }], totalReturned, hasMore.
Scope: a single user identified by targetUserId (numeric organisationUserId), over [startDate, endDate] (max 31 days).
Caveats: input dates must be ISO-8601. Output start / finish are emitted as school-local naked ISO 8601 (no Z, no offset) — treat as already in the school's timezone. Pass `activityId` to get_activity_details for the roster + occurrence schedule of any row.

List Campuses

get_reference_campusesread-only
Lists campuses configured at the active school.
Use when: translating a numeric campusId surfaced on schedule / event endpoints into a human-readable campus name, or answering 'what campuses does the school have?'.
Returns: items[{ campusId, name, importIdentifier, isDefault, archived }], totalReturned, hasMore.
Scope: whole-school catalogue — no per-user filtering.
Caveats: archived campuses are dropped by default; pass includeArchived=true for audit-style queries.

List Academic Groups

get_reference_academic_groupsread-only
Lists academic groups (year-level cohorts, electives, mixed-age streams) at the active school.
Use when: translating an academic-group code on a schedule / timetable response into a human-readable name, or enumerating 'what groups are offered?'.
Returns: items[{ id, code, name, isRelevant }], totalReturned, hasMore.
Scope: whole-school catalogue.
Caveats: legacy / inactive groups are dropped by default; pass includeIrrelevant=true to include them.

List Form Groups

get_reference_form_groupsread-only
Cursor-paginated list of form groups at the active school.
Use when: enumerating form groups (e.g. "7A", "8C") or pivoting from a student's form group code into the canonical record.
Returns: items[{ id, name, code, status, archived, updatedTimestamp, staffCount }], totalReturned, hasMore, nextCursor.
Scope: whole-school catalogue; cursor is opaque — pass back verbatim to continue paging.
Caveats: staff member arrays are dropped to a count; archived groups are excluded by default.

List Year Levels

get_reference_year_levelsread-only
Lists year levels configured at the active school.
Use when: discovering the numeric yearLevelId required by year-level scoped tools (e.g. get_attendance_summary_for_year_level), or translating a yearLevel short name surfaced on student records back to its id.
Returns: items[{ id, shortName, importIdentifier }], totalReturned, hasMore.
Scope: whole-school catalogue — no per-user filtering.
Caveats: by default only year levels that can contain users are returned (mustContainUsers=true); pass mustContainUsers=false for a complete catalogue.

Get School Calendar

get_schedule_calendarread-only
School calendar for a given year — one row per day with teaching/holiday flags.
Use when: answering 'is 2025-04-25 a public holiday?' or 'how many teaching days are in October?'.
Returns: items[{ dayOfWeek, date, isTeachingDay, isPublicHoliday }], totalReturned, hasMore.
Scope: whole-school calendar for the requested year (defaults to the current calendar year). NO date-range filter — the upstream provider is whole-year-only; slice client-side on `date` if you need a window.
Caveats: response is always ~366 rows for the requested year; trimming kicks in only if the school has wildly extended calendars configured.

Get School Terms

get_schedule_termsread-only
Term boundaries (start/end dates) for a given year.
Use when: computing date ranges by term, answering 'when does Term 2 start?', or anchoring other tool calls to term-aligned windows.
Returns: items[{ termName, startDate, endDate }], totalReturned, hasMore.
Scope: whole-school terms for the requested year (defaults to the current calendar year).
Caveats: dates are ISO-8601 strings; the array is small (typically 4 rows).

List Subjects

get_schedule_subjectsread-only
Lists subjects offered for an academic year.
Use when: answering 'what English subjects run in 2026?' or enumerating subjects by faculty.
Returns: items[{ subjectId, shortName, longName, importIdentifier, yearLevelImportIdentifier, academicYear, facultyName, facultyImportIdentifier, activityCodes }], totalReturned, hasMore, nextCursor.
Scope: whole-school subjects for the requested year (defaults to the current year); optional activityTypes int[] filter (1=StandardClass, 2=Event, 9=PD, 14=Club, etc.).
Caveats: faculty manager person ids are dropped — use search / get_user_profile to resolve teachers.

List School Events

get_schedule_eventsread-only
School-wide event listings (excursions, assemblies, sports days etc.) within a date window.
Use when: answering 'what events does the school have next month?', filtering by category, or doing incremental sync (`lastModifiedSince`).
Returns: items[{ activityId, eventId, name, start, finish, attendanceMode, eventStatus, eventOrganiserPersonId, lastModifiedTimestamp, defaultLocation, instanceCount, attendeeCount, facultyCount }], totalReturned, hasMore.
Scope: whole-school events visible to the caller, over [startDate, endDate] (max 92 days). Optional `lastModifiedSince` ISO timestamp returns only events touched after that watermark; optional `categories` array applies server-side filtering.
Caveats: instances / attendees / faculties are collapsed to counts — pass `activityId` to get_activity_details for roster + per-occurrence detail. Timestamps are school-local naked ISO 8601 (no Z, no offset).

Get Activity Details

get_activity_detailsread-only
Roster + occurrence schedule for one activity (event OR class), keyed by integer activityId.
Use when: an LLM has an activityId from a calendar/schedule row and needs to know who is on the activity and when it runs (e.g. 'who's enrolled in 9MAT1A', 'who's coming on the Term 2 excursion', 'when does this class meet?').
Returns: item{ meta{ activityId, activityType, activityTypeName, name, importIdentifier, eventActivityGuid, academicGroupName, defaultLocation, start, finish, organiserPersonId, leadTeacherCode, detailNote }, members[{ personId, importIdentifier, role, enrolmentStart, enrolmentFinish }], occurrences[{ start, finish, location, runningStatus, sessionName, teachers[] }] }.
Scope: one activity (event or class). The AI service hides the upstream split between event-detail and class-detail APIs — same shape either way.
Caveats: activity types without a public detail endpoint (PD, Duty, Meeting, OnCall, etc.) return meta + empty roster + meta.detailNote explaining why. People are returned by personId/importIdentifier only — call search / get_user_profile if you need names. Timestamps (meta.start/finish, occurrence start/finish, enrolment start/finish) are school-local naked ISO 8601 (no Z, no offset).

Troubleshooting

Policies