ekursy-mcp-py
An invite-only, GitHub-OAuth MCP server for accessing a student's eKursy/Moodle data via scoped tools.
Fetch the authenticated student's profile and USOS number.
List all enrolled courses.
Retrieve course sections, presentations, lecturer names, assignments, and files.
Fetch a course's hierarchical gradebook.
Download and parse internal university files such as PDFs and images.
Resolve/download internal university proxy links and page fragments, including PDFs, images, and URLs.
Map each GitHub identity to separately encrypted Moodle credentials without exposing the university password in OAuth tokens or tool calls.
Provides tools for accessing student profile information, course lists, course grades, page contents, and course materials (PDF/images) from the eKursy (Moodle-based) platform.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ekursy-mcp-py show my grades for this semester"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
eKursy MCP Server
A remote Model Context Protocol server that exposes a student's eKursy profile,
courses, grades, deadlines, forums, and course materials. It uses FastMCP over
Streamable HTTP, the bundled ekursy-zero Rust service, and invite-only GitHub
OAuth.
Each GitHub identity maps to its own Moodle credentials in SQLite. Credential fields are encrypted with Fernet authenticated encryption before being written to disk. OAuth tokens and MCP tool calls never contain the university password.
Production endpoint
The production MCP URL is:
https://mk.uni.markrz0.dev/mcpOAuth discovery and callback routes are served on the same origin. The Docker
port is bound only to 127.0.0.1; nginx is the public TLS endpoint.
Related MCP server: geo-explorer-mcp
Production prerequisites
Create a GitHub OAuth app at https://github.com/settings/developers.
Set its homepage URL to
https://mk.uni.markrz0.dev.Set its authorization callback URL to
https://mk.uni.markrz0.dev/auth/callback.Copy
.env.exampleto.env, fill the GitHub client ID/secret, and independently generate bothOAUTH_JWT_SIGNING_KEYandCREDENTIAL_ENCRYPTION_KEYwithopenssl rand -hex 32.Keep
.envmode600on the server.
OAUTH_ALLOWED_GITHUB_USERS is only a bootstrap list. On that user's next
authenticated request, the server records their immutable numeric GitHub ID
with no Moodle credentials. New users must be invited with the admin command
below.
Never rotate CREDENTIAL_ENCRYPTION_KEY while the SQLite database contains
credentials. Losing it makes those credential records unrecoverable.
Deploy
git submodule update --init --recursive
docker compose up --build -d
docker compose ps
docker compose logs --tail=100 ekursy-mcpThe SQLite account database and OAuth state use a named Docker volume, so they survive container recreation and are not stored in the Git checkout.
To install nginx and obtain the certificate on Ubuntu, copy
deploy/install-nginx.sh to the VPS and run:
sudo bash ~/install-ekursy-nginx.sh you@example.comThe script validates nginx before every reload and lets Certbot add the TLS and HTTP-to-HTTPS configuration.
On the prepared VPS deployment, enter the GitHub OAuth credentials without putting the secret in shell history, start the containers, and then install TLS:
bash ~/finish-ekursy-deploy.sh
sudo bash ~/install-ekursy-nginx.sh you@example.comConnect from ChatGPT
Add a custom MCP server/plugin with the server URL
https://mk.uni.markrz0.dev/mcp and OAuth authentication. Complete the GitHub
authorization as an invited account. Then install the resulting plugin and use
it from the conversation in which you create the scheduled task.
The first account listed in OAUTH_ALLOWED_GITHUB_USERS is bootstrapped on its
next request. Ask the connector to run create_account_setup_link, open the
returned browser link, and enter your Moodle credentials there.
Add a friend
Invite their GitHub account from the VPS. The command resolves the login to GitHub's immutable numeric user ID before storing it:
cd /home/saell/ekursy-mcp
docker compose exec ekursy-mcp /app/.venv/bin/python src/admin.py invite THEIR_GITHUB_LOGIN
docker compose exec ekursy-mcp /app/.venv/bin/python src/admin.py listYour friend then adds https://mk.uni.markrz0.dev/mcp in ChatGPT and completes
GitHub OAuth. In ChatGPT they ask the connector to run
create_account_setup_link, open the returned short-lived one-time link in a
browser, and enter their own Moodle credentials. The server validates and
encrypts them directly; they do not pass through ChatGPT.
Disable or re-enable access without deleting the encrypted record:
docker compose exec ekursy-mcp /app/.venv/bin/python src/admin.py disable THEIR_GITHUB_LOGIN
docker compose exec ekursy-mcp /app/.venv/bin/python src/admin.py enable THEIR_GITHUB_LOGINEach Moodle login has an isolated server-side session. Tool calls resolve the authenticated GitHub ID to exactly one database record before accessing Moodle.
The exact availability of custom MCP servers and scheduled tasks depends on your ChatGPT plan and workspace policy.
Local development
Initialize the scraper submodule, copy .env.example to .env, configure the
OAuth settings, and install dependencies with uv:
git submodule update --init --recursive
uv sync --frozen
docker compose up --buildRun tests with:
python -m unittest discover -s tests -vAvailable Tools
6 toolsget_course_contentB
Get the detailed page fragments and sections for a specific course (including presentations, lecturer names, assignments, and other files).
Inputs: id (required). Returns: result
get_course_gradesB
Fetch the hierarchical gradebook for a specific course.
Inputs: id (required). Returns: result
get_user_profileA
Fetch the authenticated student's profile information and USOS number.
Inputs: no named parameters. Returns: result
list_coursesA
Get a list of all courses the student is enrolled in.
Inputs: no named parameters. Returns: result
resolve_material_linkC
Download and parse internal university files (PDFs, Images) - resource.
Inputs: resourceId (required), kind (required).
resolve_proxyC
Download and parse internal university proxies (PDFs, Images, URLs etc).
Inputs: proxyPath (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 6 tools
Most tools are clearly distinct, but resolve_material_link and resolve_proxy have overlapping purposes (both download and parse internal files), which could cause minor confusion. Descriptions help distinguish them as one is for general materials and the other for proxies.
All tools follow a consistent verb_noun pattern with snake_case (e.g., get_course_content, list_courses, resolve_proxy). Verbs are appropriate and nouns are descriptive, making the naming predictable.
Six tools is a well-scoped number for a university course management MCP server. Each tool serves a distinct purpose without unnecessary duplication, covering essential student operations.
The tool set covers core functionalities: course listing, content retrieval, grades, profile, and file downloads. Minor gaps exist (e.g., no assignment submission or mailbox tool), but the provided tools form a coherent and practical surface for accessing course information.
Maintenance
Related MCP Connectors
Open-source AI courses taught by your AI tutor in conversation, with progress saved by MCP tools.
Your memory, everywhere AI goes. Build knowledge once, access it via MCP anywhere.
Read-only access to Epivo's live course catalogue for AI agents.
iSpring Learn (iSpring LMS) MCP server for ChatGPT, Claude and any AI agent: enroll users in courses, list enrollments, get learner progress report, cancel enrollment, reset enrollment progress, add users by email, deactivate users and list courses in your own iSpring Learn (iSpring LMS) account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to iSpring Learn (iSpring LMS) yourself; Cotlet does not store your password and you need no iSpring Learn (iSpring LMS) API key. About the official iSpring Learn (iSpring LMS) API: iSpring Learn has a REST API, but only with the Business subscription, and no official MCP server (checked 20 Oct 2026). The API covers users, departments, courses, enrollments and results, so an agent needs custom code and a token; the Zapier app covers users, departments and enrollments but has no progress or report actions. Setup and FAQ: https://cotlet.dev/integrations/ispring-api-mcp-server
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceConnects Moodle LMS with AI assistants through the Model Context Protocol, enabling users to interact with Moodle data via a conversational chatbot interface.13 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to list learning tracks, retrieve study plans, generate coding challenges, and issue fictional completion certificates through the Model Context Protocol.MIT
- AlicenseAqualityBmaintenanceGives Claude, Codex, Cursor and any other MCP client read access to your courses, content, files, grades, deadlines, announcements and discussions, using your own browser session.3139 npm5MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to access and manage academic course information, assignments, submissions, grades, calendars, materials, recordings, and announcements through authenticated LMS sessions.MIT