moodle-cli 0.6.0 → 0.7.0-alpha.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moodle-cli",
3
- "version": "0.6.0",
3
+ "version": "0.7.0-alpha.1",
4
4
  "description": "Terminal-first CLI for Moodle LMS",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -10,30 +10,35 @@
10
10
  "files": [
11
11
  "dist",
12
12
  "README.md",
13
+ "ONBOARDING.md",
13
14
  "SKILL.md",
14
15
  "references",
15
16
  "agents",
16
17
  "LICENSE"
17
18
  ],
18
19
  "scripts": {
19
- "build": "tsc --noEmit && tsup && rm -f dist/.gitignore",
20
+ "build": "tsc --noEmit && tsup && npm run build:worker && rm -f dist/.gitignore",
21
+ "build:worker": "tsup --config tsup.worker.config.ts && node scripts/check-worker-bundle.mjs",
22
+ "bin:smoke": "bun scripts/smoke-standalone.mjs",
20
23
  "check": "tsc --noEmit",
21
- "pack:check": "npm pack --dry-run --json | node -e \"let data = ''; process.stdin.on('data', chunk => data += chunk); process.stdin.on('end', () => { const files = JSON.parse(data)[0]?.files?.map(file => file.path) ?? []; for (const required of ['dist/moodle.js', 'SKILL.md', 'references/command-reference.md', 'agents/openai.yaml']) if (!files.includes(required)) throw new Error('npm package is missing ' + required); });\"",
22
- "pack:smoke": "tmp=\"$(mktemp -d)\" && npm pack --pack-destination \"$tmp\" >/dev/null && npm install --prefix \"$tmp/install\" \"$tmp\"/moodle-cli-*.tgz >/dev/null && test \"$(\"$tmp/install/node_modules/.bin/moodle\" --version)\" = \"$(node -p \"JSON.parse(require('node:fs').readFileSync('package.json', 'utf8')).version\")\"",
24
+ "pack:check": "npm pack --dry-run --json | node -e \"let data = ''; process.stdin.on('data', chunk => data += chunk); process.stdin.on('end', () => { const files = JSON.parse(data)[0]?.files?.map(file => file.path) ?? []; for (const required of ['dist/moodle.js', 'dist/worker/worker.js', 'README.md', 'ONBOARDING.md', 'SKILL.md', 'references/command-reference.md', 'references/downloads.md', 'agents/openai.yaml']) if (!files.includes(required)) throw new Error('npm package is missing ' + required); });\"",
25
+ "pack:smoke": "tmp=\"$(mktemp -d)\" && npm pack --pack-destination \"$tmp\" >/dev/null && npm install --prefix \"$tmp/install\" \"$tmp\"/moodle-cli-*.tgz >/dev/null && test \"$(\"$tmp/install/node_modules/.bin/moodle\" --version)\" = \"$(node -p \"JSON.parse(require('node:fs').readFileSync('package.json', 'utf8')).version\")\" && \"$tmp/install/node_modules/.bin/moodle\" download --help >/dev/null && \"$tmp/install/node_modules/.bin/moodle\" mcp --help >/dev/null",
23
26
  "test": "vitest run",
27
+ "test:mcp": "vitest run tests/mcp-*.test.ts tests/deployment-*.test.ts tests/renewal-*.test.ts tests/connectors-*.test.ts",
28
+ "test:worker": "vitest run tests/worker-*.test.ts",
24
29
  "test:watch": "vitest",
25
30
  "skill:generate": "node dist/moodle.js skills generate",
26
- "prepublishOnly": "npm run test && npm run build"
31
+ "prepublishOnly": "npm run test && npm run build && npm run pack:check"
27
32
  },
28
33
  "dependencies": {
29
- "commander": "^14.0.0",
34
+ "@bunizao/cli-kit": "^0.1.0",
35
+ "@steipete/sweet-cookie": "^0.4.0",
36
+ "commander": "^13.1.0",
30
37
  "node-html-parser": "^7.0.1",
38
+ "wrangler": "^4.120.0",
31
39
  "yaml": "^2.8.0",
32
40
  "zod": "^4.0.5"
33
41
  },
