Metadata-Version: 2.4
Name: arythmatic-lms-mcp
Version: 0.1.0
Summary: Model Context Protocol (MCP) server for the Arythmatic LMS Backend REST API
Keywords: mcp,model-context-protocol,lms,arythmatic,claude,ai-agents
Author: alvinbengeorge
Author-email: alvinbengeorge <alvinallen333@gmail.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Education
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Education
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Dist: httpx>=0.28.1
Requires-Dist: mcp[cli]>=2.0.0
Requires-Dist: starlette>=0.40.0
Requires-Dist: uvicorn>=0.30.0
Requires-Python: >=3.12
Project-URL: Homepage, https://github.com/askmeidentitycorp/arythmatic-lms-backend/tree/main/mcp-arythmatic-backend
Project-URL: Repository, https://github.com/askmeidentitycorp/arythmatic-lms-backend
Project-URL: Issues, https://github.com/askmeidentitycorp/arythmatic-lms-backend/issues
Description-Content-Type: text/markdown

# LMS Backend Model Context Protocol (MCP) Server

A production-ready, stateless, and multi-tenant **Model Context Protocol (MCP) Server** for the Arythmatic LMS Backend Django REST API.

Built with Python 3.12, `uv`, and the official `mcp` SDK v2.0, this server exposes **124 structured tools** across Courses, Modules/Curriculum, Batches, Groups, Enrollments, Certificates, Contents, SCORM, Live Meetings, and Payments/Subscriptions.

---

## 🌟 Key Features & Architecture

* **Token-Only Authorization**: Operates using JWT `access_token` authorization ("token token"), eliminating manual password or credential typing in AI chats.
* **Automatic JWT Claim Decoding**: Decodes tenant domain metadata (`tenant_domain`) directly from the JWT `access_token` payload. No hardcoded tenant parameters required!
* **Stateless & Task-Isolated**: Uses Python `contextvars` (`ContextVar`) for thread-safe, task-safe multi-user execution. When `LMS_ENABLE_FILE_PERSISTENCE=false` is set (default), zero session state persists to disk.
* **Actionable 401/403 Error Responses**: Across **all tools**, unauthenticated or expired requests automatically return `logged_in: false`, the tenant's exact `login_url` (`https://<tenant_domain>`), and step-by-step sign-in instructions.
* **Dedicated Login Helper Tool**: `lms_auth_get_login_url` provides exact web portal URLs and sign-in steps whenever a user or AI asks how or where to log in.
* **Multi-Transport Support**:
  * `stdio`: Standard input/output transport for desktop AI clients (Cursor, Claude Desktop, Antigravity CLI).
  * `sse` / `streamable-http`: Server-Sent Events HTTP transport for hosted cloud microservice deployments.

---

## 📦 Install from PyPI

```bash
pip install arythmatic-lms-mcp
```

