Skip to main content
Glama

Aswaya MCP

Aplikasi untuk memakai LMS Aswaya Pradita University (https://aswaya.pradita.ac.id, sebuah Moodle) dari asisten AI, terminal, atau program lain. Dibuat untuk dosen yang ingin mengotomasi pekerjaan mengajar: melihat kursus dan pesertanya, memantau pengumpulan tugas, membaca buku nilai, mengunduh berkas, membuat pengumuman, memberi nilai, mengirim pesan, serta menambah dan mengganti nama section kursus.

Aplikasi ini memakai web service Moodle yang juga dipakai aplikasi Moodle di ponsel (layanan moodle_mobile_app). Untuk section kursus, yang tidak dibuka layanan itu, aplikasi login lewat halaman web seperti peramban. Proyek saudaranya, dengan pola yang sama, adalah lppm-mcp, siakad-mcp, dan sister-mcp. Semuanya berdiri sendiri: kode, dokumentasi, dan pengujiannya terpisah.

Tersedia dalam tiga bentuk, semuanya dari paket yang sama:

Mode

Untuk siapa

Referensi

MCP

asisten AI (Claude Code, dsb.)

docs/MCP.md

REST API

aplikasi apa pun lewat HTTP

docs/API.md

Pustaka

program Python Anda sendiri

bagian Pustaka

Ada juga CLI (./aswaya kursus, ./aswaya pengumpulan, ./aswaya umumkan, dan seterusnya) untuk pemakaian langsung dari terminal; lihat docs/CLI.md.

Memakainya lewat asisten AI

Untuk Claude Code, dari klona repositori ini:

claude mcp add aswaya-mcp -s user -- /path/ke/aswaya-mcp/aswaya mcp

Langkah untuk Codex dan Antigravity, serta pengaturan izin pemanggilan tool, ada di docs/MCP.md.

Related MCP server: FCPC-lms-mcp-server

Prasyarat

  • Python 3.10 atau lebih baru (diuji dengan 3.12)

  • Akun Aswaya (username atau email kampus, dan password), atau token web service layanan moodle_mobile_app

Pasang

Ada dua cara, pilih salah satu.

A. Berdiri sendiri. Klona lalu jalankan; cocok kalau Anda hanya mau memakai aplikasinya:

git clone https://github.com/alfa-yohannis/aswaya-mcp.git
cd aswaya-mcp
./aswaya uji          # jalankan pertama menyiapkan .venv + dependensi sendiri

Virtualenv dibuat dengan python3. Untuk memakai interpreter lain: ASWAYA_PYTHON=python3.12 ./aswaya uji.

B. Sebagai paket, kalau aplikasi Anda sendiri yang akan memakainya:

pip install "aswaya-mcp[api,mcp] @ git+https://github.com/alfa-yohannis/aswaya-mcp.git"
pip install "git+https://github.com/alfa-yohannis/aswaya-mcp.git"   # pustaka saja

Kredensial

Salin contohnya lalu isi sendiri:

cp .env.contoh .env
ASWAYA_URL=https://aswaya.pradita.ac.id
ASWAYA_USERNAME=nama.anda@pradita.ac.id
ASWAYA_PASSWORD=...
ASWAYA_TOKEN=

Cukup isi password atau token. Kalau keduanya terisi, ASWAYA_TOKEN dipakai lebih dulu, dan password hanya dipakai untuk login ulang saat token itu ditolak. Isian kosong dianggap belum diisi. Login web untuk section selalu butuh password, karena token web service tidak bisa dipakai untuk login lewat halaman.

.env tidak ikut ter-commit. Kredensial hanya dibaca dari .env, environment, atau atur_setelan() di kode, tidak pernah dari aswaya.yaml, dan tidak pernah dicetak ke layar maupun log. Tool MCP sengaja tidak menerima kata sandi atau token lewat parameter, jadi asisten AI tidak pernah memegangnya.

Cache token dan sesi web

Supaya password tidak dipakai setiap kali, token hasil login disimpan di luar repositori:

$XDG_CACHE_HOME/aswaya-mcp/token-<sidik>.json    (bawaannya ~/.cache/aswaya-mcp/)
$XDG_CACHE_HOME/aswaya-mcp/sesi-<sidik>.json     cookie sesi web, untuk alat section

Berkasnya berizin 0600 di direktori berizin 0700, satu per pasangan situs dan username; nama berkasnya sidik SHA-256, jadi alamat dan username tidak terbaca dari daftar isi direktori. privatetoken dari Moodle dan sesskey tidak pernah disimpan. Di sistem berkas yang tidak menegakkan izin (NTFS, FAT, sebagian mount jaringan), berkasnya dihapus lagi dan token hanya hidup di memori; berkas cache yang ternyata terbuka bagi pemakai lain juga dibuang. Untuk mematikan cache, isi simpan_cache: tidak di aswaya.yaml (atau ASWAYA_SIMPAN_CACHE=tidak). Hapus direktori itu untuk melupakan semua token dan sesi.

Menjalankan

1. MCP

claude mcp add aswaya-mcp -- /path/ke/aswaya-mcp/aswaya mcp   # dari klona
claude mcp add aswaya-mcp -- aswaya-mcp                       # setelah pip install

Cek servernya hidup tanpa mendaftarkannya dulu:

./aswaya mcp        # bicara JSON-RPC lewat stdio; Ctrl-C untuk berhenti

Lalu minta asisten Anda, misalnya: "Siapa saja yang belum mengumpulkan Tugas 1 di kelas Pengembangan Aplikasi Web?" Ada 19 tool. Tiga belas hanya membaca: cek_login, daftar_kursus, isi_kursus, peserta_kursus, daftar_tugas, pengumpulan_tugas, nilai_kursus, daftar_forum, diskusi_forum, tenggat, daftar_section, fungsi_tersedia, dan unduh_berkas (yang menulis ke disk lokal, tidak ke Aswaya). Tujuh bisa menulis ke Aswaya dan bawaannya uji coba: kirim_pengumuman, beri_nilai, kirim_pesan, tambah_section, ubah_nama_section, ubah_ringkasan_section, dan panggil_fungsi untuk fungsi selain baca. Rinciannya di docs/MCP.md.

2. REST API

./aswaya api                  # http://localhost:8000
PORT=9001 ./aswaya api        # ganti port
uvicorn aswaya_mcp.api:app --port 8000   # kalau terpasang sebagai paket

Dokumentasi interaktif ada di /docs. Coba:

curl localhost:8000/kursus?cari=web
curl localhost:8000/kursus/5515/peserta
curl -X POST localhost:8000/kursus/5515/pengumuman -H 'Content-Type: application/json' \
  -d '{"subjek": "Kuis", "isi": "Kuis dimulai pukul 08.00."}'      # uji coba

Untuk menempelkannya ke aplikasi FastAPI Anda sendiri:

from aswaya_mcp.api import router
app.include_router(router, prefix="/aswaya")

Endpoint selengkapnya di docs/API.md.

3. Pustaka

from aswaya_mcp import KlienAswaya, daftar_kursus, pengumpulan_tugas

klien = KlienAswaya()                       # kredensial dari .env; belum menghubungi Aswaya
for kursus in daftar_kursus(klien, "web")["kursus"]:    # token diambil di sini
    print(kursus["id"], kursus["fullname"])

status = pengumpulan_tugas(klien, 77)
print(status["ringkasan"])

# fungsi web service apa pun, dengan parameter terstruktur
isi = klien.panggil("core_course_get_contents", {"courseid": 5515})

Fungsi yang menulis mengembalikan HasilTulis. Bawaannya uji coba:

from aswaya_mcp import KlienAswaya, kirim_pengumuman, tambah_section

klien = KlienAswaya()
rencana = kirim_pengumuman(klien, 5515, "Kuis minggu depan", "Kuis dimulai pukul 08.00.")
print(rencana.ringkasan, rencana.permintaan)
hasil = kirim_pengumuman(klien, 5515, "Kuis minggu depan", "Kuis dimulai pukul 08.00.", kirim=True)

rencana = tambah_section(klien, 5026, [f"Session {nomor:02d}" for nomor in range(8, 15)])

KlienAswaya.unggah_berkas(path) mengunggah berkas ke draft area pemakai dan mengembalikan itemid-nya, untuk diteruskan ke fungsi lain lewat panggil. Kredensial dan alamat situs boleh diberikan dari kode tanpa berkas apa pun: atur_setelan(ASWAYA_USERNAME="...", ASWAYA_PASSWORD="..."). Semua kegagalan berupa exception biasa (AswayaError dan turunannya: LoginDitolak, LoginWebTerhalang, MoodleError, FungsiTidakTersedia, IsianDitolak, AlamatDitolak, HasilTidakPasti; serta KonfigurasiError); pustaka tidak pernah memanggil sys.exit. Contoh utuh: examples/pustaka.py.

CLI

./aswaya cek-login                      # kredensial di .env bisa dipakai?
./aswaya publik                         # konfigurasi publik situs, tanpa login
./aswaya kursus --cari web              # kursus yang Anda ikuti
./aswaya isi 5515                       # section, modul, dan berkas
./aswaya peserta 5515 --peran student   # peserta; --lengkap untuk email dan NIM
./aswaya pengumpulan 77                 # siapa sudah dan belum mengumpulkan
./aswaya nilai 5515 --csv > nilai.csv   # buku nilai untuk spreadsheet
./aswaya tenggat --hari 14              # kegiatan yang menunggu tindakan
./aswaya umumkan 5515 --subjek "Kuis" --isi "..."            # uji coba; --kirim untuk mengirim
./aswaya tambah-section 5026 --nama "Session "{08..14}       # uji coba; --kirim untuk mengirim

Terpasang sebagai paket, perintahnya aswaya-cek-login, aswaya-kursus, dan seterusnya dengan argumen yang sama. Daftar lengkap di docs/CLI.md.

Menulis ke Aswaya

Semua alat yang menulis mengikuti alur yang sama. Isian diperiksa dulu tanpa menghubungi Aswaya, lalu data pendukung dibaca supaya pratinjaunya bisa diperiksa: forum pengumuman kursus, nilai lama mahasiswa, nama penerima pesan, section yang sudah ada. Dengan kirim=False (bawaan; di CLI tanpa --kirim) yang kembali hanya pratinjau berisi ringkasan untuk dibaca manusia dan permintaan yang akan dikirim apa adanya, tanpa token. Dengan kirim=True permintaannya dikirim tepat sekali.

Alat

Yang dikirim

Pemeriksaan sebelum kirim

kirim_pengumuman

mod_forum_add_discussion ke forum jenis news

forum pengumuman ada dan akun ini boleh menulis

beri_nilai

mod_assign_save_grade (percobaan terakhir, applytoall=0)

nilai tidak negatif dan tidak melebihi nilai maksimum tugas

kirim_pesan

core_message_send_instant_messages

setiap id penerima dikenal Aswaya

tambah_section

course/changenumsections.php, lalu nama lewat AJAX

nama belum terpakai di kursus itu (kecuali paksa)

ubah_nama_section

core_update_inplace_editable lewat AJAX

section milik kursus itu

ubah_ringkasan_section

form course/editsection.php lewat sesi web

section milik kursus itu; tautannya belum semua ada (kecuali paksa)

panggil_fungsi

wsfunction apa pun selain fungsi baca

fungsinya dimuat layanan token ini

Isi pengumuman, umpan balik, dan pesan berupa teks biasa: karakter HTML di-escape, baris kosong memisahkan paragraf, dan alamat http(s) menjadi tautan. Pakai bentuk="html" (CLI: --html) untuk mengirim HTML apa adanya.

Kiriman tidak pernah diulang otomatis, kecuali saat Aswaya menolak token atau sesskey-nya; penolakan itu terjadi sebelum fungsinya dijalankan, jadi aman diulang sekali setelah login. Kalau permintaan sudah berangkat tetapi jawabannya tidak bisa dipastikan (jaringan putus, jawaban rusak), yang muncul HasilTidakPasti; di MCP balasannya terkirim: true dengan ok: false. Periksa dulu lewat alat baca sebelum mencoba lagi.

panggil_fungsi menebak jenis fungsi dari namanya, karena site info Moodle tidak menyebutkannya: nama yang memuat _get_, _search_, atau _list_ dianggap membaca dan langsung dijalankan. Fungsi lain, termasuk fungsi view yang mencatat log dan bisa menandai aktivitas selesai, hanya dipratinjau. tool_mobile_get_autologin_key dan tool_mobile_get_tokens_for_qr_login ditolak sama sekali karena menghasilkan kunci login.

Section kursus

Layanan moodle_mobile_app tidak memuat fungsi pembuat section. Karena itu tambah_section dan ubah_nama_section login lewat halaman, seperti peramban, dengan username dan password dari .env:

  1. GET /login/index.php untuk mengambil logintoken dari form id="login", lalu POST berisi anchor, logintoken, username, dan password.

  2. Halaman kursus dibuka untuk membaca sesskey dari M.cfg, sekaligus format kursusnya kalau web service tidak menyebutnya.

  3. GET /course/changenumsections.php?courseid=..&insertsection=0&numsections=N&sesskey=.. menambah N section di akhir kursus (parameter Moodle 4.1).

  4. Setiap section baru diberi nama lewat POST /lib/ajax/service.php?sesskey=..&info=core_update_inplace_editable dengan component format_<format kursus>, itemtype sectionname, itemid id section, dan value namanya.

  5. Hasilnya diperiksa ulang lewat core_course_get_contents. Section baru dikenali dari id yang belum ada sebelumnya, jadi nama tidak pernah terpasang ke section lama.

Contoh untuk menambah Session 08 sampai 14 di kursus 5026:

./aswaya section 5026                                  # lihat section yang ada
./aswaya tambah-section 5026 --nama "Session "{08..14}            # rencana
./aswaya tambah-section 5026 --nama "Session "{08..14} --kirim    # kirim

Bash menjabarkan "Session "{08..14} menjadi tujuh nama, Session 08 sampai Session 14. Rencananya menyebut section yang ada, nama baru beserta nomor posisinya, dan langkah yang akan dijalankan. Nama yang sudah dipakai di kursus itu ditolak supaya perintah yang tidak sengaja dijalankan dua kali tidak menggandakan section; --paksa melewati pemeriksaan ini. Kalau kursus sudah berakhir dengan section kosong, rencananya memperingatkan hal itu, karena mungkin yang dimaksud adalah mengganti nama section kosong tersebut.

Kalau halaman login memuat captcha (reCAPTCHA, hCaptcha, Turnstile, dan sejenisnya), login dihentikan dengan pesan jelas dan captcha-nya tidak dicoba dijawab. Begitu juga kalau Aswaya meminta MFA, persetujuan kebijakan situs, atau penggantian password. Langkah seperti itu diselesaikan pemakai lewat peramban. Login web yang gagal tidak diulang otomatis.

Ringkasan section

ubah_ringkasan_section mengisi deskripsi sebuah section, misalnya section General (nomor 0) di bagian atas kursus, juga lewat sesi web:

  1. GET /course/editsection.php?id=<section_id>&sr=0 membuka form edit section.

  2. Isian form dibaca utuh seperti peramban mengirimnya (id, course, sesskey, name, summary_editor[itemid], availabilityconditionsjson). Hanya summary_editor[text] yang diganti, lalu form dikirim dengan tombol submitbutton.

  3. Kalau Aswaya mengalihkan ke halaman kursus, ringkasannya diperiksa ulang lewat core_course_get_contents. Kalau form tampil lagi, pesan galatnya dilaporkan dan tidak ada yang berubah.

Bawaannya isi baru ditambahkan di akhir ringkasan (--awal untuk menaruhnya di bagian paling atas, --ganti untuk mengganti seluruhnya), dan setiap tautan di isi baru dibuka di tab baru (target="_blank" rel="noopener"; --tab-sama untuk mematikannya). Isi berupa teks biasa, atau HTML dengan --html. Kalau semua tautannya sudah ada di ringkasan, penambahan ditolak supaya perintah yang terulang tidak menggandakan tautan; --paksa melewati pemeriksaan ini.

./aswaya section 5519                                                     # cari id section General
./aswaya ubah-ringkasan-section 5519 62626 --html --isi '<p><a href="https://drive.google.com/...">Slides (PDF)</a></p>'           # rencana
./aswaya ubah-ringkasan-section 5519 62626 --html --isi '<p><a href="https://drive.google.com/...">Slides (PDF)</a></p>' --kirim   # kirim

Privasi data mahasiswa

peserta_kursus hanya meminta id, nama, peran, grup, dan waktu akses terakhir dari Aswaya, lewat opsi userfields milik core_enrol_get_enrolled_users. Email dan idnumber (NIM) baru diminta dan dikembalikan kalau lengkap=True (CLI: --lengkap), supaya data pribadi mahasiswa tidak ikut tersimpan di riwayat percakapan asisten AI tanpa keperluan. nilai_kursus tidak menyertakan NIM; cocokkan lewat user_id kalau perlu. pengumpulan_tugas membaca peserta tugas dengan onlyids, jadi yang keluar hanya nama dan status.

Setelan

Semua setelan opsional. Yang menang, dari yang paling khusus:

argumen pemanggil -> atur_setelan() -> environment -> .env -> aswaya.yaml -> nilai bawaan

Di environment dan .env namanya berawalan ASWAYA_ dan huruf besar (ASWAYA_URL); di aswaya.yaml tanpa awalan dan huruf kecil (url). Salin aswaya.yaml.contoh menjadi aswaya.yaml kalau perlu mengubah sesuatu.

aswaya.yaml

Bawaan

Keterangan

url

https://aswaya.pradita.ac.id

alamat Moodle; harus https, boleh dengan subdirektori

nama_instansi

Pradita University

label pada judul REST API dan instruksi MCP

layanan

moodle_mobile_app

layanan web service yang dimintai token

batas_detik

60

login dan panggilan fungsi

batas_unduh_detik

300

unduhan dan unggahan berkas

maks_pengalihan

5

pengalihan yang diikuti saat unduh dan di sesi web

simpan_cache

ya

simpan token dan cookie sesi di cache 0600

zona_waktu

Asia/Jakarta

zona waktu tanggal di keluaran

umur_sesi_detik

900

lama klien per kredensial disimpan REST API

user_agent

aswaya-mcp

User-Agent permintaan HTTP

ASWAYA_USERNAME, ASWAYA_PASSWORD, dan ASWAYA_TOKEN hanya dibaca dari atur_setelan(), environment, dan .env.

Akar proyek

Akar proyek menentukan letak .env, aswaya.yaml, dan data/, serta titik hitung path relatif (termasuk tujuan unduhan):

  • dijalankan dari klona repositori ini: direktori repositori itu sendiri

  • dipasang sebagai paket: direktori kerja proyek pemakai

Direktori di atasnya tidak pernah ikut ditelusuri. Untuk menentukan sendiri, setel ASWAYA_AKAR_PROYEK atau panggil atur_akar_proyek().

Rancangan

pyproject.toml              metadata paket, dependensi, dan perintah terpasang
aswaya                      peluncur untuk pemakaian berdiri sendiri
aswaya.yaml.contoh          contoh setelan non-rahasia
aswaya_mcp/__init__.py      API publik paket ini
aswaya_mcp/konfigurasi.py   akar proyek, setelan, kredensial, sesi HTTP, zona waktu, cache token dan sesi
aswaya_mcp/aswaya_client.py KlienAswaya: token, perataan parameter, server.php, galat Moodle, berkas, unggahan
aswaya_mcp/sesi_web.py      SesiWeb: login lewat halaman, cookie, sesskey, AJAX service.php
aswaya_mcp/kursus.py        daftar kursus, isi kursus, peserta
aswaya_mcp/tugas.py         tugas, pengumpulan, beri nilai
aswaya_mcp/nilai.py         buku nilai kursus
aswaya_mcp/forum.py         forum, diskusi, pengumuman
aswaya_mcp/kalender.py      tenggat dari action events kalender
aswaya_mcp/pesan.py         pesan pribadi
aswaya_mcp/section.py       daftar, tambah, dan ganti nama section
aswaya_mcp/berkas.py        unduh berkas ke disk
aswaya_mcp/fungsi.py        daftar fungsi dan pemanggil generik
aswaya_mcp/situs.py         cek login dan konfigurasi publik
aswaya_mcp/tulis.py         HasilTulis: uji coba, pratinjau permintaan, hasil kiriman
aswaya_mcp/teks.py          HTML ke teks dan sebaliknya, waktu Unix ke ISO 8601
aswaya_mcp/cli.py           CLI (aswaya-kursus, aswaya-umumkan, ...)
aswaya_mcp/api.py           REST API: router yang bisa ditempel + app siap pakai
aswaya_mcp/mcp_server.py    MCP server (perintah aswaya-mcp)
tests/                      unit test dengan Aswaya tiruan, tanpa jaringan
docs/                       referensi CLI, REST API, dan MCP
examples/                   contoh prompt, konfigurasi klien MCP, klien API, pustaka

Catatan perilaku Aswaya

Diamati dari konfigurasi publik situs (tool_mobile_get_public_config, tanpa login) pada 21 Oktober 2026:

  • Nama situs "Aswaya Pradita University E-Learning", wwwroot https://aswaya.pradita.ac.id.

  • enablewebservices=1 dan enablemobilewebservice=1, jadi layanan moodle_mobile_app aktif dan login/token.php bisa dipakai.

  • typeoflogin=1: login di dalam aplikasi dengan username dan password, tanpa peramban. authloginviaemail=1: email kampus bisa dipakai sebagai username.

  • guestlogin=0, maintenanceenabled=0.

Menurut pemeriksaan pemakai, situsnya Moodle 4.1 dan halaman loginnya tidak memuat captcha, dengan isian username, password, dan logintoken. Parameter changenumsections.php dan nama itemtype sectionname dicocokkan dengan kode MOODLE_401_STABLE. Parameter fungsi web service lainnya dicocokkan dengan kode Moodle 4.1 yang sama (enrol/externallib.php, mod/assign/externallib.php, mod/forum/externallib.php, message/externallib.php, calendar/externallib.php, dan gradereport_user).

Yang belum bisa diverifikasi tanpa login, dan perlu dicek pada pemakaian pertama:

  • daftar fungsi yang benar-benar dimuat layanan moodle_mobile_app di Aswaya (./aswaya fungsi); alat yang butuh fungsi yang tidak ada memberi pesan jelas;

  • bentuk jawaban core_webservice_get_site_info, gradereport_user_get_grade_items, dan fungsi lain untuk akun dosen sungguhan, termasuk peran dan nama grup;

  • apakah idnumber pengguna di Aswaya memang berisi NIM;

  • perilaku webservice/pluginfile.php untuk token yang ditolak, dan berkas yang tersimpan sebagai tautan ke layanan luar;

  • login web, isi M.cfg, kelas body halaman kursus, dan jawaban AJAX core_update_inplace_editable; semuanya baru diuji dengan tiruan berdasarkan kode Moodle 4.1;

  • batas section kursus 5026 dan format kursusnya.

Keamanan dan batasan

  • Verifikasi sertifikat TLS selalu aktif dan tidak ada setelan untuk mematikannya.

  • Token dikirim di badan POST ke server.php, tidak di URL. Untuk unduhan, token ditambahkan ke query webservice/pluginfile.php dan hanya ke host Aswaya; pengalihan ke host lain tidak diikuti.

  • Sesi web hanya membuka alamat di host Aswaya. Password hanya dikirim dalam POST ke /login/index.php, dan action form di host lain ditolak sebelum password ikut terkirim.

  • Token, password, sesskey, privatetoken, dan userprivateaccesskey tidak muncul di repr(), pesan galat, maupun keluaran. Pesan galat dari Aswaya disamarkan kalau kebetulan menggemakan kredensial.

  • Login yang gagal tidak diulang otomatis, karena Moodle bisa mengunci akun setelah beberapa kali gagal.

  • Unduhan ditulis lewat berkas sementara lalu dipindah, nama berkas dari server dibersihkan dari pemisah direktori, dan berkas yang sudah ada tidak ditimpa kecuali timpa=True.

Menambah kemampuan baru

./aswaya fungsi forum                              # 1. cari wsfunction yang tersedia
./aswaya panggil mod_forum_get_discussion_posts --parameter '{"discussionid": 301}'
                                                   # 2. lihat bentuk jawabannya
# 3. tulis fungsi layanan di modul areanya (mis. forum.py), dengan uji coba kalau menulis
# 4. daftarkan di cli.py, api.py, dan mcp_server.py
# 5. tambahkan uji di tests/ dengan jawaban karangan di SitusTiruan

Alat yang menulis memakai tulis.jalankan_tulis() (web service) atau mengembalikan HasilTulis sendiri (sesi web), dengan kirim=False sebagai bawaan, dan instruksi MCP-nya meminta asisten menjalankan uji coba lebih dulu lalu meminta persetujuan pemakai.

Konvensi penulisan skrip

  • Satu modul untuk satu area; alur bersama tinggal di modul dasar (aswaya_client.py, sesi_web.py, tulis.py).

  • Setiap kelas, method, dan fungsi punya docstring.

  • Fungsi ditulis datar, tanpa fungsi bersarang di dalam fungsi.

  • Nama variabel dan fungsi ditulis utuh dan deskriptif, tanpa singkatan satu-dua huruf.

  • Komentar hanya untuk hal yang tidak terbaca dari kodenya.

  • Nilai rahasia tidak pernah dicetak.

Pengujian

./aswaya uji

237 unit test, semuanya berjalan tanpa jaringan dan tanpa kredensial: Aswaya digantikan SitusTiruan di tests/conftest.py, yang menjawab seperti Moodle 4.1 untuk token.php, server.php, webservice/pluginfile.php, upload.php, service-nologin.php, halaman login, changenumsections.php, dan AJAX service.php. Selama uji, akar proyek dan cache dipindah ke direktori sementara supaya .env asli dan ~/.cache/aswaya-mcp/ tidak tersentuh, dan sesi HTTP sungguhan diblokir. Nama dosen, mahasiswa, NIM, email, token, dan kata sandi di berkas uji dan dokumentasi seluruhnya dikarang.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables interaction with Moodle learning management systems through the Moodle REST API. Supports course management, user enrollment, assignments, forums, quizzes, and file operations through natural language.
    10 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Connects Waseda University's Moodle to AI assistants such as Claude, ChatGPT, and Cursor, letting users ask about assignments and deadlines, timetable, syllabus, grades, course updates, forums, and files across all their courses at once. It also supports write actions like assignment submission and forum posts through a preview-then-confirm flow.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Provides read-only access to a university's Moodle virtual campus, letting an AI assistant browse courses, sections and files, check upcoming deadlines, view assignment status and grades, and read forum announcements and threads. Authentication uses a Moodle token stored locally, with support for both undergraduate and postgraduate campus URLs.
    8
    MIT