moodlia-sync-mcp 0.1.1 → 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.
Files changed (2) hide show
  1. package/README.md +108 -95
  2. package/package.json +40 -40
package/README.md CHANGED
@@ -1,95 +1,108 @@
1
- # MoodlIA Sync MCP
2
-
3
- `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.
4
-
5
- It requires Node.js 22.13 or later because its durable state store uses the
6
- built-in SQLite API without experimental process flags.
7
-
8
- 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.
9
-
10
- ## Status
11
-
12
- 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.
13
-
14
- ## Configuration
15
-
16
- Create `.moodle-profiles.json`:
17
-
18
- ```json
19
- {
20
- "schema_version": 1,
21
- "profiles": {
22
- "source": {
23
- "url": "https://source.example.edu",
24
- "backend": "auto",
25
- "credentials": {
26
- "core": { "token_env": "SOURCE_CORE_TOKEN" },
27
- "moodlia": { "token_env": "SOURCE_MOODLIA_TOKEN" }
28
- }
29
- },
30
- "target": {
31
- "url": "https://target.example.edu",
32
- "backend": "auto",
33
- "credentials": {
34
- "core": { "token_env": "TARGET_CORE_TOKEN" },
35
- "moodlia": { "token_env": "TARGET_MOODLIA_TOKEN" }
36
- }
37
- }
38
- }
39
- }
40
- ```
41
-
42
- Create `.moodle-sync-policy.json`:
43
-
44
- ```json
45
- {
46
- "schema_version": 1,
47
- "allowed_profiles": ["source", "target"],
48
- "allowed_pairs": [
49
- {
50
- "source": "source",
51
- "target": "target",
52
- "source_courses": [42],
53
- "target_courses": [81],
54
- "target_categories": [7],
55
- "effects": ["content.read", "content.write"]
56
- }
57
- ]
58
- }
59
- ```
60
-
61
- Set `MOODLIA_SYNC_CONFIG`, `MOODLIA_SYNC_POLICY`, and optionally `MOODLIA_SYNC_STATE`. Start the stdio server with `npx moodlia-sync-mcp`.
62
-
63
- 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.
64
-
65
- ## Approval boundary
66
-
67
- `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:
68
-
69
- ```powershell
70
- moodlia course sync `
71
- --approve-plan ".moodle-sync\plans\PLAN_ID.json" `
72
- --state ".moodle-sync\coordinator.sqlite" `
73
- --yes
74
- ```
75
-
76
- 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.
77
-
78
- ## MCP tools
79
-
80
- - `sync_list_profiles`
81
- - `sync_discover_capabilities`
82
- - `sync_plan_course`
83
- - `sync_get_plan` (bounded pagination across actions, conflicts, gaps, unchanged, and unknown entries)
84
- - `sync_apply_plan`
85
- - `sync_get_job`
86
- - `sync_cancel_job`
87
- - `sync_resume_job`
88
- - `sync_verify_course`
89
- - `sync_get_conflicts`
90
- - `sync_resolve_conflict`
91
- - `sync_get_history`
92
-
93
- 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.
94
-
95
- All documentation, schemas, source identifiers, and source comments are in English.
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.1",
4
- "description": "Local MCP coordinator for policy-bound cross-site 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
- }
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
+ }