Or run it without installing, using [`uv`](https://docs.astral.sh/uv/):

```bash
uvx arythmatic-lms-mcp
```

### Connect it to Claude Desktop / Claude Code / Cursor

Add the server to your MCP configuration file (`claude_desktop_config.json`, `.mcp.json`, or your client's equivalent):

```json
{
  "mcpServers": {
    "arythmatic-lms": {
      "command": "uvx",
      "args": ["arythmatic-lms-mcp"],
      "env": {
        "LMS_API_BASE_URL": "https://api.lms-dev.arythmatic.cloud",
        "LMS_ENABLE_FILE_PERSISTENCE": "false"
      }
    }
  }
}
```

If you installed with `pip` instead, use the console script directly:

```json
{
  "mcpServers": {
    "arythmatic-lms": {
      "command": "arythmatic-lms-mcp",
      "args": ["--transport", "stdio"]
    }
  }
}
```

For Claude Code, the one-liner equivalent is:

```bash
claude mcp add arythmatic-lms -- uvx arythmatic-lms-mcp
```

Once connected, sign in from the chat itself — ask the agent for your login URL
(`lms_auth_get_login_url`), then hand it your JWT access token
(`lms_auth_set_tokens`). No credentials are typed into any config file.

---

## 🚀 Quick Start (Local Docker Setup)

### 1. Build the Docker Image

```bash
cd mcp-arythmatic-backend
docker build -t lms-mcp-server:latest .
```

### 2. Configure `mcp_config.json`

Add the server to your MCP configuration file (e.g., `~/.gemini/config/mcp_config.json`, Cursor, or Claude Desktop):

```json
{
  "mcpServers": {
    "lms-backend": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "LMS_ENABLE_FILE_PERSISTENCE=false",
        "lms-mcp-server:latest"
      ]
    }
  }
}
```

---

## 🌐 Hosting Instructions (Production SSE Deployment)

For multi-user cloud deployments where AI clients connect over HTTP via Server-Sent Events (SSE):

### 1. Run Container in SSE Mode

```bash
docker run -d \
  --name lms-mcp-server \
  --restart unless-stopped \
  -p 8080:8080 \
  -e LMS_API_BASE_URL=https://api.lms-dev.arythmatic.cloud \
  -e LMS_ENABLE_FILE_PERSISTENCE=false \
  lms-mcp-server:latest \
  --transport sse --host 0.0.0.0 --port 8080
```

### 2. Reverse Proxy Configuration (Nginx)

Expose the SSE endpoint over HTTPS (`https://mcp.arythmatic.cloud/sse`):

```nginx
server {
    server_name mcp.arythmatic.cloud;

    location /sse {
        proxy_pass http://127.0.0.1:8080/sse;
        proxy_http_version 1.1;
        proxy_set_header Connection '';
        proxy_set_header Host $host;
        proxy_buffering off;
        proxy_cache off;
        chunked_transfer_encoding off;
    }

    location /messages/ {
        proxy_pass http://127.0.0.1:8080/messages/;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
```

---

## 🔑 Authentication Workflow

1. **Unauthenticated State**: Calling any tool without an active session returns:
   ```json
   {
     "error": true,
     "logged_in": false,
     "token_expired": true,
     "tenant_domain": "<tenant-domain>",
     "login_url": "https://<tenant-domain>",
     "message": "You are currently logged out or unauthenticated for tenant '<tenant-domain>'. Please visit https://<tenant-domain> to sign in and acquire your JWT access_token, then pass it to lms_auth_set_tokens."
   }
   ```
2. **Obtain Token**: The user visits `https://<tenant-domain>` in their browser and copies their JWT `access_token`.
3. **Authenticate Session**: The AI calls `lms_auth_set_tokens(access_token="eyJhbGci...")`.
4. **Auto-Tenant Resolution**: The MCP server decodes the JWT payload, extracts `tenant_domain`, and automatically sets `X-Tenant-Domain` headers for all requests.

---

## 📚 Complete MCP Tools Reference (124 Tools)

### 🔐 1. Auth & Session Management (7 Tools)
* `lms_auth_get_login_url(tenant_domain, base_url)` – Retrieve web login portal URL and sign-in instructions.
* `lms_auth_set_tokens(access_token, refresh_token, tenant_domain, base_url)` – Set access token (auto-decodes tenant domain from JWT claims).
* `lms_auth_get_status()` – Retrieve active session status, base URL, and active tenant domain.
* `lms_auth_validate_token(access_token, tenant_domain)` – Validate access token against backend (`/api/v1/auth/me/`).
* `lms_auth_logout()` – Clear active session authorization tokens.
* `lms_auth_refresh_token(refresh_token, tenant_domain)` – Exchange a refresh token for a fresh access token (returns a preview only, never the full token).
* `lms_get_tool_docs(module, tool_name)` – Fetch documentation/parameter schemas for any registered tool.

### 📚 2. Courses & Learning Paths (27 Tools)
* `lms_list_courses(page, search, category_id, is_active, access_token, tenant_id)` – List tenant courses with filtering and search.
* `lms_get_course(course_id, access_token, tenant_id)` – Retrieve details for a specific course by ID.
* `lms_get_course_by_slug(slug, access_token, tenant_id)` – Retrieve course by unique slug.
* `lms_get_course_curriculum(course_id, access_token, tenant_id)` – Fetch full module/section/lesson curriculum structure.
* `lms_get_course_progress(course_id, access_token, tenant_id)` – Track user progress percentage across course contents.
* `lms_get_my_courses(access_token, tenant_id)` – Get courses user is currently enrolled in or instructing.
* `lms_get_course_statistics(course_id, access_token, tenant_id)` – Retrieve aggregate stats for a course.
* `lms_get_course_enrollments(course_id, access_token, tenant_id)` – Get all student enrollments for a course.
* `lms_get_featured_courses(access_token, tenant_id)` – Get featured courses for tenant.
* `lms_clone_batch_to_self_paced(course_id, batch_id, new_title, ...)` – Clone an instructor-led batch into a self-paced course.
* `lms_create_course(title, description, category_id, ...)` – Create a new course.
* `lms_update_course(course_id, title, description, ...)` – Update an existing course.
* `lms_delete_course(course_id, access_token, tenant_id)` – Delete a course.
* `lms_enroll_course(course_id, access_token, tenant_id)` – Enroll current user in a course.
* `lms_unenroll_course(course_id, access_token, tenant_id)` – Unenroll current user from a course.
* `lms_add_co_instructor(course_id, user_id, access_token, tenant_id)` – Add co-instructor to a course.
* `lms_remove_co_instructor(course_id, user_id, access_token, tenant_id)` – Remove co-instructor from a course.
* `lms_list_categories(root_only, access_token, tenant_id)` – List course categories.
* `lms_get_category_tree(access_token, tenant_id)` – Retrieve nested category hierarchy tree structure.
* `lms_create_category(name, parent_id, ...)` – Create a new category.
* `lms_update_category(category_id, name, ...)` – Update an existing category.
* `lms_delete_category(category_id, access_token, tenant_id)` – Delete a category.
* `lms_list_learning_paths(page, search, access_token, tenant_id)` – Browse multi-course learning paths.
* `lms_get_learning_path(lp_id, access_token, tenant_id)` – Retrieve details for a specific learning path.
* `lms_create_learning_path(title, description, ...)` – Create a new learning path.
* `lms_update_learning_path(lp_id, title, ...)` – Update a learning path.
* `lms_delete_learning_path(lp_id, access_token, tenant_id)` – Delete a learning path.

### 👥 3. Batches & Cohorts (14 Tools)
* `lms_list_batches(page, course_id, access_token, tenant_id)` – List active, completed, or hidden student cohorts/batches.
* `lms_get_batch(batch_id, access_token, tenant_id)` – Retrieve details for a specific batch ID.
* `lms_get_my_batches(access_token, tenant_id)` – Get user's active batch memberships.
* `lms_create_batch(name, course_id, start_date, ...)` – Create a new batch.
* `lms_update_batch(batch_id, name, ...)` – Update an existing batch.
* `lms_delete_batch(batch_id, access_token, tenant_id)` – Delete a batch.
* `lms_start_batch(batch_id, access_token, tenant_id)` – Start a batch.
* `lms_complete_batch(batch_id, access_token, tenant_id)` – Mark batch as complete.
* `lms_cancel_batch(batch_id, access_token, tenant_id)` – Cancel a batch.
* `lms_regenerate_batch_course(batch_id, access_token, tenant_id)` – Regenerate course structure for a batch.
* `lms_get_batch_enrollments(batch_id, page, access_token, tenant_id)` – List students enrolled in a specific batch.
* `lms_list_course_batches(course_id, access_token, tenant_id)` – List cohorts tied to a specific course.
* `lms_list_lp_batches(lp_id, access_token, tenant_id)` – List cohorts tied to a learning path.
* `lms_get_lp_batch_progress(batch_id, access_token, tenant_id)` – Track cohort completion percentage across a learning path.

### 🏢 4. Groups & Learner Analytics (16 Tools)
* `lms_list_groups(page, search, access_token, tenant_id)` – List tenant organizational groups.
* `lms_get_group(group_id, access_token, tenant_id)` – Retrieve details for a specific group ID.
* `lms_get_my_groups(access_token, tenant_id)` – Get user's active group memberships.
* `lms_get_group_my_courses(access_token, tenant_id)` – Get courses accessible via group assignments.
* `lms_list_group_courses(group_id, access_token, tenant_id)` – List courses assigned to a specific group.
* `lms_list_group_admins(group_id, access_token, tenant_id)` – List administrators of a specific group.
* `lms_get_group_statistics(access_token, tenant_id)` – Get overall group progress statistics.
* `lms_get_group_learner_analytics(group_id, page, search, access_token, tenant_id)` – Get paginated per-learner progress tables.
* `lms_create_group(name, description, ...)` – Create a new group.
* `lms_update_group(group_id, name, ...)` – Update an existing group.
* `lms_delete_group(group_id, access_token, tenant_id)` – Delete a group.
* `lms_add_group_member(group_id, user_id, ...)` – Add a user to a group.
* `lms_bulk_add_group_members(group_id, user_ids, ...)` – Bulk add users to a group.
* `lms_remove_group_member(group_id, user_id, ...)` – Remove a user from a group.
* `lms_assign_course_to_group(group_id, course_id, ...)` – Assign a course to a group.
* `lms_remove_course_from_group(group_id, course_id, ...)` – Remove a course from a group.

### 🎓 5. Admin Enrollments (10 Tools)
* `lms_list_admin_enrollments(page, course_id, batch_id, user_id, status, access_token, tenant_id)` – Query admin enrollments catalog with filters.
* `lms_get_enrollment_detail(enrollment_id, access_token, tenant_id)` – Retrieve details for a specific enrollment record.
* `lms_list_course_learners(course_id, access_token, tenant_id)` – List enrolled learners in a specific course.
* `lms_get_course_enrollment_stats(course_id, access_token, tenant_id)` – Retrieve enrollment statistics for a course.
* `lms_list_batch_learners(batch_id, access_token, tenant_id)` – List enrolled learners in a specific batch.
* `lms_get_global_enrollment_stats(access_token, tenant_id)` – Retrieve global tenant-wide enrollment statistics.
* `lms_admin_enroll_user(user_id, course_id, batch_id, ...)` – Admin enroll a user into a course or batch.
* `lms_admin_bulk_enroll(user_ids, course_id, batch_id, ...)` – Admin bulk enroll multiple users.
* `lms_admin_remove_user(enrollment_id, access_token, tenant_id)` – Admin remove user enrollment.
* `lms_admin_update_enrollment_status(enrollment_id, status, ...)` – Update enrollment status.

### 📜 6. Credentials & Certificates (20 Tools)
* `lms_list_my_credentials(access_token, tenant_id)` – View learner's earned certificates.
* `lms_verify_credential(credential_id)` – Public certificate verification endpoint.
* `lms_list_admin_issued_credentials(page, access_token, tenant_id)` – Admin oversight of all issued certificates.
* `lms_get_issued_credential_detail(credential_id, access_token, tenant_id)` – Retrieve details for an issued certificate.
* `lms_list_credential_templates(access_token, tenant_id)` – View active certificate template designs.
* `lms_get_credential_builder_fields(access_token, tenant_id)` – View dynamic field palette for certificate builder.
* `lms_get_issuer_profile(access_token, tenant_id)` – Get organization issuer profile.
* `lms_update_issuer_profile(org_name, logo, ...)` – Update issuer profile for certificate branding.
* `lms_issue_credential(user_id, course_id, ...)` – Manually issue certificate to a user.
* `lms_batch_issue_credentials(course_id, batch_id, ...)` – Bulk issue certificates to entire batch.
* `lms_re_render_pending_credentials(...)` – Bulk re-enqueue stuck certificate renders.
* `lms_issue_assessment_certificate(assessment_id, attempt_id, ...)` – Issue certificate for assessment attempt.
* `lms_revoke_assessment_certificate(assessment_id, attempt_id, ...)` – Revoke assessment attempt certificate.
* `lms_create_credential_template(title, description, ...)` – Create a certificate template.
* `lms_update_credential_template(template_id, title, ...)` – Update a certificate template.
* `lms_delete_credential_template(template_id, access_token, tenant_id)` – Delete a certificate template.
* `lms_publish_credential_template(template_id, access_token, tenant_id)` – Publish a certificate template.
* `lms_set_default_credential_template(template_id, access_token, tenant_id)` – Set default certificate template.
* `lms_revoke_credential(credential_id, reason, ...)` – Revoke an issued certificate.
* `lms_re_render_credential(credential_id, access_token, tenant_id)` – Re-render an issued certificate PDF/image.

### 📖 7. Content, Quizzes, SCORM & Meetings (20 Tools)
* `lms_list_course_sections(course_id, access_token, tenant_id)` – List sections for a course.
* `lms_create_course_section(course_id, title, ...)` – Create a course section.
* `lms_update_course_section(section_id, title, ...)` – Update a course section.
* `lms_delete_course_section(section_id, access_token, tenant_id)` – Delete a course section.
* `lms_get_course_content_detail(content_id, access_token, tenant_id)` – Inspect individual content item details.
* `lms_create_course_content(section_id, title, content_type, ...)` – Create course content item.
* `lms_create_live_meeting(section_id, title, start_time, ...)` – Create live meeting content.
* `lms_update_course_content(content_id, title, ...)` – Update course content item.
* `lms_delete_course_content(content_id, access_token, tenant_id)` – Delete course content item.
* `lms_get_content_player_data(content_id, access_token, tenant_id)` – Get player data with progress tracking.
* `lms_get_content_video_stream(content_id, access_token, tenant_id)` – Retrieve direct-upload video streaming URLs.
* `lms_mark_content_complete(content_id, access_token, tenant_id)` – Mark content as completed.
* `lms_update_content_progress(content_id, progress_percentage, ...)` – Update content completion progress.
* `lms_list_course_quizzes(course_id, access_token, tenant_id)` – List course quizzes with aggregate statistics.
* `lms_get_quiz_attempts(content_id, access_token, tenant_id)` – Get user's quiz attempt score history.
* `lms_submit_quiz(content_id, answers, ...)` – Submit answers for a quiz attempt.
* `lms_get_meeting_details(content_id, access_token, tenant_id)` – Retrieve detailed live meeting info with join links, passcodes, and platform details.
* `lms_get_upcoming_meetings(access_token, tenant_id)` – Get all upcoming live meetings across enrolled courses.
* `lms_list_scorm_packages(access_token, tenant_id)` – List tenant's uploaded SCORM packages.
* `lms_get_scorm_launch_config(content_id, access_token, tenant_id)` – Get SCORM package launch configuration.

### 💳 8. Payments, Pricing & Subscriptions (8 Tools)
* `lms_get_my_payment_history(page, access_token, tenant_id)` – Get user's payment transaction history.
* `lms_get_my_payment_summary(access_token, tenant_id)` – Get spending summary & financial metrics.
* `lms_get_transaction_receipt(transaction_id, access_token, tenant_id)` – Get receipt data for a transaction ID.
* `lms_get_course_prices(course_id, access_token, tenant_id)` – Get pricing configured for courses.
* `lms_get_learning_path_prices(lp_id, access_token, tenant_id)` – Get pricing configured for learning paths.
* `lms_list_membership_plans(access_token, tenant_id)` – Get available published membership plans.
* `lms_get_my_memberships(access_token, tenant_id)` – Get learner's active membership subscriptions.
* `lms_get_payment_status(payment_intent_id, access_token, tenant_id)` – Check status of a payment intent by ID.

> Platform-wide super-dashboard endpoints (cross-tenant subscriptions/revenue) are intentionally not exposed by this tenant-scoped server.

### 🏢 9. Tenant Management (2 Tools)
* `lms_get_current_tenant(tenant_domain)` – Retrieve details and configuration for the active tenant.
* `lms_update_current_tenant(name, primary_color, secondary_color, logo_url, timezone_setting, language, tenant_domain)` – Update tenant branding and settings (Admin).

---

## 🛠️ Development & Environment Variables

| Variable | Description | Default |
|---|---|---|
| `LMS_API_BASE_URL` | Base URL of the LMS REST API Gateway | `https://api.lms-dev.arythmatic.cloud` |
| `LMS_ENABLE_FILE_PERSISTENCE` | Enable/disable token persistence to `config.json` | `false` |
| `LMS_TENANT_DOMAIN` | Fallback tenant domain override | `""` |
| `LMS_CONFIG_PATH` | Custom path for `config.json` | `/app/config.json` |

