About Neptun API
Neptun API is an MCP server published by IdrissaMaiga in the Documentation category: the most complete Python wrapper for the Hungarian Neptun university system API.
The repository has 3 stars and 0 forks, with the last commit a month ago. Recent commit activity is the strongest signal that reported issues will get attention.
Install
git clone https://github.com/IdrissaMaiga/neptun-apiThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Tools (9)
*...and more*Curriculum, documents, surveys
Parameters not published.
get_all_gradesGrade for every subject across all terms (full transcript)
Parameters not published.
get_calendar_eventsCalendar events by date range
Parameters not published.
get_dashboard_dataGPA, credit progress, unread messages
Parameters not published.
get_exams_listAvailable exams for a subject in a term
Parameters not published.
get_student_infoStudent profile, neptun code, training
Parameters not published.
get_subject_gradeResult/grade for one subject by ID
Parameters not published.
get_taken_subjectsSubjects taken in a term
Parameters not published.
get_term_averagesGPA and credit index per semester
Parameters not published.
Ask AI
Ask AI about Neptun API
Powered by Claude · Grounded in docs
Security checks
Static checks derived from the repository 4 days ago. Heuristics on the source, not an audit.
- ✓README presentThe repository ships documentation.
- ✓License declaredUsable under a stated license.
- ✓Tests presentA test suite exists in the repository.
- !Dependencies pinnedNo lockfile. Installs can pull different code over time.
- ✓No dynamic code executionSource scan found no eval, dynamic Function, or shell execution.
1 check has not been run yet.
Releases
README
neptun-api
The most complete Python API wrapper for the Hungarian Neptun university system. Reverse-engineered from the Angular web client, covering 1,100+ endpoints across 75+ controllers.
Built and tested against Obuda University, but should work with any Neptun instance by changing the base URL. Instances that require two-factor login (e.g. University of Debrecen) are supported, see Two-factor authentication.
Installation
pip install -e . # core API wrapper
pip install -e ".[survey]" # + automated survey filler
pip install -e ".[all]" # + survey + dev/test tools
For survey auto-fill, also run after install:
python -m playwright install chromium
Requirements: Python 3.11+, requests
Quick Start
from neptun_api import NeptunAPI
api = NeptunAPI("YOUR_NEPTUN_CODE", "YOUR_PASSWORD",
base_url="https://neptun.uni-obuda.hu/ujhallgato/api/")
api.authenticate()
# Get your GPA
averages = api.get_term_averages()
for term in averages["termAveragesByTrainings"]:
print(f'{term["average"]} avg, {term["creditIndex"]} credit index')
# Get the grade for every subject across all terms (full transcript).
# This is the reliable way to read grades — including midterm marks and
# transfer/recognised grades — which get_subject_results_list does not return
# on many instances. (get_subject_result / get_subject_results_list are kept
# only as raw endpoint wrappers; prefer these.)
for g in api.get_all_grades():
print(f'{g["term"]} [{g["subjectCode"]}] {g["subjectName"]}: {g["grade"]} ({g["gradeName"]})')
# Or one subject's result by its subject id
result = api.get_subject_grade(subject_id) # {"resultValue": 4, "resultName": "Jó", "passed": True}
# Get current courses
terms = api.get_taken_subjects_terms()
subjects = api.get_taken_subjects(terms[1]["value"]) # [1] skips "0. felev"
for s in subjects:
print(f'[{s["subjectCode"]}] {s["subjectName"]} - {s["subjectCredit"]} credits')
# Get unread messages
count = api.get_unread_message_count()
messages = api.get_received_messages(0, 20)
# Calendar
from datetime import datetime
events = api.get_calendar_events(datetime(2025, 9, 1), datetime(2026, 1, 31))
# Finances
impositions = api.get_financial_impositions()
# Auto-fill all pending semester surveys (rating 1-5)
from neptun_api import fill_all_surveys
results = fill_all_surveys(api, rating=5)
What's Covered
| Area | Methods | Examples |
|---|---|---|
| Dashboard | 6 | GPA, credit progress, exam entries |
| Messages | 18+ | Inbox, sent, deleted, compose, recipients |
| Calendar | 29 | Events, export, subscriptions, filters |
| Subjects & Courses | 60+ | Taken subjects, registration, course changes |
| Exams | 30+ | Registration, results, remaining exams |
| Grades & Advancement | 21 | Term averages, credit index, curriculum progress |
| Financial | 50+ | Impositions, payments, invoices, scholarships |
| Personal Data | 113 | Addresses, emails, phones, documents, language exams |
| Documents | 49 | Upload, download, containers, folders |
| Timetable & Rooms | 38+ | Room schedule, booking, institutional timetable |
| Curriculum | 12 | Templates, subject groups, completable subjects |
| Request Forms | 62 | Submit, track, attachments, judgements |
| Student Card | 12 | Claims, address, status |
| Tasks | 28 | Assignments, documentation, deadlines |
| Questionnaires | 17 + auto-fill | List, fill out via browser automation, view results |
| Consultation | 12 | Appointments, sign up, drop |
| E-Materials | 28 | Course materials, downloads |
| Online Occasions | 24 | Virtual classes, Webex/Teams links |
| Thesis | 46+ | Application, upload, published theses |
| Practice | 26 | External practice, documentation |
| Erasmus | 15 | Applications, learning contracts |
| Dormitory | 16 | Registration, periods, applications |
| Final Exams | 15 | Periods, topics, applications |
| MeetStreet | 70+ | Forums, news, events, votes, e-learning |
| Bank Account | 17 | Manage payment accounts |
| Publications | 18 | Academic publications |
| User Profile | 29 | Settings, avatars, onboarding |
| And more... | Specializations, modules, registry sheets, legal remedies |
Total: 1,100+ methods
Auto-Fill Semester Surveys
Neptun's end-of-semester opinion surveys (Unipoll) can be filled automatically using browser automation. The filler handles both English and Hungarian survey interfaces.
from neptun_api import NeptunAPI, fill_all_surveys
api = NeptunAPI("code", "password", base_url="https://neptun.uni-obuda.hu/ujhallgato/api/")
api.authenticate()
# Fill all pending surveys with 5/5 rating
results = fill_all_surveys(api, rating=5)
# Custom rating (1-5) and optional text comment
results = fill_all_surveys(api, rating=4, text_answer="Great course!")
# Dry run — fills forms but doesn't submit
results = fill_all_surveys(api, rating=5, dry_run=True)
# Show browser window (useful for debugging)
results = fill_all_surveys(api, rating=5, headless=False)
Each result dict contains subject, course, and status ("submitted", "failed", or "error").
Requires:
pip install playwright && python -m playwright install chromium
MCP Server
Run Neptun as an MCP server so any MCP-compatible AI (Claude Desktop, Claude Code, Cursor, etc.) can access your university data.
Stdio (local — Claude Desktop / Claude Code):
pip install -e ".[mcp]"
python -m neptun_api --username YOUR_CODE --password YOUR_PASS
SSE (remote / port-forwarded):
python -m neptun_api --username YOUR_CODE --password YOUR_PASS --transport sse --port 8000
Streamable HTTP:
python -m neptun_api --username YOUR_CODE --password YOUR_PASS --transport streamable-http --port 8000
Or use environment variables:
export NEPTUN_USERNAME=YOUR_CODE
export NEPTUN_PASSWORD=YOUR_PASS
export NEPTUN_BASE_URL=https://neptun.uni-obuda.hu/ujhallgato/api/
export NEPTUN_TOTP_SECRET=BASE32SECRET # only for two-factor instances (see below)
python -m neptun_api --transport sse --port 8000
Claude Desktop config
Add to claude_desktop_config.json:
{
"mcpServers": {
"neptun": {
"command": "python",
"args": ["-m", "neptun_api"],
"env": {
"NEPTUN_USERNAME": "YOUR_CODE",
"NEPTUN_PASSWORD": "YOUR_PASS"
}
}
}
}
There is also an installed console command equivalent to python -m neptun_api:
neptun-mcp --username YOUR_CODE --password YOUR_PASS
Available MCP Tools (23)
| Tool | Description |
|---|---|
get_student_info |
Student profile, neptun code, training |
get_dashboard_data |
GPA, credit progress, unread messages |
get_term_averages |
GPA and credit index per semester |
get_all_grades |
Grade for every subject across all terms (full transcript) |
get_subject_grade |
Result/grade for one subject by ID |
get_taken_subjects |
Subjects taken in a term |
get_exam_results / get_exam_results_terms |
Exam results per term |
get_exams_list |
Available exams for a subject in a term |
get_received_messages / get_message_detail |
Read inbox / a thread |
get_calendar_events |
Calendar events by date range |
get_financial_impositions / get_financial_payments |
Fees and transactions |
get_pending_surveys / fill_all_surveys |
Surveys (Playwright auto-fill) |
call_method / list_methods |
Call/discover any of the 1,100+ API methods |
| ...and more | Curriculum, documents, surveys |
Authentication
The wrapper uses JWT Bearer tokens. Authentication is automatic — if your token expires mid-session, the client re-authenticates and retries transparently.
api = NeptunAPI("code", "password", base_url="https://your-university.hu/ujhallgato/api/")
api.authenticate()
# Token refresh
api.refresh_token()
# Auto-retry on 401 is built in — you don't need to handle token expiry
Two-factor authentication
Some universities (for example the University of Debrecen) require an authenticator-app code on every login. Their Neptun answers the first login with HTTP 202 and "isTwoFactorRequired": true instead of a token; the official web client then re-sends the login with the 6-digit code in a token field. authenticate() does the same, and you have three ways to supply the code:
from neptun_api import NeptunAPI, NeptunTwoFactorRequired
DEBRECEN = "https://www-h-ng.neptun.unideb.hu/hallgato_ng/api/"
# 1. Pass the code from your authenticator app for this login only
api = NeptunAPI("code", "password", base_url=DEBRECEN)
api.authenticate(totp_code=input("Authenticator code: "))
# 2. Ask for it whenever the client needs to (re-)authenticate
api = NeptunAPI("code", "password", base_url=DEBRECEN,
two_factor_callback=lambda: input("Authenticator code: "))
api.authenticate()
# 3. Fully unattended: give the TOTP secret and codes are generated for you
# (this is the base32 key behind the QR code shown when you registered the
# authenticator — most apps let you view or export it; otherwise delete the
# key in Neptun and register it again, noting the key this time).
api = NeptunAPI("code", "password", base_url=DEBRECEN, totp_secret="JBSWY3DPEHPK3PXP")
api.authenticate()
If none of these is provided and the instance asks for a second factor, authenticate() raises NeptunTwoFactorRequired (a NeptunAuthError). A wrong or expired code raises NeptunAuthError; after repeated failed logins Neptun may also demand a captcha, which surfaces as NeptunCaptchaRequired — log in once through the website to clear it.
Option 1 only covers the initial login: if the session later expires (401) the client cannot re-authenticate without a fresh code, so long-running scripts should use option 2 or 3. generate_totp(secret) is exported if you need the current code yourself; it is a dependency-free RFC 6238 implementation (6 digits, 30 s, SHA-1, the Google Authenticator defaults Neptun uses).
Raw Requests
For endpoints not yet wrapped, use the raw methods:
# GET
data = api.raw_get("SomeController/SomeAction", params={"key": "value"})
# POST
data = api.raw_post("SomeController/SomeAction", data={"key": "value"})
# PUT / DELETE
data = api.raw_put("SomeController/SomeAction", data={"key": "value"})
data = api.raw_delete("SomeController/SomeAction", params={"key": "value"})
Other Universities
Change the base_url to point to your university's Neptun instance:
# Obuda University
api = NeptunAPI("code", "pass", base_url="https://neptun.uni-obuda.hu/ujhallgato/api/")
# BME
api = NeptunAPI("code", "pass", base_url="https://neptun.bme.hu/ujhallgato/api/")
# ELTE
api = NeptunAPI("code", "pass", base_url="https://neptun.elte.hu/ujhallgato/api/")
# University of Debrecen (two-factor login, see Authentication above)
api = NeptunAPI("code", "pass", base_url="https://www-h-ng.neptun.unideb.hu/hallgato_ng/api/",
two_factor_callback=lambda: input("Authenticator code: "))
# Any Neptun instance — take the URL of the new student web (it ends in
# /ujhallgato/ or /hallgato_ng/ depending on the university) and append api/
Note: Not all universities may have the same endpoints enabled. Some features (booking, theses, practice) may return 403 depending on your institution's configuration.
Running Tests
# Unit tests
pip install -e ".[dev]"
pytest
# Live integration test (requires NEPTUN_USERNAME / NEPTUN_PASSWORD env vars)
NEPTUN_USERNAME=YOUR_CODE NEPTUN_PASSWORD=YOUR_PASS python tests/test_live_comprehensive.py
Project Structure
neptun_api/
__init__.py # Public exports
__main__.py # Entry point for python -m neptun_api
client.py # API wrapper (1,100+ methods)
mcp_server.py # MCP server (stdio / SSE / streamable-http)
survey_filler.py # Automated Unipoll survey filler (Playwright)
models.py # Dataclasses for common response types
exceptions.py # NeptunAuthError, NeptunRequestError
tests/
test_client.py # client unit tests (incl. grade API)
test_models.py # dataclass model tests
test_mcp_server.py # guards MCP tools against client drift
test_live_comprehensive.py # live smoke test (run directly, needs creds)
docs/
request_forms.md # guide to the request-form (petition) endpoints
License
MIT
README fetched from the repository 4 days ago. The original is authoritative.