moodlia-sync-mcp 0.1.0 → 0.1.2
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 +108 -95
- package/package.json +40 -40
package/README.md
CHANGED
|
@@ -1,95 +1,108 @@
|
|
|
1
|
-
# MoodlIA Sync MCP
|
|
2
|
-
|
|
3
|
-
`moodlia-sync-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
##
|
|
79
|
-
|
|
80
|
-
- `
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
- `
|
|
85
|
-
- `
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
1
|
+
# MoodlIA Sync MCP (deprecated)
|
|
2
|
+
|
|
3
|
+
> **Deprecated.** This coordinator is replaced by the [`moodlia-sync`](https://www.npmjs.com/package/moodlia-sync) CLI and receives no further updates. Its approval boundary did not protect against agents with shell access, which can run the same CLI; `moodlia-sync` keeps the approval model by consuming an approval of the exact plan digest atomically on every `apply` and `resume`.
|
|
4
|
+
>
|
|
5
|
+
> | MCP tool | `moodlia-sync` command |
|
|
6
|
+
> | --- | --- |
|
|
7
|
+
> | `sync_list_profiles`, `sync_discover_capabilities` | `capabilities --profile <name>` |
|
|
8
|
+
> | `sync_plan_course` | `plan --source-profile ... --plan-file plan.json` |
|
|
9
|
+
> | external approval + `sync_apply_plan` | `approve plan.json --yes`, then `apply plan.json --plan-digest <d> --allow-write` |
|
|
10
|
+
> | `sync_get_plan`, `sync_get_conflicts`, `sync_resolve_conflict` | `conflicts plan.json [--resolve source-wins|target-wins]` |
|
|
11
|
+
> | `sync_get_job`, `sync_get_history`, `sync_cancel_job` | `status`, `history`, `cancel` |
|
|
12
|
+
> | `sync_resume_job`, `sync_verify_course` | `resume ... --approve --yes`, `verify --plan-id <id>` |
|
|
13
|
+
>
|
|
14
|
+
> Existing state databases open unchanged in `moodlia-sync`.
|
|
15
|
+
|
|
16
|
+
`moodlia-sync-mcp` is an MCP coordinator for one-way course-content synchronization between Moodle sites. Each endpoint may use Moodle Core web services, the MoodlIA plugin, or both. Provider selection is capability-based and is frozen into every approved action.
|
|
17
|
+
|
|
18
|
+
It requires Node.js 22.13 or later because its durable state store uses the
|
|
19
|
+
built-in SQLite API without experimental process flags.
|
|
20
|
+
|
|
21
|
+
The coordinator does not send Moodle tokens or binary files through MCP tool arguments or results. Profiles reference environment variables, and an allowlist restricts profile pairs, course IDs, and effects.
|
|
22
|
+
|
|
23
|
+
## Status
|
|
24
|
+
|
|
25
|
+
The current preview synchronizes verified course metadata, hidden target-course creation, sections, groups and grouping membership, portable Pages/Labels/URLs, file resources and folders, Books with chapter files, selected assignment definitions and grading forms, Workshop forms, supported question banks and Quiz slots, portable Lesson pages, Database fields, Feedback items, course-completion criteria, and selected gradebook configuration. The coordinator uses the same engine and adaptive adapters as the CLI, so provider selection and advanced action semantics are identical. Existing unsupported authoring changes and unsafe transformations are reported before writing. It does not use Moodle backup files.
|
|
26
|
+
|
|
27
|
+
## Configuration
|
|
28
|
+
|
|
29
|
+
Create `.moodle-profiles.json`:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"schema_version": 1,
|
|
34
|
+
"profiles": {
|
|
35
|
+
"source": {
|
|
36
|
+
"url": "https://source.example.edu",
|
|
37
|
+
"backend": "auto",
|
|
38
|
+
"credentials": {
|
|
39
|
+
"core": { "token_env": "SOURCE_CORE_TOKEN" },
|
|
40
|
+
"moodlia": { "token_env": "SOURCE_MOODLIA_TOKEN" }
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"target": {
|
|
44
|
+
"url": "https://target.example.edu",
|
|
45
|
+
"backend": "auto",
|
|
46
|
+
"credentials": {
|
|
47
|
+
"core": { "token_env": "TARGET_CORE_TOKEN" },
|
|
48
|
+
"moodlia": { "token_env": "TARGET_MOODLIA_TOKEN" }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Create `.moodle-sync-policy.json`:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"schema_version": 1,
|
|
60
|
+
"allowed_profiles": ["source", "target"],
|
|
61
|
+
"allowed_pairs": [
|
|
62
|
+
{
|
|
63
|
+
"source": "source",
|
|
64
|
+
"target": "target",
|
|
65
|
+
"source_courses": [42],
|
|
66
|
+
"target_courses": [81],
|
|
67
|
+
"target_categories": [7],
|
|
68
|
+
"effects": ["content.read", "content.write"]
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Set `MOODLIA_SYNC_CONFIG`, `MOODLIA_SYNC_POLICY`, and optionally `MOODLIA_SYNC_STATE`. Start the stdio server with `npx moodlia-sync-mcp`.
|
|
75
|
+
|
|
76
|
+
For Streamable HTTP, set a random `MOODLIA_SYNC_BEARER_TOKEN` of at least 32 bytes and run `npx moodlia-sync-mcp-http`. It binds to `127.0.0.1:3333` by default. Put a TLS-authenticated reverse proxy in front of it for remote clients, set `MOODLIA_SYNC_ALLOWED_HOSTS`, and never expose the plain HTTP listener directly. The bearer token authenticates the client to the coordinator; Moodle tokens remain separate downstream credentials.
|
|
77
|
+
|
|
78
|
+
## Approval boundary
|
|
79
|
+
|
|
80
|
+
`sync_plan_course` is read-only. `sync_apply_plan` accepts only a plan that was approved outside MCP and stored in the same SQLite state database:
|
|
81
|
+
|
|
82
|
+
```powershell
|
|
83
|
+
moodlia course sync `
|
|
84
|
+
--approve-plan ".moodle-sync\plans\PLAN_ID.json" `
|
|
85
|
+
--state ".moodle-sync\coordinator.sqlite" `
|
|
86
|
+
--yes
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Approval is bound to the complete plan digest, expires with the plan, and is consumed before execution. A model-provided boolean is never treated as human authorization.
|
|
90
|
+
|
|
91
|
+
## MCP tools
|
|
92
|
+
|
|
93
|
+
- `sync_list_profiles`
|
|
94
|
+
- `sync_discover_capabilities`
|
|
95
|
+
- `sync_plan_course`
|
|
96
|
+
- `sync_get_plan` (bounded pagination across actions, conflicts, gaps, unchanged, and unknown entries)
|
|
97
|
+
- `sync_apply_plan`
|
|
98
|
+
- `sync_get_job`
|
|
99
|
+
- `sync_cancel_job`
|
|
100
|
+
- `sync_resume_job`
|
|
101
|
+
- `sync_verify_course`
|
|
102
|
+
- `sync_get_conflicts`
|
|
103
|
+
- `sync_resolve_conflict`
|
|
104
|
+
- `sync_get_history`
|
|
105
|
+
|
|
106
|
+
Jobs, action attempts, approvals, mappings, baselines, and leases are durable in SQLite. On restart, in-flight jobs become `interrupted` and must be reconciled and explicitly re-approved before resume. Timeout outcomes are marked `unknown_outcome`, not retried blindly.
|
|
107
|
+
|
|
108
|
+
All documentation, schemas, source identifiers, and source comments are in English.
|
package/package.json
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "moodlia-sync-mcp",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
5
|
-
"type": "module",
|
|
6
|
-
"license": "GPL-3.0-or-later",
|
|
7
|
-
"author": "Pablo Gallego",
|
|
8
|
-
"bin": {
|
|
9
|
-
"moodlia-sync-mcp": "server/stdio.mjs",
|
|
10
|
-
"moodlia-sync-mcp-http": "server/http.mjs"
|
|
11
|
-
},
|
|
12
|
-
"exports": {
|
|
13
|
-
".": "./server/coordinator.mjs",
|
|
14
|
-
"./mcp-server": "./server/mcp-server.mjs",
|
|
15
|
-
"./http": "./server/http.mjs"
|
|
16
|
-
},
|
|
17
|
-
"files": [
|
|
18
|
-
"server/",
|
|
19
|
-
"README.md",
|
|
20
|
-
"LICENSE"
|
|
21
|
-
],
|
|
22
|
-
"scripts": {
|
|
23
|
-
"test": "node --test tests/*.test.mjs",
|
|
24
|
-
"check": "node --check server/coordinator.mjs && node --check server/mcp-server.mjs && node --check server/stdio.mjs && node --check server/http.mjs && npm test",
|
|
25
|
-
"pack:check": "npm pack --dry-run"
|
|
26
|
-
},
|
|
27
|
-
"engines": {
|
|
28
|
-
"node": ">=22.13"
|
|
29
|
-
},
|
|
30
|
-
"dependencies": {
|
|
31
|
-
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
32
|
-
"moodle-core-cli": "^0.3.
|
|
33
|
-
"moodlia": "^0.3.
|
|
34
|
-
"zod": "^4.6.5"
|
|
35
|
-
},
|
|
36
|
-
"publishConfig": {
|
|
37
|
-
"access": "public",
|
|
38
|
-
"registry": "https://registry.npmjs.org"
|
|
39
|
-
}
|
|
40
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "moodlia-sync-mcp",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Deprecated: use the moodlia-sync CLI. MCP coordinator for Moodle course synchronization.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "GPL-3.0-or-later",
|
|
7
|
+
"author": "Pablo Gallego",
|
|
8
|
+
"bin": {
|
|
9
|
+
"moodlia-sync-mcp": "server/stdio.mjs",
|
|
10
|
+
"moodlia-sync-mcp-http": "server/http.mjs"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
".": "./server/coordinator.mjs",
|
|
14
|
+
"./mcp-server": "./server/mcp-server.mjs",
|
|
15
|
+
"./http": "./server/http.mjs"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"server/",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"test": "node --test tests/*.test.mjs",
|
|
24
|
+
"check": "node --check server/coordinator.mjs && node --check server/mcp-server.mjs && node --check server/stdio.mjs && node --check server/http.mjs && npm test",
|
|
25
|
+
"pack:check": "npm pack --dry-run"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=22.13"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
32
|
+
"moodle-core-cli": "^0.3.6",
|
|
33
|
+
"moodlia": "^0.3.7",
|
|
34
|
+
"zod": "^4.6.5"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public",
|
|
38
|
+
"registry": "https://registry.npmjs.org"
|
|
39
|
+
}
|
|
40
|
+
}
|