Frappe LMS MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| FRAPPE_URL | No | Frappe base URL | http://localhost:8000 |
| FRAPPE_SITE | No | Frappe site name | lms.localhost |
| FRAPPE_API_KEY | No | API key for token auth | |
| FRAPPE_PASSWORD | No | Login password | |
| FRAPPE_USERNAME | No | Login username/email | |
| FRAPPE_API_SECRET | No | API secret for token auth | |
| FRAPPE_LMS_DB_PATH | No | SQLite database file path | data/frappe_lms.db |
| FRAPPE_LMS_NO_DASHBOARD | No | Set to '1' to disable the web dashboard | |
| FRAPPE_LMS_DASHBOARD_PORT | No | Port for the web dashboard | 8080 |
| FRAPPE_LMS_SESSION_SECRET | No | Secret key for dashboard session cookies |
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 |
|---|---|
| list_coursesB | List LMS courses. Set published_only=True to see only published courses. |
| get_courseA | Get full details of a course including its chapter/lesson outline. Args: course: The course name (slug) or title. |
| create_courseB | Create a new LMS Course. A URL slug is auto-generated from the title. Args: title: Course title (required). short_introduction: One-line summary shown on course cards (required). description: Full HTML description. instructor: Email/User ID of the instructor. tags: Comma-separated tags, e.g. "Python, Web, Beginner". category: Category name (must exist in LMS Category doctype). image: Path to preview image. video_link: YouTube video ID or embed URL. published: Publish immediately. featured: Mark as featured. upcoming: Mark as upcoming. card_gradient: Card colour (Red/Blue/Green/Amber/Cyan/Orange/Pink/Purple/Teal/Violet/Yellow/Gray). disable_self_learning: Students can only learn via batches. paid_course: Whether this is a paid course. course_price: Price (required if paid_course). currency: Currency code (required if paid_course), e.g. "USD" or "IDR". enable_certification: Enable completion certificate. paid_certificate: Certificate requires payment. |
| update_courseA | Update fields on an existing course. Args: course: The course name (slug). fields: JSON string of fields to update, e.g. '{"title":"New Title","published":true}'. |
| delete_courseA | Delete a course and all its chapters, lessons, and enrollments. Args: course: The course name (slug). |
| publish_courseA | Toggle the published status of a course. Args: course: The course name (slug). published: True to publish, False to unpublish. |
| create_chapterA | Create a chapter in a course. Args: course: The course name (slug). title: Chapter title. |
| get_chapterB | Get a chapter with its lessons. Args: chapter: The chapter name. |
| update_chapterA | Update a chapter title. Args: chapter: The chapter name. title: New chapter title. |
| delete_chapterB | Delete a chapter and all its lessons. Args: chapter: The chapter name. |
| reorder_chapterA | Move a chapter to a new position in the course outline. Args: course: The course name (slug). chapter: The chapter name. idx: New 0-based position. |
| create_lessonA | Create a lesson in a chapter. Args: chapter: The chapter name. title: Lesson title. content: EditorJS JSON string for the lesson body. Use build_lesson_content to construct it. |
| get_lessonC | Get a lesson with its content and metadata. Args: lesson: The lesson name. |
| update_lessonA | Update a lesson's fields. Pass empty strings for fields you don't want to change. Args: lesson: The lesson name. title: New lesson title (empty = no change). content: EditorJS JSON string (empty = no change). youtube: YouTube video URL (empty = no change). include_in_preview: Whether this lesson is visible in the course preview. instructor_notes: Markdown instructor notes (empty = no change). |
| delete_lessonC | Delete a lesson and remove it from the chapter. Args: lesson: The lesson name. chapter: The chapter name. |
| move_lessonA | Move a lesson to a different chapter or reorder within the same chapter. Args: lesson: The lesson name. source_chapter: Current chapter. target_chapter: Destination chapter (same as source to reorder). idx: New 0-based position. |
| build_lesson_contentA | Build an EditorJS JSON content string for a lesson from a spec. Args: content_spec: JSON string with optional keys: paragraphs, headers, lists, images, code, embeds, quiz_refs, markdown. Example: '{"paragraphs":["Hello world"],"headers":[{"text":"Intro","level":2}]}' Returns: EditorJS JSON string ready for the content field of a Course Lesson. |
| add_paragraph_to_contentA | Append a paragraph to an existing EditorJS content string. Args: existing_content: Current EditorJS JSON string (can be empty). text: Paragraph text to append. Returns: Updated EditorJS JSON string. |
| create_questionA | Create a reusable LMS Question. Args: question: The question text (HTML allowed). question_type: "Choices", "User Input", or "Open Ended". options: JSON list for Choices type: [{"text":"Yes","correct":false,"explanation":"..."},...]. possibilities: JSON list of strings for User Input type: ["answer1","answer2"]. |
| create_quizA | Create an LMS Quiz with optional questions. Args: title: Quiz title (slug auto-generated). passing_percentage: Minimum percentage to pass (0-100). questions: JSON list of [{"question":"","marks":5}]. max_attempts: Max attempts (0 = unlimited). show_answers: Show correct answers after submission. duration: Time limit in minutes (as string). shuffle_questions: Randomise question order. enable_negative_marking: Deduct marks for wrong answers. marks_to_cut: Marks to deduct per wrong answer. |
| add_question_to_quizB | Add an existing question to a quiz. Args: quiz: The quiz name (slug). question: The LMS Question name. marks: Marks for this question. |
| get_quizA | Get a quiz, optionally with full question details. Args: quiz: The quiz name (slug). with_questions: If True, fetch full question text and options. |
| list_quizzesC | List all quizzes. |
| delete_quizB | Delete a quiz. Args: quiz: The quiz name (slug). |
| embed_quiz_in_lessonB | Embed a quiz into a lesson's content as an EditorJS quiz block. Args: lesson: The lesson name. quiz: The quiz name (slug). |
| enroll_studentA | Enroll a student in a course. Args: course: The course name (slug). student: The User email/ID of the student. member_type: "Student", "Mentor", or "Staff". |
| list_enrollmentsA | List enrollments, optionally filtered by course or student. Args: course: Filter by course name (empty = all). student: Filter by student User email/ID (empty = all). limit: Maximum results. |
| unenroll_studentB | Remove a student's enrollment. Args: enrollment: The enrollment name. |
| create_batchA | Create an LMS Batch (cohort). Args: title: Batch title. start_date: Start date (YYYY-MM-DD). end_date: End date (YYYY-MM-DD). start_time: Start time (HH:MM:SS). end_time: End time (HH:MM:SS). timezone: Timezone, e.g. "Asia/Jakarta". description: Short description. batch_details: Full HTML details. instructor: Instructor User email/ID. courses: JSON list of course names to include, e.g. '["course-1","course-2"]'. published: Whether the batch is published. allow_self_enrollment: Allow students to self-enroll. seat_count: Number of seats (0 = unlimited). medium: "Online" or "Offline". paid_batch: Whether this is a paid batch. amount: Price amount (required if paid_batch). currency: Currency code (required if paid_batch). category: Category name. |
| list_batchesC | List LMS batches. |
| issue_certificateA | Manually issue a certificate to a member for a course. Args: course: The course name (slug). member: The User email/ID. template: The Print Format name for the certificate template. issue_date: Issue date (YYYY-MM-DD). Empty = today. expiry_date: Expiry date (YYYY-MM-DD). Empty = no expiry. |
| create_full_courseA | Create a complete course with chapters, lessons, and quizzes from a single JSON spec. This is the primary tool for building comprehensive courses in one call. Args: spec: JSON string with the full course definition. Structure: { "title": "...", "short_introduction": "...", "description": "...", "instructor": "email", "tags": "a,b", "category": "...", "published": false, "chapters": [ { "title": "Chapter 1", "lessons": [ { "title": "Lesson 1", "content": { "paragraphs": ["text..."], "headers": [{"text": "Section", "level": 2}], "lists": [{"items": ["a","b"], "ordered": false}], "code": [{"code": "print(1)", "language": "python"}], "embeds": [{"service": "youtube", "source": "url"}] } }, { "title": "Quiz Lesson", "content": {"paragraphs": ["Test your knowledge"]}, "quiz": { "title": "Quiz 1", "passing_percentage": 70, "questions": [ {"question": "text", "type": "Choices", "options": [{"text":"Yes","correct":false},{"text":"No","correct":true}]} ] } } ] } ] } Returns: JSON with course name, chapter names, lesson names, and quiz names. |
| list_connectionsA | List all saved Frappe LMS connections from the local database. The active connection is shown first. API secrets are masked. Use this to see which Frappe instances are configured and which is active. |
| switch_connectionA | Switch the active Frappe LMS connection by name. After switching, all subsequent MCP tool calls use the new connection's credentials. Args: name: The connection name (label) to activate. |
| list_cached_coursesA | List courses cached in the local SQLite database. These are courses previously created or imported. Use this to find a course by ID for re-upload without querying Frappe. Args: connection_name: Filter by connection name. Empty = all connections. |
| get_cached_courseA | Get full details of a cached course, including its JSON spec. The spec_json field contains the full create_full_course spec that can be re-uploaded to any Frappe instance. Args: course_id: The cache ID (from list_cached_courses). |
| reupload_courseA | Re-upload a cached course to a Frappe LMS instance. Uses the stored JSON spec to recreate the course on the specified (or active) connection. Useful for migrating courses between Frappe instances. Args: course_id: The cache ID of the course to re-upload. connection_name: Target connection name. Empty = active connection. |
| import_course_from_frappeA | Import a course from the active Frappe connection into the local cache. Fetches the course outline and stores its metadata in SQLite for quick lookup. Args: course_slug: The Frappe course name (slug). |
| list_operation_logsA | List recent operations from the audit log (most recent first). Shows create, delete, reupload, and import operations across all connections. Args: limit: Maximum number of entries to return. |
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/anggun-indra/frape-lms-mcp-tools'
If you have feedback or need assistance with the MCP directory API, please join our Discord server