Ninova MCP
Click on "Install 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., "@Ninova MCPshow my upcoming deadlines"
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.
Ninova MCP
Ninova MCP is a credential-based Model Context Protocol server for ITU Ninova. It lets MCP-compatible AI clients such as Claude, OpenClaw, Cursor, and Codex read your own Ninova courses, announcements, files, assignments, grades, message boards, attendance, and deadlines.
It logs in with NINOVA_USERNAME and NINOVA_PASSWORD, opens its own temporary Ninova session, and exposes tools for:
reading the dashboard
listing courses
resolving a course by code, title, path, or URL
listing a course's direct Ninova sections/routes
getting a course's announcements
getting a course's class files
getting a course's lesson files
getting a course's assignments with detail pages
getting a course's class information
getting a course's grades
getting a course's message board topics and threads
getting a course's attendance
getting a course's remote learning page
building a combined course overview
getting dashboard announcements
getting dashboard assignments with detail pages
reading any Ninova page
crawling a course tree
downloading files
snapshotting pages
comparing snapshots to track changes
syncing all courses into a local tracking state
listing detected updates
listing upcoming deadlines
It does not read Chrome cookies or reuse browser profiles.
Easiest install: paste this prompt to your AI assistant
Copy the block below into ChatGPT, Claude, Cursor, Codex, or any chat AI. It will install the server and configure your MCP client end-to-end.
Install the ninova-mcp MCP server (PyPI: ninova-mcp, https://github.com/hikmedit/ninova-mcp).
1. Install from PyPI. Prefer `pipx install ninova-mcp`. If pipx is not
available, `pip install --user ninova-mcp` is fine — both put a
`ninova-mcp` command on my PATH.
2. Add a `ninova` server to my MCP client's config — command `ninova-mcp`,
env `NINOVA_USERNAME` and `NINOVA_PASSWORD`. Detect which client I use
and write the config in the right place. Merge into existing
`mcpServers`; do not overwrite other servers. Do NOT ask me for
credentials — leave the values as placeholders, unless I already
pasted real credentials in this chat.
3. Tell me to fill in NINOVA_USERNAME and NINOVA_PASSWORD if I haven't,
then restart the client and call the `auth_status` tool to verify.Related MCP server: waterloo-learn-mcp
Manual install
You need Python 3.11+.
Step 1: Install the server
pipx install ninova-mcpThis puts a ninova-mcp command on your PATH. (Alternatives: uv tool install ninova-mcp or pip install --user ninova-mcp.)
Step 2: Tell your MCP client about it
Open your client's MCP config file (paths below) and add the ninova entry. If mcpServers already exists, merge — do not replace it.
Claude Desktop
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"ninova": {
"command": "ninova-mcp",
"env": {
"NINOVA_USERNAME": "your_itu_username",
"NINOVA_PASSWORD": "your_itu_password"
}
}
}
}Claude Code — one shell command, no manual editing:
claude mcp add ninova ninova-mcp -e NINOVA_USERNAME=your_itu_username -e NINOVA_PASSWORD=your_itu_passwordCursor — .cursor/mcp.json (per project) or ~/.cursor/mcp.json (global). Use the same JSON block as Claude Desktop.
Codex CLI — ~/.codex/config.toml:
[mcp_servers.ninova]
command = "ninova-mcp"
[mcp_servers.ninova.env]
NINOVA_USERNAME = "your_itu_username"
NINOVA_PASSWORD = "your_itu_password"Step 3: Restart the client and try it
Restart your MCP client. Ask the model to call auth_status. It should report that credentials are present and a Ninova session works.
Supported priority clients: Claude Desktop / Claude Code, Cursor, Codex CLI, OpenClaw.
See also: Installation guide · Security notes · Example configs
Security Notice
This project uses credentials that you provide locally. Never commit .env, downloads, course files, submissions, screenshots, or tracking state. Prefer local stdio MCP. If you deploy the remote HTTP server for Claude.ai custom connectors, use HTTPS and a long random private MCP path.
Request Model
Ninova appears to be classic ASP.NET WebForms. In practice this server now prefers request-level access to Ninova's own routes such as:
/Sinif/<id>.<id>/Notlar/Sinif/<id>.<id>/MesajPanosu/Sinif/<id>.<id>/Yoklama/Sinif/<id>.<id>/UzaktanEgitim
For interactive actions Ninova uses same-page form POST requests with __VIEWSTATE, __EVENTTARGET, and related WebForms fields rather than a clean public JSON API.
Requirements
Python 3.11+
requestsbeautifulsoup4lxmlmcpuvicornOptional:
playwrightfor login fallback when the form flow changes
Configuration
Only two variables are required:
NINOVA_USERNAME=your_username
NINOVA_PASSWORD=your_passwordThe server reads them from the process environment. If a .env file exists in the current working directory (or any parent), NINOVA_* variables are loaded from it without overriding variables already set in the environment.
Advanced (optional)
These are not needed for normal local use. Set them only if you need to override defaults or run the remote HTTP transport.
Local overrides:
export NINOVA_BASE_URL="https://ninova.itu.edu.tr" # default
export NINOVA_STATE_DIR="/absolute/path/to/.ninova_state"
export NINOVA_DISABLE_PLAYWRIGHT_FALLBACK="1"
export NINOVA_ENV_FILE="/absolute/path/to/.env"Remote HTTP server (only for self-hosted Claude.ai custom connectors):
export NINOVA_REMOTE_HOST="0.0.0.0"
export NINOVA_REMOTE_PORT="8000"
export NINOVA_REMOTE_MCP_PATH="/mcp-choose-a-long-random-secret"
export NINOVA_PUBLIC_BASE_URL="https://your-public-domain.example.com"
export NINOVA_ALLOWED_HOSTS="your-public-domain.example.com"
export NINOVA_ALLOWED_ORIGINS="https://claude.ai,https://claude.com"Run
After installing the package:
ninova-mcpThis starts the stdio MCP server. It is normal for it to wait silently because your MCP client talks to it over stdin/stdout.
To run from a source checkout without installing:
PYTHONPATH=src python3 -m ninova_mcpRun Remote HTTP Server
To expose the server for Claude Cowork / Claude.ai, run the remote Streamable HTTP transport:
ninova-mcp-remoteBy default this starts an HTTP server on 0.0.0.0:8000.
Useful endpoints:
GET /healthz: health checkPOST/GET <NINOVA_REMOTE_MCP_PATH>: MCP endpoint for remote connectors
Example:
export NINOVA_REMOTE_MCP_PATH="/mcp-6f8f94c5b6bb4b8f8f6d2f8b20f28e9f"
export NINOVA_PUBLIC_BASE_URL="https://ninova-mcp.example.com"
export NINOVA_ALLOWED_HOSTS="ninova-mcp.example.com"
export NINOVA_ALLOWED_ORIGINS="https://claude.ai,https://claude.com"
ninova-mcp-remoteThen your connector URL is:
https://ninova-mcp.example.com/mcp-6f8f94c5b6bb4b8f8f6d2f8b20f28e9fThis server currently uses an authless remote MCP setup, so for personal use you should choose a long random NINOVA_REMOTE_MCP_PATH and keep the full URL private. OAuth is not implemented yet.
Docker
Build and run:
docker build -t ninova-mcp .
docker run --rm -p 8000:8000 \
-e NINOVA_USERNAME="your_username" \
-e NINOVA_PASSWORD="your_password" \
-e NINOVA_REMOTE_MCP_PATH="/mcp-choose-a-long-random-secret" \
-e NINOVA_PUBLIC_BASE_URL="https://your-public-domain.example.com" \
-e NINOVA_ALLOWED_HOSTS="your-public-domain.example.com" \
ninova-mcpClaude Cowork / Claude.ai
Anthropic's remote MCP support requires a publicly reachable HTTP server; local stdio servers are not available in Cowork.
To use this connector in Claude Cowork:
Deploy this repo to a public host.
Set
NINOVA_USERNAME,NINOVA_PASSWORD,NINOVA_REMOTE_MCP_PATH,NINOVA_PUBLIC_BASE_URL, andNINOVA_ALLOWED_HOSTS.Confirm
https://your-domain/healthzreturns200.In Claude, add a custom connector and paste the full remote MCP URL:
https://your-domain<your-random-mcp-path>Enable the tools you want to expose.
Anthropic references:
Remote connectors overview: Anthropic Help
Remote MCP transport support: Anthropic Help
Streamable HTTP requirement: Anthropic MCP connector docs
Example MCP Config
After pipx install ninova-mcp, the minimal local stdio entry is:
{
"mcpServers": {
"ninova": {
"command": "ninova-mcp",
"env": {
"NINOVA_USERNAME": "your_username",
"NINOVA_PASSWORD": "your_password"
}
}
}
}Exposed Tools
auth_status: Check whether credentials exist and whether a fresh Ninova session can be created.refresh_session: Force a new login with the configured credentials.get_dashboard: Read/Kampus1and return dashboard sections, recent items, and course list.list_courses: Return the discovered courses from the dashboard.get_courses: Alias forlist_courses.get_course_announcements: Return announcements for a given course. Accepts course code, title, path, or full URL.get_course_class_files: Return structured entries fromSınıf Dosyaları, optionally recursively.get_course_lesson_files: Return structured entries fromDers Dosyaları, optionally recursively.get_course_assignments: Return assignments for a course and fetch each assignment's detail page.get_course_info: Return structured data fromSınıf Bilgileri.get_course_sections: Return the course routes exposed on the course home page.get_course_grades: Return structured data fromNotlar.get_course_message_board: Return structured topics fromMesaj Panosu, optionally with thread details.get_course_attendance: Return structured data fromYoklama.get_course_remote_learning: Return structured data fromUzaktan Eğitim.get_course_overview: Return a combined live or tracked overview of a course.get_dashboard_announcements: Return the announcements listed in/Kampus?1/Duyurular.get_dashboard_assignments: Return the assignments listed in/Kampus?1/Odevlerand fetch each detail page.sync_all_courses: Save a local snapshot for every visible course and detect changes since the previous sync.get_updates: Return recently detected changes from the local tracking state.get_upcoming_deadlines: Return upcoming assignment deadlines from the local tracking state.read_page: Read and structure any Ninova HTML page.crawl_course: Inventory internal pages and downloadable resources inside a course.download_resource: Download a file or page response to disk.snapshot_page: Save a structured snapshot of a page for later tracking.diff_snapshot: Compare the current page against a stored snapshot.
Notes
Sessions are created by normal login flow and held in process memory.
The server automatically retries once with a fresh login if a session expires.
Downloaded files are stored inside the requested output directory. The default is
~/.ninova_state/downloads.Snapshots are stored under
~/.ninova_state/snapshotsunlessNINOVA_STATE_DIRis set.Course tracking state is stored under
~/.ninova_state/tracking-state.jsonunlessNINOVA_STATE_DIRis set.The remote HTTP entrypoint is implemented with the official Python MCP SDK's Streamable HTTP server support.
Tests
PYTHONPATH=src python3 -m unittest discover -s tests -vThis server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/hikmedit/ninova-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server