ed-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| get_userA | Get the authenticated user's profile (name, role). Call list_courses instead to see enrolled courses. |
| list_coursesA | List courses the user is enrolled in. Call this first to find a course_id before using other tools. Returns id, code, name, year, session, and status. Args: status: Filter by status — "active", "archived", or "inactive". Omit for all. year: Filter by year (e.g. "2025"). Omit for all years. code: Filter by course code substring, case-insensitive (e.g. "ENVX"). Omit for all codes. |
| get_course_statsA | Get a quick course overview for daily review. Returns enrollment count, number of unanswered questions, number of unresolved threads, number of threads with new follow-up replies, and top categories by volume. Args: course_id: The course ID (use list_courses to find it). |
| list_categoriesA | List the available thread categories and subcategories in a course. Use this to find valid category names before creating or recategorising threads. Args: course_id: The course ID (use list_courses to find it). |
| list_threadsA | FALLBACK browse tool. PREFER Args: course_id: The course ID (use list_courses to find it). limit: Max threads to return (default 50, max 100). offset: Pagination offset (use with limit to page through results). sort: Sort order — "new" for most recent, "top" for most voted, or "trending" for currently active. filter: Narrow results. Triage filters: "unanswered", "unresolved", "new_replies". Personal filters: "unread", "starred", "watching", "mine", "following". Visibility filters: "private", "public", "staff", "endorsed". Invalid values silently return empty results. category: Filter by category name (case-insensitive). Only returns threads in this category. |
| get_threadA | Read a thread's full content, comments, and answers. Use this when you have a thread ID (a large number like 2785693) from list_threads or search_threads results. For looking up a thread by its UI number (e.g. #42), use get_course_thread instead. Args: thread_id: The global thread ID (a large number from list_threads or search_threads, not the #number shown in the UI). |
| get_course_threadA | Read a thread by its number as shown in the Ed UI (e.g. #42, #220). Use this when someone refers to a thread by number. Returns full content, comments, and answers. Args: course_id: The course ID (use list_courses to find it). thread_number: The thread number as shown in the UI (e.g. 42 for thread #42). |
| get_thread_by_urlA | Read a thread by pasting its Ed Discussion URL. Use this when someone shares a link to a thread. Returns full content, comments, and answers. Args: url: Full Ed Discussion thread URL (e.g. https://edstem.org/au/courses/20849/discussion/2785693). |
| accept_answerA | Mark a comment as the accepted answer on a question thread. Use get_thread first to find the comment_id of the correct answer. Args: thread_id: The global thread ID (from list_threads or search_threads). comment_id: The ID of the comment to accept (from get_thread results). |
| mark_duplicateA | Mark a thread as a duplicate of another thread. Use this when a question has already been answered elsewhere to point students to the original. Args: thread_id: The global ID of the duplicate thread (from list_threads or search_threads). original_thread_id: The global ID of the original thread it duplicates. |
| unmark_duplicateA | Remove the duplicate mark from a thread, restoring it as a standalone thread. Args: thread_id: The global ID of the thread to unmark (from list_threads or search_threads). |
| search_threadsA | FALLBACK keyword search via the Ed API. PREFER Args: course_id: The course ID (use list_courses to find it). query: Search keywords (e.g. "peer review", "exam", "deadline"). limit: Max results (default 20). type: Filter by thread type — "question", "post", or "announcement". Omit for all types. exclude_pinned: If true, exclude pinned threads from results (useful to skip announcements). Default false. |
| create_threadA | Create a new thread in a course. Wrap content in Ed XML: Your text here. Use list_categories to find valid category names. Args: course_id: The course ID (use list_courses to find it). title: Thread title. content: Thread body in Ed XML format. type: "post" for a discussion, "question" for a question that can be answered, or "announcement" for a course-wide notice. category: Category name (use list_categories to see options). subcategory: Subcategory name (optional). is_private: If true, only staff can see the thread. is_anonymous: If true, the author's name is hidden. |
| edit_threadA | Edit an existing thread's title, content, or category. Only provided fields are updated; omitted fields are left unchanged. Args: thread_id: The global thread ID (from list_threads or search_threads). title: New title (omit to keep current). content: New body in Ed XML format (omit to keep current). category: New category name (omit to keep current; use list_categories for valid names). subcategory: New subcategory name (omit to keep current). |
| bulk_recategoriseA | Move multiple threads to a new category at once. Use search_threads or list_threads to find thread IDs, and list_categories for valid category names. Set dry_run=true to preview changes without applying them. Args: thread_ids: List of global thread IDs to move. category: Target category name (use list_categories to see options). subcategory: Target subcategory name (optional). dry_run: If true, show what would change without applying. Default false. |
| delete_threadA | Permanently delete a thread and all its comments. This cannot be undone. Args: thread_id: The global thread ID (from list_threads or search_threads). |
| lock_threadA | Lock a thread to prevent new comments. Useful after a question is resolved or a discussion is concluded. Args: thread_id: The global thread ID (from list_threads or search_threads). |
| unlock_threadA | Unlock a thread to allow new comments again. Args: thread_id: The global thread ID (from list_threads or search_threads). |
| pin_threadA | Pin a thread so it stays at the top of the course feed. Good for important announcements or FAQs. Args: thread_id: The global thread ID (from list_threads or search_threads). |
| unpin_threadA | Unpin a thread from the top of the course feed. Args: thread_id: The global thread ID (from list_threads or search_threads). |
| endorse_threadA | Endorse a thread with an instructor badge to signal it contains good content or a correct answer. Args: thread_id: The global thread ID (from list_threads or search_threads). |
| unendorse_threadA | Remove the instructor endorsement badge from a thread. Args: thread_id: The global thread ID (from list_threads or search_threads). |
| get_enrollment_countsA | Get a quick headcount for a course. Returns student count and total enrolled. Use this to answer "how many students" questions without loading the full user list. For per-role breakdowns (staff, admin), use list_users with a role filter. Args: course_id: The course ID (use list_courses to find it). |
| list_usersA | List enrolled users in a course. Use get_enrollment_counts for a quick headcount. Use this when you need names or user IDs (e.g. before calling get_user_activity). Args: course_id: The course ID (use list_courses to find it). role: Filter by role — "student", "staff", or "admin". Omit for all roles. limit: Max users to return (default 50). offset: Pagination offset (use with limit to page through results). |
| get_user_activityA | See what a specific user has been posting and commenting in a course. Use list_users first to find the user_id. Args: user_id: The user ID (use list_users to find it). course_id: The course ID (use list_courses to find it). limit: Max entries to return (default 30). offset: Pagination offset (use with limit to page through results). filter: Narrow results — "thread" for threads only, "answer" for answers only, "comment" for comments only, or "all" for everything (default). |
| upload_fileA | Upload a file from your computer to Ed Discussion and get a URL you can use in thread content or comments. Args: file_path: Absolute path to the file on your computer. |
| upload_file_urlA | Upload a file from a URL directly to Ed Discussion without downloading it locally first. Returns the Ed CDN URL you can use in thread content or comments. Args: url: Public URL of the file to upload (e.g. an image or document URL from the web). |
| download_fileA | Download a file from an Ed Discussion CDN URL to a temporary local path. Returns the local file path so you can read or view it. Args: url: The Ed CDN URL (e.g. https://static.au.edusercontent.com/files/...). |
| download_thread_filesA | Download all images and file attachments from a thread's content, answers, and comments to temporary local files. Returns local file paths so you can read or view them. Args: thread_id: The global thread ID (from list_threads or search_threads results). |
| reply_to_threadA | Reply to a thread with a comment or answer. Wrap content in Ed XML: Your text here Args: thread_id: The global thread ID (from list_threads or search_threads). content: Reply body in Ed XML format. type: "comment" for a general reply, or "answer" for a direct answer (only works on "question" type threads). is_private: If true, only staff can see this reply. is_anonymous: If true, the author's name is hidden. parent_id: To nest this reply under an existing comment, pass that comment's ID here. |
| edit_commentA | Edit an existing comment's content. Replaces the entire body with the new content in Ed XML format. Args: comment_id: The comment ID (from get_thread results). content: New body in Ed XML format. |
| delete_commentA | Permanently delete a comment. This cannot be undone. Args: comment_id: The comment ID (from get_thread results). |
| list_attendance_sessionsA | List attendance sessions in a course. Returns compact summaries. Use get_attendance_session to see full details. Args: course_id: The course ID (use list_courses to find it). |
| get_attendance_sessionA | Get full details of an attendance session, including its check-ins. Args: event_id: The session ID (from list_attendance_sessions results). |
| create_attendance_sessionA | Create a new attendance session in a course. Args: course_id: The course ID (use list_courses to find it). title: Session title (e.g. "Week 3 Tutorial"). start: Optional start time in ISO 8601 format (e.g. "2026-03-01T09:00:00+11:00"). Defaults to now. is_hidden: If true, the session is hidden from students. |
| update_attendance_sessionA | Update an attendance session. Use this to close/reopen, hide/unhide, or rename a session. Args: event_id: The session ID (from list_attendance_sessions results). title: New title (omit to keep current). is_closed: Set true to close the session, false to reopen. is_hidden: Set true to hide from students, false to show. |
| delete_attendance_sessionA | Permanently delete an attendance session and all its check-ins. This cannot be undone. Args: event_id: The session ID (from list_attendance_sessions results). |
| list_check_insA | List attendance check-ins. Provide either course_id for all check-ins across sessions, or event_id for a single session. Args: course_id: The course ID — returns check-ins across all sessions. event_id: A specific session ID — returns only that session's check-ins. |
| manual_check_inA | Manually mark students' attendance for a session. Use list_users to find user IDs. Args: event_id: The session ID (from list_attendance_sessions results). user_ids: List of user IDs to check in. kind: Attendance status — "present", "late", "excused", or "absent". |
| undo_check_inA | Remove check-in records for specific users in a session. This undoes both manual and self check-ins. Args: event_id: The session ID. user_ids: List of user IDs whose check-ins to remove. |
| get_attendance_analyticsA | Get a combined attendance report for a course — all sessions with all check-ins. Useful for generating attendance summaries. Args: course_id: The course ID (use list_courses to find it). |
| sync_indexA | Force-refresh the local search index for a course. You usually do NOT need to call this — Args: course_id: The course ID (use list_courses to find it). |
| search_indexA | DEFAULT thread search/browse tool. Searches the local BM25-ranked index over all threads in a course. Returns ranked results with full content for top hits. Auto-syncs when the index is missing or stale (>30 min) — you do NOT need to call Args: course_id: The course ID (use list_courses to find it). query: Search query. Supports phrases ("peer review"), prefix (assign*), boolean (AND/OR/NOT), and column-specific (title:exam, staff_replies:deadline). Implicit AND between terms. limit: Max results (default 20). category: Filter by category name (e.g. "Assignments"). type: Filter by thread type — "question", "post", or "announcement". has_staff_reply: If true, only threads with staff/admin replies. is_answered: If true, only answered threads. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/januarharianto/ed-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server