ohneben's Model Context Protocol server for the LearnWorlds API — all 94 endpoints as safety-categorized MCP tools (read-only / write / destructive). Runs over stdio or Streamable HTTP, with Docker, retries, and rate limiting.
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
git clone https://github.com/ohneben/Learnworlds-MCP{
"mcpServers": {
"learnworlds-mcp": {
"command": "node",
"args": ["/path/to/Learnworlds-MCP/dist/index.js"]
}
}
}MCP Servers overview
# ohneben's LearnWorlds MCP
[](https://buymeacoffee.com/ohneben)
---
#### License & checks
[](https://github.com/ohneben/Learnworlds-MCP/actions/workflows/ci.yml)
[](./LICENSE.md)
#### MCP registries
[](https://registry.modelcontextprotocol.io/v0.1/servers/io.github.ohneben%2Flearnworlds-mcp/versions/latest)
[](https://mcpservers.org/servers/ohneben/learnworlds-mcp)
[](https://glama.ai/mcp/servers/ohneben/Learnworlds-MCP)
Run your [LearnWorlds](https://www.learnworlds.com/) school in plain language from AI
assistants like **Claude**, **Cursor**, and any other
[MCP](https://modelcontextprotocol.io) client.
This [Model Context Protocol](https://modelcontextprotocol.io) server exposes the
**LearnWorlds public API** — all **94 endpoints**, generated straight from the
OpenAPI spec into MCP tools. Every tool is **safety-categorized**
(🟢 read-only / 🟡 write / 🔴 destructive) so your assistant knows what an action does
*before* it calls it. It runs over **stdio** (Claude Desktop and other local launchers)
or **Streamable HTTP** (hosted in Docker), and ships with retries, client-side rate
limiting, and request timeouts so it holds up against a live school.
## Why you'll want this
Some MCP servers just forward an API. This one is built to be **safe to hand to an
LLM** and **easy to run for real**:
| What you get | Why it matters |
| --- | --- |
| **All 94 endpoints, spec-driven** | Full coverage of courses, users, enrollments, payments, subscriptions, coupons, certificates, seats, community and reporting — nothing hand-picked or left behind. |
| **Every tool is safety-categorized** 🟢 / 🟡 / 🔴 | A banner at the top of each tool description tells the model exactly what it does — read, create, update or delete — before it acts. |
| **Descriptions written for agents, not humans** | Every tool spells out its side effects, auth and rate-limit behavior, return shape, error codes, when *not* to reach for it, and which sibling tools are the alternatives. |
| **Machine-readable MCP annotations** (`readOnlyHint`, `destructiveHint`) | Hosts that honor annotations (Claude included) can auto-trust reads and demand confirmation before anything destructive. |
| **Automatic retries with backoff** | Transient `429` / `5xx` responses are retried with jittered exponential backoff, honoring the server's `Retry-After` header. |
| **Built-in rate limiting** | Self-throttles under LearnWorlds' **30 requests / 10 s** cap so a burst of tool calls never trips a `429`. |
| **Per-request timeouts** | A hung upstream call is aborted and retried instead of freezing the server. |
| **Two transports: stdio *and* Streamable HTTP** | Use it locally in Claude Desktop, or run one always-on server that any number of MCP clients reach over HTTP. |
| **Docker + docker-compose, health check, auto-restart** | Production-style deployment out of the box: `docker compose up` and it stays up. |
| **Bearer-token auth** on the HTTP endpoint | Required as soon as the server is bound beyond loopback: without `MCP_AUTH_TOKEN` it refuses to start rather than exposing the API unprotected. |
| **Your secrets never reach the model** | Credentials live in the server's environment and are injected on every request — the assistant only ever sees tool inputs and API responses. |
| **Drop-in spec updates** | LearnWorlds ships a newer YAML? Replace one file and rebuild — new endpoints become new tools automatically, no code changes. |
### How it compares
At the time of writing this appears to be the only dedicated LearnWorlds MCP server.
You *could* instead point a generic OpenAPI→MCP wrapper at the spec — here's what
that leaves on the table:
| Capability | **This project** | Generic OpenAPI→MCP wrapper\* |
| --- | :---: | :---: |
| All 94 LearnWorlds endpoints as tools | ✅ | ✅ |
| Per-tool 🟢 / 🟡 / 🔴 safety category + banner | ✅ | ❌ |
| `readOnlyHint` / `destructiveHint` MCP annotations | ✅ | ➖ |
| `$ref` dereferencing + recursion-safe schemas | ✅ | ➖ |
| Automatic retries on `429` / `5xx` (honors `Retry-After`) | ✅ | ❌ |
| Client-side rate limiting (stays under 30 req / 10 s) | ✅ | ❌ |
| Per-request timeout with abort | ✅ | ➖ |
| `stdio` transport | ✅ | ✅ |
| **Streamable-HTTP transport** | ✅ | ➖ |
| **Docker + docker-compose**, health check, auto-restart | ✅ | ❌ |
| **Enforced bearer-token auth** on the endpoint | ✅ | ❌ |
| Credentials injected server-side, never sent to the model | ✅ | ➖ |
| License | MIT | varies |
<sub>\*Generic OpenAPI→MCP wrappers turn any Swagger/OpenAPI spec into MCP tools. They
can reach the same endpoints, but treat every operation identically — no safety
categories, no resilience, no deployment story, and no guardrails tuned for live
school data. "➖" = varies by tool / not guaranteed. Snapshot from July 2026.</sub>
## What you can do
Once it's connected, ask your assistant things like:
- "List the 10 most recent users who signed up this month."
- "Create a user for jane@example.com and enroll her in the 'Pro' bundle."
- "Show me this month's payments and total revenue."
- "Which users haven't completed the 'Onboarding' course yet?"
- "Create a 20%-off coupon for the annual subscription plan."
- "Pull completion analytics for our top 5 courses."
Tools are generated automatically from the API and grouped into 🟢 read-only,
🟡 write, and 🔴 destructive — so a well-behaved host can treat each group differently.
## How it works
```
Claude / Cursor / any MCP client ──MCP──► this server ──HTTPS──► LearnWorlds API (your school)
```
The server parses the bundled OpenAPI spec into MCP tools (resolving `$ref`s and
guarding against recursive schemas), tags each with its safety category, and injects
your bearer token and `Lw-Client` header on every outgoing request. Your credentials
stay in the server's environment — the model never sees or handles them.
## Requirements
- A **LearnWorlds school with API access** — an **access token** and a **Client ID**
(admin → Settings → Integrations → Developers), plus your school's API base URL.
See [Get your API credentials](#get-your-api-credentials).
- **Docker** (Docker Desktop on macOS/Windows) for the quick start below — or
**Node.js ≥ 18** to [run from source](#run-from-source-stdio-no-docker).
## Quick start (Docker)
**1. Add your credentials.** Copy the example config and fill it in:
```bash
cp .env.example .env
# edit .env → set LEARNWORLDS_BASE_URL, LEARNWORLDS_API_TOKEN, LEARNWORLDS_CLIENT_ID
# → set MCP_AUTH_TOKEN (required once the port is published beyond
# 127.0.0.1): openssl rand -hex 32
```
**2. Start the server:**
```bash
docker compose up -d --build
```
The bundled `docker-compose.yml` binds to `127.0.0.1:8765` only, so the server is
reachable from your machine but not the network.
**3. Confirm it's running:**
```bash
curl -s http://localhost:8765/health
# → {"status":"ok","server":"learnworlds-mcp","tools":94}
```
**4. Connect your MCP client.** The MCP endpoint is `http://localhost:8765/mcp`.
- **Claude Desktop** — add a **custom connector** (Settings → Connectors) pointing at
the URL, or bridge it locally with [`mcp-remote`](https://www.npmjs.com/package/mcp-remote).
Add this under `mcpServers` in your config, then fully quit and reopen the app:
```json
{
"mcpServers": {
"learnworlds": {
"command": "npx",
"args": [
"mcp-remote",
"http://localhost:8765/mcp",
"--header", "Authorization: Bearer YOUR_MCP_AUTH_TOKEN"
]
}
}
}
```
(Drop the `--header` line if you left `MCP_AUTH_TOKEN` empty.)
- **Claude Code** — one command:
```bash
claude mcp add --transport http learnworlds http://localhost:8765/mcp
```
- **Claude Cowork** — shares Claude Code's MCP config, so the command above makes the
tools available there too.
### Prefer a prebuilt image?
Every push to `main` publishes a ready-to-run image to the GitHub Container Registry,
so you can skip the local build entirely:
```bash
docker run -d --name learnworlds-mcp -p 127.0.0.1:8765:8765 --env-file .env \
ghcr.io/ohneben/learnworlds-mcp:latest
```
## Get your API credentials
1. Log in to your LearnWorlds school admin.
2. Go to **Settings → Integrations → Developers** (the API screen).
3. Copy your **Access Token** → `LEARNWORLDS_API_TOKEN`, and your **Client ID** →
`LEARNWORLDS_CLIENT_ID`.
4. Set `LEARNWORLDS_BASE_URL` to your school's API base:
`https://<your-school>.learnworlds.com/admin/api`. If your school uses a custom
domain, use that host instead (e.g. `https://academy.example.com/admin/api`).
Put all three in `.env`. The server injects them on every request, so your assistant
never sees them.
## Configuration
Everything is set in `.env` (copied from `.env.example`):
| Variable | Required | Default | Description |
|---|---|---|---|
| `LEARNWORLDS_BASE_URL` | ✅ | — | Your school's API base URL |
| `LEARNWORLDS_API_TOKEN` | ✅ | — | Bearer access token |
| `LEARNWORLDS_CLIENT_ID` | ✅ | — | Sent as the `Lw-Client` header |
| `MCP_TRANSPORT` | — | `stdio` | `stdio` or `http` (the Docker image defaults to `http`) |
| `PORT` | — | `8765` | HTTP listen port |
| `HOST` | — | `0.0.0.0` | HTTP bind address |
| `MCP_HTTP_PATH` | — | `/mcp` | HTWhat people ask about Learnworlds-MCP
What is ohneben/Learnworlds-MCP?
+
ohneben/Learnworlds-MCP is mcp servers for the Claude AI ecosystem. ohneben's Model Context Protocol server for the LearnWorlds API — all 94 endpoints as safety-categorized MCP tools (read-only / write / destructive). Runs over stdio or Streamable HTTP, with Docker, retries, and rate limiting. It has 1 GitHub stars and its last recorded update is dated 2026-09-09.
How do I install Learnworlds-MCP?
+
You can install Learnworlds-MCP by cloning the repository (https://github.com/ohneben/Learnworlds-MCP) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is ohneben/Learnworlds-MCP safe to use?
+
Our security agent has analyzed ohneben/Learnworlds-MCP and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.
Who maintains ohneben/Learnworlds-MCP?
+
ohneben/Learnworlds-MCP is maintained by ohneben. The last recorded GitHub activity is dated 2026-09-09, with 1 open issues.
Are there alternatives to Learnworlds-MCP?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy Learnworlds-MCP to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/ohneben-learnworlds-mcp)<a href="https://claudewave.com/repo/ohneben-learnworlds-mcp"><img src="https://claudewave.com/api/badge/ohneben-learnworlds-mcp" alt="Featured on ClaudeWave: ohneben/Learnworlds-MCP" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
The fastest path to AI-powered full stack observability, even for lean teams.
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!