learnhouse-mcp-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +564 -0
- package/package.json +35 -0
- package/src/apply_aesthetics.ts +46 -0
- package/src/client.ts +480 -0
- package/src/index.ts +532 -0
- package/src/test-api.ts +185 -0
- package/src/types.ts +243 -0
- package/tsconfig.json +17 -0
package/README.md
ADDED
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
# LearnHouse MCP Server
|
|
2
|
+
|
|
3
|
+
> **Model Context Protocol (MCP) Server for LearnHouse LMS**
|
|
4
|
+
|
|
5
|
+
This MCP server provides AI agents (like GitHub Copilot, Claude, and other AI assistants) with the ability to programmatically manage a LearnHouse Learning Management System instance.
|
|
6
|
+
|
|
7
|
+
## π Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Overview](#overview)
|
|
10
|
+
- [Architecture](#architecture)
|
|
11
|
+
- [Installation & Setup](#installation--setup)
|
|
12
|
+
- [Configuration](#configuration)
|
|
13
|
+
- [Available Tools](#available-tools)
|
|
14
|
+
- [Data Models](#data-models)
|
|
15
|
+
- [Usage Examples](#usage-examples)
|
|
16
|
+
- [VS Code Integration](#vs-code-integration)
|
|
17
|
+
- [API Reference](#api-reference)
|
|
18
|
+
- [Testing Results](#testing-results)
|
|
19
|
+
- [Troubleshooting](#troubleshooting)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Overview
|
|
24
|
+
|
|
25
|
+
### What is MCP?
|
|
26
|
+
|
|
27
|
+
The **Model Context Protocol (MCP)** is an open standard developed by Anthropic that enables AI assistants to interact with external systems through a standardized interface. Instead of hardcoding integrations, MCP allows AI models to discover and use tools dynamically.
|
|
28
|
+
|
|
29
|
+
### What does this server do?
|
|
30
|
+
|
|
31
|
+
The LearnHouse MCP Server exposes **21 tools** that allow AI agents to:
|
|
32
|
+
|
|
33
|
+
- **Manage Courses**: Create, read, update, delete courses
|
|
34
|
+
- **Organize Chapters**: Structure course content into chapters
|
|
35
|
+
- **Create Activities**: Add learning materials (documents, videos, PDFs)
|
|
36
|
+
- **Set Content**: Populate activities with TipTap documents or video URLs
|
|
37
|
+
- **Track Progress**: Monitor user progress through courses
|
|
38
|
+
- **Search**: Find courses and content across the organization
|
|
39
|
+
|
|
40
|
+
### Why use MCP instead of direct API calls?
|
|
41
|
+
|
|
42
|
+
1. **Standardized Interface**: AI models can discover tools automatically
|
|
43
|
+
2. **Type Safety**: Zod schemas validate all parameters
|
|
44
|
+
3. **Authentication Handled**: One-time login, persistent session
|
|
45
|
+
4. **Error Handling**: Consistent error responses
|
|
46
|
+
5. **Multi-Agent Ready**: Any MCP-compatible agent can use these tools
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Architecture
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
54
|
+
β VS Code / AI Agent β
|
|
55
|
+
β (GitHub Copilot, Claude, etc.) β
|
|
56
|
+
βββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
|
|
57
|
+
β stdio (JSON-RPC)
|
|
58
|
+
βΌ
|
|
59
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
60
|
+
β LearnHouse MCP Server β
|
|
61
|
+
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
|
|
62
|
+
β β FastMCP Framework β β
|
|
63
|
+
β β βββββββββββ βββββββββββ βββββββββββ ββββββββββββββββββββ β
|
|
64
|
+
β β β Course β β Chapter β βActivity β β Progress/Search ββ β
|
|
65
|
+
β β β Tools β β Tools β β Tools β β Tools ββ β
|
|
66
|
+
β β ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ ββββββββββ¬ββββββββββ β
|
|
67
|
+
β βββββββββΌββββββββββββΌββββββββββββΌββββββββββββββββΌββββββββββ β
|
|
68
|
+
β β β β β β
|
|
69
|
+
β βββββββββ΄ββββββββββββ΄ββββββββββββ΄ββββββββββββββββ΄ββββββββββ β
|
|
70
|
+
β β LearnHouseClient (API Wrapper) β β
|
|
71
|
+
β β β’ Authentication (login, token management) β β
|
|
72
|
+
β β β’ HTTP Methods (GET, POST, PUT, DELETE) β β
|
|
73
|
+
β β β’ Error Handling β β
|
|
74
|
+
β βββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ β
|
|
75
|
+
ββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ
|
|
76
|
+
β HTTPS
|
|
77
|
+
βΌ
|
|
78
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
79
|
+
β LearnHouse API (FastAPI) β
|
|
80
|
+
β http://localhost:3000 β
|
|
81
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Key Components
|
|
85
|
+
|
|
86
|
+
| Component | File | Description |
|
|
87
|
+
| -------------------- | ------------------ | --------------------------------- |
|
|
88
|
+
| **MCP Server** | `src/index.ts` | Tool definitions with Zod schemas |
|
|
89
|
+
| **API Client** | `src/client.ts` | LearnHouseClient wrapper class |
|
|
90
|
+
| **Type Definitions** | `src/types.ts` | TypeScript interfaces & enums |
|
|
91
|
+
| **Configuration** | `.vscode/mcp.json` | VS Code MCP server config |
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Installation & Setup
|
|
96
|
+
|
|
97
|
+
### Prerequisites
|
|
98
|
+
|
|
99
|
+
- **Node.js** 18+
|
|
100
|
+
- **pnpm** (or npm/yarn)
|
|
101
|
+
- **LearnHouse instance** with admin credentials
|
|
102
|
+
- **VS Code** with GitHub Copilot (for integration)
|
|
103
|
+
|
|
104
|
+
### Install Dependencies
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
cd .mcp
|
|
108
|
+
pnpm install
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Build (for production)
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
pnpm build
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Run in Development Mode
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
pnpm dev
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Test the Server
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# Inspect available tools
|
|
127
|
+
pnpm inspect
|
|
128
|
+
|
|
129
|
+
# Run API tests
|
|
130
|
+
pnpm test
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Configuration
|
|
136
|
+
|
|
137
|
+
### Environment Variables
|
|
138
|
+
|
|
139
|
+
| Variable | Description | Default |
|
|
140
|
+
| --------------------- | ------------------------------ | ----------------------- |
|
|
141
|
+
| `LEARNHOUSE_URL` | Base URL of LearnHouse API | `http://localhost:3000` |
|
|
142
|
+
| `LEARNHOUSE_EMAIL` | Admin email for authentication | Required |
|
|
143
|
+
| `LEARNHOUSE_PASSWORD` | Admin password | Required |
|
|
144
|
+
| `LEARNHOUSE_ORG_ID` | Organization ID | `1` |
|
|
145
|
+
|
|
146
|
+
### VS Code Configuration
|
|
147
|
+
|
|
148
|
+
The MCP server is configured in `.vscode/mcp.json`:
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"servers": {
|
|
153
|
+
"learnhouse": {
|
|
154
|
+
"command": "npx",
|
|
155
|
+
"args": ["tsx", "${workspaceFolder}/.mcp/src/index.ts"],
|
|
156
|
+
"env": {
|
|
157
|
+
"LEARNHOUSE_URL": "http://localhost:3000",
|
|
158
|
+
"LEARNHOUSE_EMAIL": "admin@example.com",
|
|
159
|
+
"LEARNHOUSE_PASSWORD": "YourPassword",
|
|
160
|
+
"LEARNHOUSE_ORG_ID": "1"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Available Tools
|
|
170
|
+
|
|
171
|
+
### Course Management (5 tools)
|
|
172
|
+
|
|
173
|
+
| Tool | Description | Parameters |
|
|
174
|
+
| --------------- | ------------------------------------ | ---------------------------------------------------- |
|
|
175
|
+
| `list_courses` | List all courses in the organization | `page?`, `limit?` |
|
|
176
|
+
| `get_course` | Get detailed course information | `course_uuid` |
|
|
177
|
+
| `create_course` | Create a new course | `name`, `description`, `public?` |
|
|
178
|
+
| `update_course` | Update an existing course | `course_uuid`, `name?`, `description?`, `published?` |
|
|
179
|
+
| `delete_course` | Delete a course | `course_uuid` |
|
|
180
|
+
|
|
181
|
+
### Chapter Management (4 tools)
|
|
182
|
+
|
|
183
|
+
| Tool | Description | Parameters |
|
|
184
|
+
| ---------------- | ----------------------------- | ---------------------------------------------- |
|
|
185
|
+
| `list_chapters` | List all chapters in a course | `course_id` |
|
|
186
|
+
| `get_chapter` | Get chapter details | `chapter_id` |
|
|
187
|
+
| `create_chapter` | Create a new chapter | `course_id`, `name`, `description?`, `org_id?` |
|
|
188
|
+
| `update_chapter` | Update a chapter | `chapter_id`, `name?`, `description?` |
|
|
189
|
+
|
|
190
|
+
### Activity Management (6 tools)
|
|
191
|
+
|
|
192
|
+
| Tool | Description | Parameters |
|
|
193
|
+
| ---------------------- | -------------------------------- | -------------------------------------------------------------------------- |
|
|
194
|
+
| `list_activities` | List all activities in a chapter | `chapter_id` |
|
|
195
|
+
| `get_activity` | Get activity details | `activity_uuid` |
|
|
196
|
+
| `create_activity` | Create a new activity | `chapter_id`, `name`, `activity_type?`, `activity_sub_type?`, `published?` |
|
|
197
|
+
| `update_activity` | Update an activity | `activity_uuid`, `name?`, `published?` |
|
|
198
|
+
| `publish_activity` | Publish an activity | `activity_uuid` |
|
|
199
|
+
| `set_document_content` | Set TipTap document content | `activity_uuid`, `content` (JSON string) |
|
|
200
|
+
|
|
201
|
+
### Content Tools (1 tool)
|
|
202
|
+
|
|
203
|
+
| Tool | Description | Parameters |
|
|
204
|
+
| ------------------- | -------------------------- | ---------------------------- |
|
|
205
|
+
| `set_video_content` | Set video URL for activity | `activity_uuid`, `video_url` |
|
|
206
|
+
|
|
207
|
+
### User & Organization (2 tools)
|
|
208
|
+
|
|
209
|
+
| Tool | Description | Parameters |
|
|
210
|
+
| ------------------ | --------------------------- | ---------- |
|
|
211
|
+
| `get_current_user` | Get authenticated user info | None |
|
|
212
|
+
| `get_organization` | Get organization details | `org_id?` |
|
|
213
|
+
|
|
214
|
+
### Progress Tracking (2 tools)
|
|
215
|
+
|
|
216
|
+
| Tool | Description | Parameters |
|
|
217
|
+
| ------------------------ | -------------------------- | --------------- |
|
|
218
|
+
| `get_course_progress` | Get user's course progress | `course_uuid` |
|
|
219
|
+
| `mark_activity_complete` | Mark activity as completed | `activity_uuid` |
|
|
220
|
+
|
|
221
|
+
### Search (1 tool)
|
|
222
|
+
|
|
223
|
+
| Tool | Description | Parameters |
|
|
224
|
+
| -------- | -------------------------- | -------------------- |
|
|
225
|
+
| `search` | Search courses and content | `query`, `org_slug?` |
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Data Models
|
|
230
|
+
|
|
231
|
+
### Activity Types
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
enum ActivityType {
|
|
235
|
+
TYPE_DYNAMIC = "TYPE_DYNAMIC", // Rich text document (TipTap)
|
|
236
|
+
TYPE_VIDEO = "TYPE_VIDEO", // Video content
|
|
237
|
+
TYPE_DOCUMENT = "TYPE_DOCUMENT", // PDF or document
|
|
238
|
+
TYPE_ASSIGNMENT = "TYPE_ASSIGNMENT", // Assignment
|
|
239
|
+
TYPE_CUSTOM = "TYPE_CUSTOM", // Custom type
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
enum ActivitySubType {
|
|
243
|
+
SUBTYPE_DYNAMIC_PAGE = "SUBTYPE_DYNAMIC_PAGE", // TipTap editor page
|
|
244
|
+
SUBTYPE_VIDEO_YOUTUBE = "SUBTYPE_VIDEO_YOUTUBE", // YouTube embed
|
|
245
|
+
SUBTYPE_VIDEO_HOSTED = "SUBTYPE_VIDEO_HOSTED", // Self-hosted video
|
|
246
|
+
SUBTYPE_DOCUMENT_PDF = "SUBTYPE_DOCUMENT_PDF", // PDF viewer
|
|
247
|
+
SUBTYPE_DOCUMENT_DOC = "SUBTYPE_DOCUMENT_DOC", // Document
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### TipTap Document Structure
|
|
252
|
+
|
|
253
|
+
LearnHouse uses **TipTap** as its rich text editor. Content is stored as JSON:
|
|
254
|
+
|
|
255
|
+
```json
|
|
256
|
+
{
|
|
257
|
+
"type": "doc",
|
|
258
|
+
"content": [
|
|
259
|
+
{
|
|
260
|
+
"type": "heading",
|
|
261
|
+
"attrs": { "level": 1 },
|
|
262
|
+
"content": [{ "type": "text", "text": "Welcome" }]
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"type": "paragraph",
|
|
266
|
+
"content": [{ "type": "text", "text": "This is a paragraph." }]
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"type": "bulletList",
|
|
270
|
+
"content": [
|
|
271
|
+
{
|
|
272
|
+
"type": "listItem",
|
|
273
|
+
"content": [
|
|
274
|
+
{
|
|
275
|
+
"type": "paragraph",
|
|
276
|
+
"content": [{ "type": "text", "text": "Item 1" }]
|
|
277
|
+
}
|
|
278
|
+
]
|
|
279
|
+
}
|
|
280
|
+
]
|
|
281
|
+
}
|
|
282
|
+
]
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Course Structure
|
|
287
|
+
|
|
288
|
+
```
|
|
289
|
+
Organization (org_id: 1)
|
|
290
|
+
βββ Course (course_uuid)
|
|
291
|
+
βββ name: string
|
|
292
|
+
βββ description: string
|
|
293
|
+
βββ public: boolean
|
|
294
|
+
βββ published: boolean
|
|
295
|
+
βββ chapters[]
|
|
296
|
+
βββ Chapter (chapter_id, chapter_uuid)
|
|
297
|
+
βββ name: string
|
|
298
|
+
βββ description: string
|
|
299
|
+
βββ activities[]
|
|
300
|
+
βββ Activity (activity_uuid)
|
|
301
|
+
βββ name: string
|
|
302
|
+
βββ activity_type: ActivityType
|
|
303
|
+
βββ activity_sub_type: ActivitySubType
|
|
304
|
+
βββ content: TipTapDocument | VideoContent
|
|
305
|
+
βββ published: boolean
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Usage Examples
|
|
311
|
+
|
|
312
|
+
### Example 1: Create a Complete Course
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
User: Create a course called "Python Fundamentals" with two chapters
|
|
316
|
+
|
|
317
|
+
AI Agent (using MCP tools):
|
|
318
|
+
1. create_course(name: "Python Fundamentals", description: "Learn Python basics")
|
|
319
|
+
β Returns course_uuid: "course_abc123"
|
|
320
|
+
|
|
321
|
+
2. create_chapter(course_id: 15, name: "Getting Started")
|
|
322
|
+
β Returns chapter_id: 70
|
|
323
|
+
|
|
324
|
+
3. create_chapter(course_id: 15, name: "Variables & Data Types")
|
|
325
|
+
β Returns chapter_id: 71
|
|
326
|
+
|
|
327
|
+
4. create_activity(chapter_id: 70, name: "Introduction to Python", activity_type: "TYPE_DYNAMIC")
|
|
328
|
+
β Returns activity_uuid: "activity_xyz789"
|
|
329
|
+
|
|
330
|
+
5. set_document_content(activity_uuid: "activity_xyz789", content: {...tiptap json...})
|
|
331
|
+
β Content saved
|
|
332
|
+
|
|
333
|
+
6. publish_activity(activity_uuid: "activity_xyz789")
|
|
334
|
+
β Activity published
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Example 2: Add a YouTube Video
|
|
338
|
+
|
|
339
|
+
```
|
|
340
|
+
User: Add a YouTube tutorial to chapter 70
|
|
341
|
+
|
|
342
|
+
AI Agent (using MCP tools):
|
|
343
|
+
1. create_activity(
|
|
344
|
+
chapter_id: 70,
|
|
345
|
+
name: "Python Tutorial Video",
|
|
346
|
+
activity_type: "TYPE_VIDEO",
|
|
347
|
+
activity_sub_type: "SUBTYPE_VIDEO_YOUTUBE"
|
|
348
|
+
)
|
|
349
|
+
β Returns activity_uuid: "activity_video123"
|
|
350
|
+
|
|
351
|
+
2. set_video_content(
|
|
352
|
+
activity_uuid: "activity_video123",
|
|
353
|
+
video_url: "https://www.youtube.com/watch?v=example"
|
|
354
|
+
)
|
|
355
|
+
β Video URL set
|
|
356
|
+
|
|
357
|
+
3. publish_activity(activity_uuid: "activity_video123")
|
|
358
|
+
β Published
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Example 3: Search and Update
|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
User: Find all courses about MCP and update their descriptions
|
|
365
|
+
|
|
366
|
+
AI Agent (using MCP tools):
|
|
367
|
+
1. search(query: "MCP")
|
|
368
|
+
β Returns: [{course_uuid: "course_mcp1", name: "MCP Introduction"}]
|
|
369
|
+
|
|
370
|
+
2. update_course(
|
|
371
|
+
course_uuid: "course_mcp1",
|
|
372
|
+
description: "Updated description for MCP course"
|
|
373
|
+
)
|
|
374
|
+
β Course updated
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## VS Code Integration
|
|
380
|
+
|
|
381
|
+
### How It Works
|
|
382
|
+
|
|
383
|
+
1. **VS Code loads `mcp.json`** at startup
|
|
384
|
+
2. **Starts the MCP server** as a subprocess
|
|
385
|
+
3. **Tools become available** to GitHub Copilot
|
|
386
|
+
4. **AI agent discovers tools** via MCP protocol
|
|
387
|
+
5. **Tools execute** and return results
|
|
388
|
+
|
|
389
|
+
### Verifying the Server
|
|
390
|
+
|
|
391
|
+
In VS Code:
|
|
392
|
+
|
|
393
|
+
1. Open Command Palette (`Ctrl+Shift+P`)
|
|
394
|
+
2. Run "Developer: Show MCP Tools"
|
|
395
|
+
3. You should see all 21 LearnHouse tools
|
|
396
|
+
|
|
397
|
+
### Using with Copilot
|
|
398
|
+
|
|
399
|
+
Simply ask Copilot to perform LearnHouse operations:
|
|
400
|
+
|
|
401
|
+
> "List all courses in LearnHouse"
|
|
402
|
+
> "Create a new chapter called 'Introduction' in course 5"
|
|
403
|
+
> "Search for courses about Python"
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## API Reference
|
|
408
|
+
|
|
409
|
+
### Base URL
|
|
410
|
+
|
|
411
|
+
```
|
|
412
|
+
http://localhost:3000/api/v1
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### Authentication
|
|
416
|
+
|
|
417
|
+
The client uses **OAuth2 password flow**:
|
|
418
|
+
|
|
419
|
+
```
|
|
420
|
+
POST /auth/login
|
|
421
|
+
Content-Type: application/x-www-form-urlencoded
|
|
422
|
+
|
|
423
|
+
username=admin@example.com&password=YourPassword
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
Returns:
|
|
427
|
+
|
|
428
|
+
```json
|
|
429
|
+
{
|
|
430
|
+
"user": { "id": 1, "email": "admin@example.com", ... },
|
|
431
|
+
"tokens": {
|
|
432
|
+
"access_token": "eyJ...",
|
|
433
|
+
"refresh_token": "eyJ..."
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### Key Endpoints
|
|
439
|
+
|
|
440
|
+
| Method | Endpoint | Description |
|
|
441
|
+
| ------ | --------------------------------------------- | --------------- |
|
|
442
|
+
| GET | `/courses/org_slug/{slug}/page/{p}/limit/{l}` | List courses |
|
|
443
|
+
| GET | `/courses/{uuid}` | Get course |
|
|
444
|
+
| POST | `/courses/` | Create course |
|
|
445
|
+
| PUT | `/courses/{uuid}` | Update course |
|
|
446
|
+
| DELETE | `/courses/{uuid}` | Delete course |
|
|
447
|
+
| GET | `/chapters/{id}` | Get chapter |
|
|
448
|
+
| POST | `/chapters/` | Create chapter |
|
|
449
|
+
| PUT | `/chapters/{id}` | Update chapter |
|
|
450
|
+
| GET | `/activities/{uuid}` | Get activity |
|
|
451
|
+
| POST | `/activities/` | Create activity |
|
|
452
|
+
| PUT | `/activities/{uuid}` | Update activity |
|
|
453
|
+
| GET | `/search/org_slug/{slug}?query=` | Search |
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## Testing Results
|
|
458
|
+
|
|
459
|
+
### Tool Verification (January 23, 2026)
|
|
460
|
+
|
|
461
|
+
| # | Tool | Status | Notes |
|
|
462
|
+
| --- | ------------------------ | ------------ | -------------------------------- |
|
|
463
|
+
| 1 | `list_courses` | β
Pass | 12 courses returned |
|
|
464
|
+
| 2 | `get_course` | β
Pass | Course details retrieved |
|
|
465
|
+
| 3 | `create_course` | β
Pass | Created course id=13 |
|
|
466
|
+
| 4 | `update_course` | β
Pass | Name updated |
|
|
467
|
+
| 5 | `delete_course` | β
Pass | Course deleted |
|
|
468
|
+
| 6 | `list_chapters` | β API Error | HTTP 500 (backend issue) |
|
|
469
|
+
| 7 | `get_chapter` | β
Pass | Chapter details retrieved |
|
|
470
|
+
| 8 | `create_chapter` | β
Pass | Created chapter id=62 |
|
|
471
|
+
| 9 | `update_chapter` | β
Pass | Name/description updated |
|
|
472
|
+
| 10 | `list_activities` | β
Pass | Activities listed |
|
|
473
|
+
| 11 | `get_activity` | β
Pass | Activity details retrieved |
|
|
474
|
+
| 12 | `create_activity` | β
Pass | Created activities (doc & video) |
|
|
475
|
+
| 13 | `update_activity` | β
Pass | Name updated |
|
|
476
|
+
| 14 | `publish_activity` | β
Pass | Activity published |
|
|
477
|
+
| 15 | `set_document_content` | β
Pass | TipTap content set |
|
|
478
|
+
| 16 | `set_video_content` | β
Pass | YouTube URL set |
|
|
479
|
+
| 17 | `get_current_user` | β
Pass | admin@example.com |
|
|
480
|
+
| 18 | `get_organization` | β
Pass | AgentOne org details |
|
|
481
|
+
| 19 | `search` | β
Pass | Found courses |
|
|
482
|
+
| 20 | `get_course_progress` | β API Error | Requires enrollment |
|
|
483
|
+
| 21 | `mark_activity_complete` | β API Error | Requires enrollment |
|
|
484
|
+
|
|
485
|
+
**Result: 18/21 tools working (86% success rate)**
|
|
486
|
+
|
|
487
|
+
The 3 failing tools have backend API issues, not MCP server bugs.
|
|
488
|
+
|
|
489
|
+
---
|
|
490
|
+
|
|
491
|
+
## Troubleshooting
|
|
492
|
+
|
|
493
|
+
### Server won't start
|
|
494
|
+
|
|
495
|
+
```bash
|
|
496
|
+
# Check Node.js version
|
|
497
|
+
node --version # Should be 18+
|
|
498
|
+
|
|
499
|
+
# Reinstall dependencies
|
|
500
|
+
cd .mcp
|
|
501
|
+
rm -rf node_modules
|
|
502
|
+
pnpm install
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
### Authentication fails
|
|
506
|
+
|
|
507
|
+
1. Verify credentials in environment variables
|
|
508
|
+
2. Check if user exists in LearnHouse
|
|
509
|
+
3. Ensure user has admin permissions
|
|
510
|
+
|
|
511
|
+
### Tool returns "Not Found"
|
|
512
|
+
|
|
513
|
+
- Verify the UUID/ID exists
|
|
514
|
+
- Check if the resource is in the correct organization
|
|
515
|
+
- Some endpoints require user enrollment (progress tools)
|
|
516
|
+
|
|
517
|
+
### "Cannot find module" error
|
|
518
|
+
|
|
519
|
+
```bash
|
|
520
|
+
# Rebuild TypeScript
|
|
521
|
+
pnpm build
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### VS Code doesn't show tools
|
|
525
|
+
|
|
526
|
+
1. Reload VS Code window
|
|
527
|
+
2. Check `.vscode/mcp.json` syntax
|
|
528
|
+
3. View Output β "MCP" channel for errors
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
## Dependencies
|
|
533
|
+
|
|
534
|
+
| Package | Version | Purpose |
|
|
535
|
+
| ------------ | ------- | -------------------- |
|
|
536
|
+
| `fastmcp` | ^3.29.0 | MCP framework |
|
|
537
|
+
| `zod` | ^3.23.8 | Schema validation |
|
|
538
|
+
| `typescript` | ^5.x | Type safety |
|
|
539
|
+
| `tsx` | ^4.x | TypeScript execution |
|
|
540
|
+
|
|
541
|
+
---
|
|
542
|
+
|
|
543
|
+
## License
|
|
544
|
+
|
|
545
|
+
MIT License - See [LICENSE](../LICENSE)
|
|
546
|
+
|
|
547
|
+
---
|
|
548
|
+
|
|
549
|
+
## Contributing
|
|
550
|
+
|
|
551
|
+
1. Fork the repository
|
|
552
|
+
2. Create a feature branch
|
|
553
|
+
3. Make changes to `.mcp/src/`
|
|
554
|
+
4. Test with `pnpm inspect`
|
|
555
|
+
5. Submit a pull request
|
|
556
|
+
|
|
557
|
+
---
|
|
558
|
+
|
|
559
|
+
## Related Documentation
|
|
560
|
+
|
|
561
|
+
- [LearnHouse API Docs](https://docs.learnhouse.app)
|
|
562
|
+
- [MCP Specification](https://modelcontextprotocol.io)
|
|
563
|
+
- [FastMCP GitHub](https://github.com/punkpeye/fastmcp)
|
|
564
|
+
- [TipTap Documentation](https://tiptap.dev/docs)
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "learnhouse-mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP Server for LearnHouse LMS - Manage courses, chapters, activities, and users",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"dev": "tsx watch src/index.ts",
|
|
10
|
+
"start": "node dist/index.js",
|
|
11
|
+
"test": "tsx src/test-api.ts",
|
|
12
|
+
"test:auth": "tsx src/tests/auth.test.ts",
|
|
13
|
+
"test:courses": "tsx src/tests/courses.test.ts",
|
|
14
|
+
"test:chapters": "tsx src/tests/chapters.test.ts",
|
|
15
|
+
"test:activities": "tsx src/tests/activities.test.ts",
|
|
16
|
+
"inspect": "npx fastmcp inspect src/index.ts"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"mcp",
|
|
20
|
+
"learnhouse",
|
|
21
|
+
"lms",
|
|
22
|
+
"ai-agents"
|
|
23
|
+
],
|
|
24
|
+
"author": "AgentOne",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"fastmcp": "^3.29.0",
|
|
28
|
+
"zod": "^3.23.8"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^22.0.0",
|
|
32
|
+
"tsx": "^4.19.0",
|
|
33
|
+
"typescript": "^5.6.0"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { LearnHouseClient } from "./client.js";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
const config = {
|
|
6
|
+
baseUrl: process.env.LEARNHOUSE_URL || "http://localhost:3000",
|
|
7
|
+
email: process.env.LEARNHOUSE_EMAIL || "",
|
|
8
|
+
password: process.env.LEARNHOUSE_PASSWORD || "",
|
|
9
|
+
orgId: parseInt(process.env.LEARNHOUSE_ORG_ID || "1", 10),
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
async function main() {
|
|
13
|
+
const client = new LearnHouseClient({
|
|
14
|
+
baseUrl: config.baseUrl,
|
|
15
|
+
orgId: config.orgId,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
console.log("Logging in...");
|
|
19
|
+
await client.login(config.email, config.password);
|
|
20
|
+
|
|
21
|
+
// 1. Upload Thumbnail to Mastering MCP
|
|
22
|
+
const courseUuid = "course_d6d76f09-c553-4f82-ab81-82a1c69fdd5f";
|
|
23
|
+
const imagePath = "\\\\192.168.2.108\\Users\\Laptop\\Desktop\\Projects\\Studies\\Winter_2026\\01_SIA 3000 - Projet integrateur\\AgentOne_Project\\_Handover\\Hero\\1_Hero_Backgrounds\\hero_grid_08_circuit_grid.png";
|
|
24
|
+
|
|
25
|
+
if (fs.existsSync(imagePath)) {
|
|
26
|
+
console.log(`Uploading thumbnail: ${imagePath}`);
|
|
27
|
+
const buffer = fs.readFileSync(imagePath);
|
|
28
|
+
const fileName = path.basename(imagePath);
|
|
29
|
+
const updatedCourse = await client.uploadCourseThumbnail(courseUuid, buffer, fileName);
|
|
30
|
+
console.log(`β
Thumbnail uploaded! URL: ${updatedCourse.thumbnail_image}`);
|
|
31
|
+
} else {
|
|
32
|
+
console.warn(`β οΈ Image not found: ${imagePath}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 2. Create Collection
|
|
36
|
+
console.log("Creating collection 'Artemis AI Core Protocols'...");
|
|
37
|
+
const collection = await client.createCollection({
|
|
38
|
+
name: "Artemis AI Core Protocols",
|
|
39
|
+
description: "Foundational protocols and frameworks for the Agentic Internet.",
|
|
40
|
+
courses: [16], // Mastering MCP
|
|
41
|
+
public: true,
|
|
42
|
+
});
|
|
43
|
+
console.log(`β
Collection created! UUID: ${collection.collection_uuid}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
main().catch(console.error);
|