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 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);