A complete end-to-end guide for connecting Claude Desktop and Claude Code to your university Moodle — including a workaround for schools that use Microsoft/Google SSO login, where the standard token method doesn't work.
Built on top of moodle-mcp by @1alexandrer. All credit for the MCP server goes to them — this repo documents the full setup process and the SSO token workaround that isn't in the original README.
- "What assignments do I have due this week?"
- "Summarise my Derivatives course"
- "What are my grades so far?"
- "Build me a linked Obsidian study vault from all my course notes"
Claude gets live access to your courses, assignments, grades, deadlines, and files — all through natural conversation.
- Prerequisites
- Step 1 — Get your Moodle token
- Step 2 — Install moodle-mcp
- Step 3 — Configure Claude Desktop
- Step 4 — Verify the connection
- Step 5 — Use with Claude Code
- Bonus — Build an Obsidian study vault
- Troubleshooting
- Tested on
| Requirement | Check |
|---|---|
| Claude Desktop | Installed and logged in |
| Node.js (LTS) | node --version → should return a version number |
| University Moodle account | Any school running Moodle 4.x |
Navigate to this URL while logged into Moodle in your browser:
https://moodle.yourschool.edu/user/managetoken.php
Copy the Moodle mobile web service token and skip to Step 2.
If your school uses SSO, the token page only shows an RSS token — not the one you need. The Moodle app "tap the version number 5 times" trick also no longer works on newer app versions.
Here's the method that actually works:
1. Log into Moodle in Safari on your Mac (must be Safari, not Chrome/Firefox).
2. Open this URL — swap in your school's Moodle domain:
https://moodle.yourschool.edu/admin/tool/mobile/launch.php?service=moodle_mobile_app&passport=12345&urlscheme=moodlemobile
3. Safari will try (and fail) to open a moodlemobile:// URL. A blank "Untitled" tab will appear. Click the address bar of that tab — it shows a long URL starting with moodlemobile://token=...
4. Select all (Cmd+A) and copy the full URL.
5. Extract the base64 string — it's everything after token=, including the trailing ==.
6. Decode it in Terminal:
echo "YOUR_BASE64_STRING==" | base64 --decodeThe output is colon-separated. Depending on your Moodle version it has two or three fields:
# two-field format (older Moodle):
<signature>:::<token>
# three-field format (newer Moodle — this is what City St George's returns):
<signature>:::<token>:::<privatetoken>
Your web service token is the middle field — the value between the first and second
:::.
- The first field is a passport signature, not a token.
- The optional third field is a "private token" used only for the Moodle mobile app's auto-login — you don't need it here.
⚠️ Don't just copy "everything after:::". If you get three fields there are two separators, and the last field is the wrong one. Take the field in the middle.
7. Verify the token works:
curl "https://moodle.yourschool.edu/webservice/rest/server.php?wstoken=YOUR_TOKEN&wsfunction=core_webservice_get_site_info&moodlewsrestformat=json"A successful response returns your name, username, and site info as JSON. If you see that, your token is valid.
🔒 Treat this token like a password. It grants full access to your Moodle account — your courses, grades, personal details, and messages. Anyone who has it can act as you.
- Never commit it to a public repo, paste it into a chat, or share a screenshot of it.
- If it's ever exposed, generate a fresh one by repeating the SSO steps above — doing so invalidates the previous token.
- The
your_token_hereplaceholders in the config examples below are intentional. Put your real token only in your local config files, never anywhere public.
Install the package globally so Claude Desktop can find it without needing to fetch it on every start:
npm install -g moodle-mcpThen grab the two paths you'll need in the next step — the absolute path to node, and the absolute path to the server script:
which node
# e.g. /opt/anaconda3/bin/node
echo "$(npm root -g)/moodle-mcp/dist/server.js"
# e.g. /opt/anaconda3/lib/node_modules/moodle-mcp/dist/server.jsWhy not just point Claude at
moodle-mcpdirectly? Themoodle-mcpcommand is a small wrapper whose first line is#!/usr/bin/env node— meaning "findnodeon the PATH." Claude Desktop launches MCP servers with a minimal PATH that often does not include your Node install directory (very common with Anaconda/nvm). When that happens the wrapper can't findnode, exits instantly, and Claude reports "Server disconnected." Pointing the config straight at thenodebinary with the script as an argument sidesteps the PATH lookup entirely and is far more robust. See Troubleshooting.
Open the Claude Desktop config file:
open -e ~/Library/Application\ Support/Claude/claude_desktop_config.jsonMerge in the mcpServers block below. Set command to your absolute node path and put the server.js path in args — use the two values you got from Step 2. Do not write moodle-mcp, npx, or a bare node:
{
"mcpServers": {
"moodle": {
"command": "/opt/anaconda3/bin/node",
"args": [
"/opt/anaconda3/lib/node_modules/moodle-mcp/dist/server.js"
],
"env": {
"MOODLE_URL": "https://moodle.yourschool.edu",
"MOODLE_TOKEN": "your_token_here"
}
}
}
}Older guides (and the original README) tell you to set
commandto themoodle-mcpwrapper directly. That works only if Claude Desktop happens to seenodeon its PATH — which frequently it doesn't. The node +server.jsform above is the reliable version and is what fixed a stubborn "Server disconnected" loop on a fresh install. If you'd rather try the shorter form first, it's"command": "/opt/anaconda3/bin/moodle-mcp", "args": []— just switch to the form above the moment you see "Server disconnected."
Save the file (Cmd+S), then fully quit Claude Desktop (Cmd+Q, not just closing the window) and reopen it.
In a new Claude Desktop chat, click the + button in the input box → Connectors → confirm Moodle shows a blue toggle.
Test it by asking: "What courses am I enrolled in?"
To use the same Moodle tools inside the Claude Code CLI, run this once (same node + server.js form as Step 3):
claude mcp add moodle /opt/anaconda3/bin/node \
"$(npm root -g)/moodle-mcp/dist/server.js" \
-e MOODLE_URL=https://moodle.yourschool.edu \
-e MOODLE_TOKEN=your_token_hereRestart Claude Code for the change to take effect.
With Claude Code running locally, you can pull all your course materials and have them written as a fully linked Obsidian vault directly to your machine:
Pull all my Moodle courses and build a linked Obsidian vault at
/Users/yourname/Desktop/Study Notes — one note per topic with [[wikilinks]]
between related concepts, a MOC.md index, and tags for each section.
Important: Use Claude Code (not Claude Desktop chat) for this. Claude Desktop runs in a sandbox and cannot write to your local filesystem. Claude Code runs natively on your machine and writes files directly.
"Server disconnected" in Claude Desktop (the most common issue)
This almost always means the server process crashed on launch — not a token problem. The usual cause: Claude Desktop launches MCP servers with a minimal PATH, and the moodle-mcp wrapper's shebang (#!/usr/bin/env node) can't find node on it, so it exits before it can even talk to Moodle.
The fix is the config form in Step 3: set command to your absolute node path and pass .../moodle-mcp/dist/server.js in args. This skips the PATH lookup entirely.
To confirm this is what's happening, run the wrapper under a stripped-down PATH — if you see env: node: No such file or directory, that's it:
env -i PATH="/usr/bin:/bin" $(which moodle-mcp) </dev/nullThen verify the node + script form starts cleanly (it should sit and wait for input rather than exit):
env -i PATH="/usr/bin:/bin" $(which node) "$(npm root -g)/moodle-mcp/dist/server.js"
# Press Ctrl+C to stop — no error output means it's healthy.The View Logs button under the server entry in Claude Desktop's MCP settings shows the exact error if you need to dig deeper.
Tip: If the token is genuinely expired you'll see
invalidtokenin the logs (not "Server disconnected") — regenerate it via Step 1. SSO Moodle tokens expire periodically, so this is normal maintenance, not a broken setup.
Token page only shows RSS token
Your school's mobile web service token isn't exposed on the standard token page. Use the SSO method above to extract it via the browser redirect.
fetch failed error in MCP logs
This usually means the token is being rejected. Verify it with the curl command in Step 1 before adding it to the config.
Hammer/tools icon not showing in Claude Desktop
It's hidden behind the + button in the input box → click Connectors.
| School | City St George's, University of London (moodle4.city.ac.uk) |
| Login | Microsoft SSO |
| OS | macOS (Apple Silicon) |
| Moodle version | 4.5.8 (Build 20251208) |
| moodle-mcp version | 0.2.0 |
| Node.js version | v22.6.0 |
All credit for the MCP server goes to @1alexandrer — github.com/1alexandrer/moodle-mcp.
This guide documents the full end-to-end setup and the SSO workaround discovered while setting it up at City St George's, University of London.