34
- "optionalDependencies": {
35
- "chrome-cookies-secure": "^3.0.2"
36
- },
37
42
  "devDependencies": {
38
43
  "@types/node": "^24.0.10",
39
44
  "tsup": "^8.5.0",
@@ -41,7 +46,7 @@
41
46
  "vitest": "^3.2.4"
42
47
  },
43
48
  "engines": {
44
- "node": ">=20"
49
+ "node": ">=22"
45
50
  },
46
51
  "repository": {
47
52
  "type": "git",
@@ -4,35 +4,45 @@ Read this file for exact arguments, flags, and defaults after selecting a branch
4
4
 
5
5
  | Command | Description | Arguments | Flags |
6
6
  | --- | --- | --- | --- |
7
- | moodle activities | List activities in a course. | <course> | --json<br>--yaml<br>--table<br>--fields (value required) |
8
- | moodle alerts | List notifications and message counts. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--limit (default: 20; value required) |
9
- | moodle assign | Show assignment details. | <assign> | --json<br>--yaml<br>--table<br>--fields (value required) |
7
+ | moodle activities | Inspect activities. | | |
8
+ | moodle activities list | List activities in a unit. | <unit> | --json<br>--yaml<br>--table<br>--fields (value required) |
9
+ | moodle activities show | Show activity detail. | <id> | --json<br>--yaml<br>--table<br>--fields (value required) |
10
+ | moodle alerts | List notifications and message counts. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--limit (value required) |
10
11
  | moodle auth | Session and keepalive utilities. | | |
11
12
  | moodle auth keepalive | Renew the Moodle session once; used by the background keepalive agent. | | --no-renew<br>--json<br>--yaml<br>--table<br>--fields (value required) |
12
13
  | moodle auth keepalive install | Install a macOS launch agent that renews the session periodically. | | --interval (value required)<br>--json<br>--yaml<br>--table<br>--fields (value required) |
13
14
  | moodle auth keepalive status | Show whether the keepalive launch agent is installed. | | --json<br>--yaml<br>--table<br>--fields (value required) |
14
15
  | moodle auth keepalive uninstall | Remove the keepalive launch agent. | | --json<br>--yaml<br>--table<br>--fields (value required) |
15
- | moodle auth login | Force a fresh login and refresh the session cache. | | --json<br>--yaml<br>--table<br>--fields (value required) |
16
+ | moodle auth login | Extract a fresh session, opening the browser when needed. | | --json<br>--yaml<br>--table<br>--fields (value required) |
16
17
  | moodle auth status | Show cached session freshness and keepalive state. | | --json<br>--yaml<br>--table<br>--fields (value required) |
17
- | moodle course | Show course detail with sections. | <course> | --json<br>--yaml<br>--table<br>--fields (value required) |
18
- | moodle courses | List enrolled courses. | | --json<br>--yaml<br>--table<br>--fields (value required) |
19
- | moodle folder | Show folder details. | <folder> | --json<br>--yaml<br>--table<br>--fields (value required) |
20
- | moodle forum | Forum utilities. | | |
21
- | moodle forum check | Validate discussion rendering. | <forum> | --json<br>--yaml<br>--table<br>--fields (value required)<br>--limit (default: 20; value required) |
22
- | moodle forum discussion | Show posts in a forum discussion. | <discussion> | --json<br>--yaml<br>--table<br>--fields (value required)<br>--post (value required)<br>--body |
23
- | moodle forum discussions | List discussions from a forum. | <forum> | --json<br>--yaml<br>--table<br>--fields (value required)<br>--limit (default: 50; value required)<br>--query (value required) |
24
- | moodle forum find | Find the best forum match. | <query> | --list<br>--body<br>--json<br>--yaml<br>--table<br>--fields (value required)<br>--course (value required)<br>--forum (value required)<br>--titles-only<br>--unread-only<br>--recent<br>--limit-forums (value required)<br>--limit-discussions (value required)<br>--limit (default: 5; value required) |
25
- | moodle forum forums | List forum activities. | [query] | --json<br>--yaml<br>--table<br>--fields (value required)<br>--course (value required)<br>--limit (default: 50; value required) |
26
- | moodle forum search | Search forum discussion titles and post text. | <query> | --json<br>--yaml<br>--table<br>--fields (value required)<br>--course (value required)<br>--forum (value required)<br>--titles-only<br>--unread-only<br>--recent<br>--limit-forums (value required)<br>--limit-discussions (value required)<br>--limit (default: 20; value required) |
27
- | moodle grades | Show grade details for a course. | <course> | --json<br>--yaml<br>--table<br>--fields (value required) |
28
- | moodle link | Show link details. | <link> | --json<br>--yaml<br>--table<br>--fields (value required) |
29
- | moodle overview | Show a compact multi-source overview. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--todo-limit (default: 5; value required)<br>--todo-days (value required)<br>--alerts-limit (default: 5; value required) |
30
- | moodle page | Show page details. | <page> | --json<br>--yaml<br>--table<br>--fields (value required) |
31
- | moodle quiz | Show quiz details. | <quiz> | --json<br>--yaml<br>--table<br>--fields (value required) |
32
- | moodle resource | Show resource details. | <resource> | --json<br>--yaml<br>--table<br>--fields (value required) |
18
+ | moodle commands | Describe the complete command tree. | | --json<br>--yaml<br>--table<br>--fields (value required) |
19
+ | moodle download | Download one authenticated Moodle file. | <source> | --dest (value required)<br>--force<br>--json<br>--yaml<br>--table<br>--fields (value required) |
20
+ | moodle forums | Inspect forums. | | |
21
+ | moodle forums list | List forum activities in a unit. | <unit> | --json<br>--yaml<br>--table<br>--fields (value required)<br>--limit (value required) |
22
+ | moodle forums search | Search forum discussion titles and post text. | <query> | --json<br>--yaml<br>--table<br>--fields (value required)<br>--course (value required)<br>--forum (value required)<br>--titles-only<br>--unread-only<br>--recent<br>--limit-forums (value required)<br>--limit-discussions (value required)<br>--limit (value required) |
23
+ | moodle forums show | List discussions from a forum. | <forum> | --json<br>--yaml<br>--table<br>--fields (value required)<br>--limit (value required)<br>--query (value required) |
24
+ | moodle grades | Inspect grades. | | |
25
+ | moodle grades list | Show grade details for a unit. | <unit> | --json<br>--yaml<br>--table<br>--fields (value required) |
26
+ | moodle mcp | Deploy and manage a private Moodle MCP server. | | |
27
+ | moodle mcp bridge | Bridge a stdio MCP client to the managed remote server. | | --profile (value required) |
28
+ | moodle mcp connect | Connect a supported MCP client. | [client] | --json<br>--yaml<br>--table<br>--fields (value required)<br>--mode (value required)<br>--show-token |
29
+ | moodle mcp deploy | Deploy or update the managed Moodle MCP server. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--dry-run<br>--repair<br>--rotate-token<br>--rollback |
30
+ | moodle mcp login | Acquire and upload a fresh Moodle session. | | --json<br>--yaml<br>--table<br>--fields (value required) |
31
+ | moodle mcp remove | Remove one managed Moodle MCP deployment. | | --json<br>--yaml<br>--table<br>--fields (value required) |
32
+ | moodle mcp renewal | Run the installed managed-session renewal job. | | |
33
+ | moodle mcp renewal run | Check and renew one managed Moodle session. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--profile (value required) |
34
+ | moodle mcp serve | Run the local Moodle MCP server. | | --stdio |
35
+ | moodle mcp session | Advanced managed-session operations. | | |
36
+ | moodle mcp session push | Upload a Moodle cookie from standard input. | | --stdin<br>--json<br>--yaml<br>--table<br>--fields (value required) |
37
+ | moodle mcp status | Show local and remote Moodle MCP readiness. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--verbose<br>--logs |
38
+ | moodle overview | Show a compact multi-source overview. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--todo-limit (value required)<br>--todo-days (value required)<br>--alerts-limit (value required) |
33
39
  | moodle skills | Show skill metadata or delegate to the shared skills CLI. | | |
34
40
  | moodle skills add | Install the published skill through npx skills add. | | |
35
41
  | moodle skills generate | Regenerate the agent skill bundle from the CLI command tree. | | |
36
- | moodle todo | List upcoming actionable timeline items. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--limit (default: 20; value required)<br>--days (value required) |
37
- | moodle update | Check for updates and upgrade the installed CLI. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--check-only |
42
+ | moodle threads | Inspect forum discussion threads. | | |
43
+ | moodle threads show | Show posts in a forum discussion. | <discussion> | --json<br>--yaml<br>--table<br>--fields (value required)<br>--post (value required)<br>--body |
44
+ | moodle todo | List upcoming actionable timeline items. | | --json<br>--yaml<br>--table<br>--fields (value required)<br>--limit (value required)<br>--days (value required) |
45
+ | moodle units | Inspect enrolled units. | | |
46
+ | moodle units list | List enrolled units. | | --json<br>--yaml<br>--table<br>--fields (value required) |
47
+ | moodle units show | Show unit detail with sections. | <unit> | --json<br>--yaml<br>--table<br>--fields (value required) |
38
48
  | moodle user | Show authenticated user info. | | --json<br>--yaml<br>--table<br>--fields (value required) |
@@ -7,7 +7,7 @@ Read this file for grades or detail about assignments, quizzes, resources, links
7
7
  Use a course ID or unique course name:
8
8
 
9
9
  ```bash
10
- moodle grades COURSE --json
10
+ moodle grades UNIT --json
11
11
  ```
12
12
 
13
13
  Report the course total and requested grade items. Preserve displayed values and percentages; Moodle gradebooks may expose text such as ranges, letters, or incomplete totals.
@@ -18,12 +18,15 @@ Each command accepts a numeric module ID or its full Moodle URL:
18
18
 
19
19
  | Activity | Command |
20
20
  | --- | --- |
21
- | Assignment | `moodle assign ASSIGNMENT --json` |
22
- | Quiz | `moodle quiz QUIZ --json` |
23
- | File/resource | `moodle resource RESOURCE --json` |
24
- | External link | `moodle link LINK --json` |
25
- | Moodle page | `moodle page PAGE --json` |
26
- | Folder | `moodle folder FOLDER --json` |
21
+ All supported activity types share the course-module ID namespace and use one command:
22
+
23
+ ```bash
24
+ moodle activities show ACTIVITY_ID --json
25
+ ```
26
+
27
+ The result includes `type` (`assign`, `quiz`, `resource`, `link`, `page`, or `folder`).
28
+
29
+ Resource and folder details include `file_entries` with a filename, authenticated URL, and authentication requirement. When the user wants local files, continue with [downloads.md](downloads.md) instead of fetching those URLs outside the CLI.
27
30
 
28
31
  When the user supplies a supported Moodle URL without naming a command, route it directly:
29
32
 
@@ -37,6 +40,6 @@ The CLI recognizes course, grade report, forum, assignment, quiz, resource, link
37
40
 
38
41
  1. Use the activity-specific command when the activity type is known.
39
42
  2. Use direct URL routing when the user already supplied a URL and only wants its content.
40
- 3. Return structured links and files from the result instead of scraping prose from the formatted table.
43
+ 3. Return structured links and `file_entries` from the result instead of scraping prose from the formatted table.
41
44
 
42
45
  The branch is complete when the answer identifies the course or module and quotes the grade or activity state returned by Moodle.
@@ -0,0 +1,38 @@
1
+ # Local File Downloads
2
+
3
+ Read this file when the user wants one or more Moodle files saved locally. The canonical command is `moodle download`; `moodle dl` is an optional alias.
4
+
5
+ ## One Resource
6
+
7
+ When the caller has an activity but not a direct file URL, inspect it first:
8
+
9
+ ```bash
10
+ moodle activities show ACTIVITY_ID --json
11
+ ```
12
+
13
+ For one resource, pass its positive course-module ID, same-site resource URL, or same-site `pluginfile.php` URL:
14
+
15
+ ```bash
16
+ moodle download ACTIVITY_ID --dest './Course/Week 03/slides.pdf' --json
17
+ moodle download 'MOODLE_RESOURCE_URL' --dest './Course/Week 03/slides.pdf' --json
18
+ ```
19
+
20
+ `--dest` is the exact downloaded file path. Without it, the CLI writes the upstream filename in the current directory. Existing files are preserved by default.
21
+
22
+ ## Folder Files
23
+
24
+ The CLI does not recursively download a Moodle folder. Inspect the folder, select the relevant `file_entries`, plan each destination, and invoke `moodle download` separately for every chosen URL:
25
+
26
+ ```bash
27
+ moodle activities show FOLDER_ACTIVITY_ID --json
28
+ moodle download 'FILE_ENTRY_URL' --dest './Course/Week 03/chapter-1.pdf' --json
29
+ ```
30
+
31
+ Treat every `file_entries.url` as authenticated Moodle data. Use it only through the CLI and never expose Moodle cookies, sesskeys, or other credentials.
32
+
33
+ ## Replacement and Verification
34
+
35
+ - Preserve an existing destination unless the user explicitly authorized replacement or you independently verified that replacing that exact path is safe.
36
+ - Add `--force` only for that verified replacement. It atomically replaces the completed destination; downloads do not use `--yes`.
37
+ - Keep `-o/--output` separate from `--dest`: output selects where the receipt is written, while destination selects the downloaded file.
38
+ - Validate the receipt fields, confirm `file_path` exists, and verify the saved file is non-empty and not a Moodle login page or unresolved resource wrapper. Command success alone is not proof of valid file content.
@@ -7,7 +7,7 @@ Read this file for forum discovery, title or body search, discussion reading, gr
7
7
  Start with the narrowest high-level command:
8
8
 
9
9
  ```bash
10
- moodle forum find QUERY --json
10
+ moodle forums search QUERY --json
11
11
  ```
12
12
 
13
13
  Refine it with:
@@ -20,12 +20,12 @@ Refine it with:
20
20
  - `--body` only when the winning snippet is insufficient.
21
21
  - `--limit-forums N` and `--limit-discussions N` to bound large-site scans.
22
22
 
23
- Use `moodle forum search QUERY --json` when a larger result set is the goal. `forum find` is the default for one best answer.
23
+ Use `moodle forums search QUERY --json` and narrow with `--limit` when only a few matches are needed.
24
24
 
25
25
  When one request combines search with the full matching post, use one command:
26
26
 
27
27
  ```bash
28
- moodle forum find QUERY --course COURSE --body --json
28
+ moodle forums search QUERY --course UNIT --limit 1 --json
29
29
  ```
30
30
 
31
31
  Reserve `forum discussion` for an existing discussion ID or URL, or for selecting a known post ID.
@@ -34,12 +34,11 @@ Reserve `forum discussion` for an existing discussion ID or URL, or for selectin
34
34
 
35
35
  | Need | Command |
36
36
  | --- | --- |
37
- | List forum activities | `moodle forum forums [QUERY] --json` |
38
- | List discussions in one forum | `moodle forum discussions FORUM_OR_URL --json` |
39
- | Read a discussion | `moodle forum discussion DISCUSSION_OR_URL --json` |
40
- | Read one post | `moodle forum discussion DISCUSSION_OR_URL --post POST_ID --json` |
41
- | Include full bodies in terminal format | `moodle forum discussion DISCUSSION_OR_URL --body --table` |
42
- | Validate discussion rendering | `moodle forum check FORUM_OR_URL --limit 20 --json` |
37
+ | List forum activities | `moodle forums UNIT --json` |
38
+ | List discussions in one forum | `moodle forums show FORUM_OR_URL --json` |
39
+ | Read a discussion | `moodle threads show DISCUSSION_OR_URL --json` |
40
+ | Read one post | `moodle threads show DISCUSSION_OR_URL --post POST_ID --json` |
41
+ | Include full bodies in terminal format | `moodle threads show DISCUSSION_OR_URL --body --table` |
43
42
 
44
43
  Skip discovery when the user already supplied a discussion URL. Use `forum discussions` when they supplied a forum view URL and want nearby threads.
45
44
 
@@ -1,16 +1,16 @@
1
1
  # Maintenance
2
2
 
3
- Read this file for update checks, upgrades, agent-skill installation, or repository skill regeneration.
3
+ Read this file for CLI upgrades or agent-skill installation.
4
4
 
5
5
  ## Update the CLI
6
6
 
7
- Check without changing the installation:
7
+ Check the npm registry without changing the installation:
8
8
 
9
9
  ```bash
10
- moodle update --check-only --json
10
+ npm view moodle-cli version
11
11
  ```
12
12
 
13
- Run `moodle update --table` when the user explicitly wants the installation upgraded. npm installations use `npm install -g moodle-cli@latest`; standalone binaries return the latest GitHub Release URL.
13
+ Upgrade an npm installation with `npm install -g moodle-cli@latest`. Standalone binaries are available from GitHub Releases.
14
14
 
15
15
  If the registry check fails, verify network access and retry before proposing an upgrade command.
16
16
 
@@ -29,15 +29,3 @@ moodle skills add
29
29
  ```
30
30
 
31
31
  Extra arguments are passed to the shared `skills` CLI, for example `moodle skills add --agent codex`.
32
-
33
- ## Regenerate the Skill Bundle
34
-
35
- Inside the `moodle-cli` source repository:
36
-
37
- ```bash
38
- npm run build
39
- npm run skill:generate
40
- git diff -- SKILL.md references agents/openai.yaml
41
- ```
42
-
43
- Regeneration is complete when the root skill, branch references, command reference, output contract, and agent metadata are all current.
@@ -10,17 +10,18 @@ Read this file when choosing an output mode, filtering fields, consuming errors,
10
10
  - When stdout is not a TTY, commands default to JSON unless `--table` is set.
11
11
  - `--fields a,b,c` keeps only listed top-level fields. Arrays apply the field filter to each item.
12
12
  - Invalid `--fields` values are usage errors and list valid fields.
13
- - With JSON output enabled, errors are one JSON line on stderr: `{"error":true,"code":"auth_failed","message":"...","hint":"..."}`.
13
+ - Structured errors use `{ok:false,error:{code,message,hint},exit_code}` on stderr.
14
14
 
15
15
  Exit codes:
16
16
 
17
17
  | Code | Meaning |
18
18
  | --- | --- |
19
19
  | 0 | Success |
20
- | 1 | Unexpected error |
21
- | 2 | Authentication or configuration error |
22
- | 3 | Usage error |
20
+ | 1 | Network, configuration, or unexpected error |
21
+ | 2 | Usage error |
22
+ | 3 | Authentication error |
23
23
  | 4 | Requested course, activity, forum, or discussion was not found |
24
+ | 5 | Moodle rejected a well-formed request |
24
25
 
25
26
  ## Agent Handling
26
27
 
@@ -7,21 +7,21 @@ Read this file for identity, enrolled-course discovery, course sections, or cour
7
7
  | Need | Command |
8
8
  | --- | --- |
9
9
  | Authenticated user and site | `moodle user --json` |
10
- | Enrolled courses | `moodle courses --json` |
11
- | Sections and nested activities | `moodle course COURSE --json` |
12
- | Flat activity list | `moodle activities COURSE --json` |
10
+ | Enrolled units | `moodle units --json` |
11
+ | Sections and nested activities | `moodle units show UNIT --json` |
12
+ | Flat activity list | `moodle activities UNIT --json` |
13
13
 
14
- `COURSE` accepts a numeric course ID or a unique course-name match. When a name could match several courses, run `moodle courses --json`, identify the intended course, and continue with its ID.
14
+ `UNIT` accepts a numeric ID or a unique name match. When a name could match several units, run `moodle units --json`, identify the intended unit, and continue with its ID.
15
15
 
16
16
  ## Agent Steps
17
17
 
18
18
  1. Use `user` only for account or site identity.
19
- 2. Use `courses` for discovery and ID resolution.
19
+ 2. Use `units` for discovery and ID resolution.
20
20
  3. Use `course` when section placement matters; use `activities` when the user wants a flat inventory.
21
21
  4. Use `--fields` only for fields present in the returned objects, for example:
22
22
 
23
23
  ```bash
24
- moodle courses --json --fields id,shortname,fullname
24
+ moodle units --json --fields id,shortname,fullname
25
25
  ```
26
26
 
27
27
  The branch is complete when the requested course or activity facts are tied to an unambiguous course ID.
@@ -60,14 +60,32 @@ moodle auth keepalive --json # renew once (re-login from browser/okta
60
60
  moodle auth keepalive install # macOS launch agent, renews every 30 min
61
61
  moodle auth keepalive install --interval 15
62
62
  moodle auth keepalive uninstall
63
- moodle auth login --json # force a fresh login and refresh the cache
63
+ moodle auth login --json # extract a session; open the browser if needed
64
64
  ```
65
65
 
66
66
  On Linux, schedule `moodle auth keepalive --json` with cron instead of `install`.
67
67
 
68
+ `moodle auth login` first checks local session sources. If none is valid, it opens Moodle's login page in the system browser and waits up to two minutes for the completed SSO/OAuth login.
69
+
68
70
  ## Recover Failures
69
71
 
70
72
  - **No usable MoodleSession**: sign in to Moodle in a supported browser and retry; otherwise configure `okta-auth-cli` or provide `MOODLE_SESSION` through the environment.
71
73
  - **Configured site is wrong**: correct `MOODLE_BASE_URL` or the saved `base_url`, then rerun `moodle user --json`.
72
74
  - **Cached session expired**: run `moodle auth login`, or rerun with `--no-cache` once so the CLI reacquires a session.
73
75
  - **Non-interactive config error**: set `MOODLE_BASE_URL`; a pipe cannot answer the first-run prompt.
76
+
77
+ ## Manage the Private MCP Server
78
+
79
+ Use the lifecycle commands instead of asking the user to copy cookies, tokens, Wrangler commands, or client configuration:
80
+
81
+ ```bash
82
+ moodle mcp deploy
83
+ moodle mcp status --json
84
+ moodle mcp login
85
+ moodle mcp connect
86
+ moodle mcp remove
87
+ ```
88
+
89
+ `moodle mcp deploy` validates the local Moodle session, deploys and verifies a private Cloudflare Worker, installs local renewal, and connects detected clients. The default bridge mode keeps the Bearer token out of client files. Use `moodle mcp login` when status reports `SESSION_EXPIRED`; use `moodle mcp deploy --repair` when Cloudflare authorization or managed deployment state needs repair.
90
+
91
+ Never print or request the raw Moodle cookie, MCP access token, session sync token, or sesskey. An advanced operator may pipe a cookie directly to `moodle mcp session push --stdin`; do not place it in arguments or shell history.