lmstelkom-mcp
Integrates with LMS Telkom University's Moodle instance, allowing AI to view courses, upcoming deadlines, course materials, and read or download LMS files using the user's own account.
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., "@lmstelkom-mcpTampilkan deadline tugas saya 7 hari ke depan"
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.
lmstelkom-mcp
Bagus Ardin Prayoga
MCP server untuk LMS Telkom University (Moodle). AI bisa melihat mata kuliah, deadline, dan materi, serta mengambil file LMS memakai akunmu sendiri.
Ini proyek mahasiswa yang tidak resmi dan tidak berafiliasi dengan Telkom University atau CeLOE. Aturan akademik tetap tanggung jawab masing-masing pengguna.
Pilih mode
Kamu memakai | Mode | Perlu deploy? |
Claude Code, Codex, Claude Desktop, Cursor, VS Code, Antigravity, AI lokal seperti LM Studio | Lokal (stdio) | Tidak |
claude.ai, ChatGPT, dan AI chat web lain yang mendukung custom MCP | Online (HTTP) | Ya |
Related MCP server: FCPC-lms-mcp-server
Tool yang tersedia
Tool | Fungsi | Mode |
| Profil dan izin unduh serta upload file | Keduanya |
| Mata kuliah berjalan, selesai, atau akan datang | Keduanya |
| Aktivitas yang belum selesai dan jatuh tempo dalam sekian hari | Keduanya |
| Isi mata kuliah per bagian: aktivitas, file, dan link luar | Keduanya |
| Membaca teks file per halaman, untuk merangkum atau menjawab pertanyaan | Keduanya |
| Membuat tautan file untuk dibuka di browser | Keduanya |
| Mengunduh file LMS ke komputermu, maksimal 200 MB | Lokal |
Semua tool hanya membaca data LMS, jadi belum ada yang bisa mengumpulkan tugas atau mengirim pesan.
Batasan membaca file
read_file_text mendukung PDF, PPTX, DOCX, TXT, MD, CSV, dan HTML sampai 50 MB, tanpa menyimpan file di server.
File di Office 365 tidak bisa dibaca. Dosen bisa menaruh materi di Office 365 lalu menautkannya ke LMS, dan Moodle menolak mengirim file seperti ini lewat token. File ini ditandai
stored_outside_lms. Buka lewatget_file_linkdi browser, lalu unggah filenya ke AI kalau isinya perlu dibaca.Gambar tidak terbaca. PDF hasil scan hampir tidak menghasilkan teks, dan gambar serta diagram di slide tidak ikut.
Format lain belum didukung, termasuk XLSX, PPT, dan DOC versi lama.
Ambil token
LMS hanya bisa login lewat Office365, jadi token diambil lewat alur SSO aplikasi mobile Moodle.
Buka halaman token, lalu login kalau diminta.
Klik kanan tautan "Click here if the app does not open automatically", lalu pilih "Copy link address".
Tautan harus sama persis sampai ke tiap huruf, jadi jangan diketik ulang atau dibaca dari gambar. Kalau ditolak, tekan F12 di halaman token, lalu jalankan ini di tab Console untuk menyalinnya:
copy(document.getElementById('launchapp').href)Token ini setara akses penuh ke akun LMS, jadi jangan dibagikan atau dikirim ke chat AI, termasuk lewat screenshot.
Token punya masa berlaku yang diatur admin LMS, dengan default Moodle 12 minggu. Kalau sudah habis, tool akan membalas error accessexception atau invalidtoken, lalu ulangi langkah di atas.
Mode lokal
Butuh uv.
git clone <url-repo-ini>
cd mcp-lmstelkom
uv syncSalin .env.example menjadi .env, lalu tempel tautan token setelah LMS_TOKEN=. File .env tidak ikut di-commit. Setelah itu uji aksesnya:
uv run lms-mcp checkGanti /path/ke/mcp-lmstelkom dengan lokasi folder proyek ini.
Claude Code
claude mcp add lms-telkom -- uv run --directory /path/ke/mcp-lmstelkom lms-mcp serveCodex
codex mcp add lms-telkom -- uv run --directory /path/ke/mcp-lmstelkom lms-mcp serveClaude Desktop, Cursor, Antigravity, LM Studio, dan client lain yang memakai format mcpServers
{
"mcpServers": {
"lms-telkom": {
"command": "uv",
"args": ["run", "--directory", "/path/ke/mcp-lmstelkom", "lms-mcp", "serve"]
}
}
}VS Code memakai format yang mirip di mcp.json, tapi kuncinya servers, bukan mcpServers.
Kalau uv tidak ditemukan oleh aplikasinya, isi command dengan lokasi lengkap uv.
Mode online
Deploy
Repo ini berisi Dockerfile, jadi bisa dijalankan di hosting apa pun yang mendukung container. railway.json sudah disiapkan untuk Railway.
Isi variabel ini di pengaturan hosting:
Variabel | Keterangan |
| Alamat publik server, contoh |
| Kunci enkripsi acak, minimal 32 karakter |
| Opsional, host klien tambahan yang diizinkan, dipisah koma |
Buat LMS_SERVER_SECRET dengan perintah ini, dan jangan pernah mengubahnya tanpa alasan, karena semua pengguna akan perlu login ulang:
python -c "import secrets; print(secrets.token_urlsafe(48))"Jangan isi LMS_TOKEN di hosting, karena mode online tidak memakainya.
Sambungkan ke AI chat
Alamat connector-nya adalah LMS_PUBLIC_URL ditambah /mcp.
claude.ai: Settings, Connectors, lalu Add custom connector.
ChatGPT: aktifkan Developer Mode, lalu tambahkan connector di pengaturan Apps & Connectors. Ketersediaannya tergantung paket.
AI chat lain: tambahkan host callback-nya ke
LMS_EXTRA_REDIRECT_HOSTS. Hanya claude.ai dan ChatGPT yang diizinkan secara default.
Saat menyambungkan, akan muncul halaman login server ini. Tempel tautan token di sana.
Cara kerja login
Server tidak punya database. Token LMS dienkripsi dan disimpan di dalam access token yang dipegang aplikasi AI, dan hanya server yang bisa membukanya. Karena itu, tiap orang otomatis memakai akunnya sendiri.
Tetap saja, pemilik server secara teknis bisa membaca token yang lewat. Tempel token hanya di server milik orang yang kamu percaya, atau pakai mode lokal. Untuk memutus akses sepenuhnya, reset token di halaman Security keys LMS.
Keamanan
Isi LMS bisa ditulis siapa saja di kelasmu, termasuk teks yang mencoba memberi perintah ke AI. Periksa dulu aksi AI sebelum menyetujuinya.
Data LMS yang dibaca AI ikut terkirim ke penyedia model AI, kecuali kalau memakai model lokal.
Token hanya dikirim ke LMS, dan URL unduhan ke server lain ditolak.
Semua aksi tercatat di log LMS atas nama akunmu.
Konfigurasi mode lokal
Variabel | Keterangan |
| Tautan |
| Opsional, default folder |
| Opsional, default |
Variabel environment mengalahkan nilai di .env.
Tes
uv run pytestAvailable Tools
7 toolsdownload_fileA
Mengunduh file LMS ke folder unduhan di komputer pengguna, maksimal 200 MB.
file_url harus berasal dari get_course_materials. Link luar seperti Google Drive atau YouTube tidak bisa diunduh dengan tool ini. Hasilnya berisi lokasi file.
| Name | Required | Description | Default |
|---|---|---|---|
| file_url | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare a non-read-only, open-world, non-idempotent but non-destructive operation; the description adds the important detail that output lands in the user's local download folder, that there is a 200 MB ceiling, and that the result reports the file location. It does not mention overwrite behavior for duplicate filenames or what happens when the size limit is exceeded.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, front-loaded with the action and its main constraint (size limit, destination), then the input restriction, then the return value. Nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with no output schema, the description covers destination, size limit, input provenance, and the shape of the result. Error behavior and duplicate-file handling are unstated but are peripheral to correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% for the single file_url parameter, so the description must carry the semantics — and it does, by constraining provenance to get_course_materials and ruling out external hosts. It still doesn't state the expected URL format or how to obtain the value beyond naming a sibling tool, leaving a small gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (downloads LMS files) plus concrete scope: saved to the user's download folder with a 200 MB cap. It also implicitly separates itself from siblings like get_file_link and read_file_text by describing an actual file transfer to disk.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear precondition — file_url must originate from get_course_materials — and explicitly excludes external links such as Google Drive or YouTube. It stops short of stating when to prefer this over read_file_text or get_file_link for the same file, so the sibling routing is only partially resolved.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_course_materialsARead-onlyIdempotent
Menampilkan isi mata kuliah per bagian: aktivitas, file, dan link luar.
Pakai id dari list_courses. Baca isi file dengan file_url lewat read_file_text. File dengan stored_outside_lms ada di luar LMS, jadi tidak bisa dibaca lewat tool: beri pengguna tautan dari get_file_link. Deskripsi dipotong sampai 500 karakter, dan field yang kosong tidak ditampilkan.
| Name | Required | Description | Default |
|---|---|---|---|
| course_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and openWorld, so the safety profile is covered. The description adds real behavioral context beyond them: results are truncated at 500 characters, empty fields are omitted, and files stored outside the LMS cannot be read by this tool. It does not mention freshness, pagination, or size limits on the material list.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five short lines, front-loaded with what the tool returns, then parameter sourcing, then the sibling routing. Every line carries information, though the truncation note reads slightly ambiguously (whether it applies to the course description or the whole payload).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, but the description outlines the return shape (sections with activities, files, external links), the truncation and empty-field rules, and the unreadable-file case. Combined with annotations, an agent has everything needed to call it and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the single course_id parameter is undocumented in the schema, so the description must compensate; it does so by stating that course_id comes from list_courses. It adds the essential provenance but no format, range, or invalid-id behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific verb and resource ('Menampilkan isi mata kuliah per bagian') and enumerates the returned content types (aktivitas, file, link luar), which cleanly separates it from siblings like read_file_text or get_file_link.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly tells the agent where the required id comes from ('Pakai id dari list_courses') and routes downstream steps: use read_file_text for readable files, and get_file_link for files with stored_outside_lms. The when-to-use and when-not-to-use path is fully specified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_file_linkARead-onlyIdempotent
Membuat tautan file LMS untuk dibuka pengguna di browser.
file_url harus berasal dari get_course_materials. Pengguna perlu sudah login ke LMS di browsernya. Tool ini tidak membaca isi file.
| Name | Required | Description | Default |
|---|---|---|---|
| file_url | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and open-world, so the safety profile is covered. The description adds real behavioral context beyond them: this only produces a link (no file content is fetched), and it depends on the end user holding an active LMS browser session. It doesn't say what the returned value looks like or whether the link expires.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the action, then the parameter constraint, then the login caveat and the read-behavior disclaimer. No filler and nothing repeated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter, read-only tool with no output schema, the description covers origin of input, session prerequisite and the fact that no file content is read. The only gap is that it never states what is returned (a link string) or any expiry behavior, which an agent might need to relay to the user.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry the single parameter — and it does, by specifying that file_url must originate from get_course_materials. That is meaningful provenance guidance the schema lacks. It still doesn't describe the expected format (full URL vs. identifier) or what an invalid value does.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb and resource: it creates an LMS file link intended to be opened by the user in a browser. The clause 'Tool ini tidak membaca isi file' actively separates it from read_file_text. It does not explicitly contrast with download_file, which is the nearest sibling for file access.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a hard precondition ('file_url harus berasal dari get_course_materials') that routes the agent to the correct upstream tool rather than inventing a URL. It also names the login requirement in the user's browser. What it lacks is an explicit statement of when to choose this over download_file or read_file_text.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_profileBRead-onlyIdempotent
Menampilkan profil pengguna LMS dan izin unduh serta upload file.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered externally. The description contributes extra context by stating that download and upload permissions are part of the response, which is genuinely useful behavior information. It does not, however, clarify whose profile is returned (the authenticated caller or a target user) or whether the call can fail for unauthenticated sessions despite openWorldHint=true.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with the core information front-loaded and no filler. It is arguably slightly too terse for the permission scope it claims to return, but there is no redundant wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-argument read tool with a full annotation set and no output schema, the description covers the essentials, but it leaves two real gaps: who the profile belongs to and how the permission data is shaped. A short clause on identity scope would make it complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline of 4 applies. The single sentence is consistent with the empty schema and raises no questions about inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Menampilkan' / display) with a clear resource ('profil pengguna LMS') and adds that download/upload permissions are included. The resource and intent are unambiguous, though it does not explicitly distinguish itself from siblings such as list_courses or get_file_link.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to call this tool, no prerequisites, and no mention of alternatives among the six sibling tools. The only implicit signal is that it is the entry point for user/permission information, which an agent must infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_upcoming_deadlinesARead-onlyIdempotent
Menampilkan aktivitas yang belum selesai dan jatuh tempo dalam sekian hari ke depan.
Tugas yang sudah dikumpulkan biasanya tidak ikut tampil. Tenggat yang sudah lewat tidak ditampilkan.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, so safety needs no restating. The description adds real behavioral value by disclosing the result-filtering rules: completed/submitted activities are normally excluded and expired deadlines are hidden. The hedge 'biasanya' (usually) is honest about non-determinism but slightly weakens predictability.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the core purpose, followed by the two exclusion rules. No filler or marketing language. The odd mid-sentence line wrapping is formatting noise rather than verbal waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read-only tool with rich annotations and no output schema, the description covers purpose and filtering rules adequately. It leaves open what an 'activity' actually is (assignment, quiz, exam), whether results are sorted by due date, and how the default window is applied — modest but real gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% for the single 'days' parameter, so the description must carry the load. It does explain the parameter's meaning ('jatuh tempo dalam sekian hari ke depan'), i.e. a forward-looking window, but gives no units guidance, no mention of the default of 14, and no boundary behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource in behavioral terms: activities that are not yet completed and fall due within the next N days. An agent can tell at a glance this is a filtered deadline list rather than a profile, course, or file tool like any of the siblings. It stops short of naming scope relative to siblings, but no sibling overlaps so confusion risk is low.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: the exclusions ('submitted tasks usually don't appear', 'past deadlines are not shown') tell the agent what results will look like, which indirectly signals when this tool is useful. There is no explicit when-to-use/when-not statement and no alternative named, so the guidance remains inferential.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_coursesBRead-onlyIdempotent
Menampilkan mata kuliah pengguna beserta id-nya.
status: inprogress (berjalan), past (selesai), future (akan datang), atau all.
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | inprogress |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=true and destructiveHint=false, so safety and idempotence need no restatement. The description adds that course IDs are returned, which the annotations do not cover, but says nothing about pagination, ordering, or what an empty result means.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short lines, front-loaded with the purpose and followed by the status legend; no filler. The formatting is slightly terse and the default-value fact is orphaned outside the sentence structure, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A one-parameter read tool with annotations and no output schema is simple, but at 0% schema coverage the description should state the default, the sort order, and roughly what a course record contains. Instead it omits the default entirely and leaves return shape to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the parameter meaning, and it only partially does: it glosses the status values but never explains what 'all' returns or that omitting the parameter defaults to inprogress, which is the key behavior for a zero-required-parameter tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Menampilkan mata kuliah pengguna beserta id-nya' = display the user's courses along with their IDs), so the agent knows it lists courses with identifiers. It does not name or contrast with any sibling tool, but none of the siblings list courses, so confusion risk is low.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description enumerates the status values with short glosses (inprogress=ongoing, past=completed, future=upcoming, all), which implies when to use each filter. There is no explicit statement of when to prefer this tool over fetching materials or deadlines, and no guidance that the default is inprogress.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_file_textARead-onlyIdempotent
Membaca teks file LMS per halaman, untuk merangkum atau menjawab pertanyaan materi.
file_url harus berasal dari get_course_materials. Mendukung PDF, PPTX, DOCX, TXT, MD, CSV, dan HTML sampai 50 MB. File dengan stored_outside_lms tidak bisa dibaca. Gambar tidak terbaca, dan PDF hasil scan hampir tidak menghasilkan teks. Kalau next_start_page terisi dan masih perlu, panggil lagi dari halaman itu. page_count maksimal 50.
| Name | Required | Description | Default |
|---|---|---|---|
| file_url | Yes | ||
| page_count | No | ||
| start_page | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and open-world, so the safety profile is covered; the description goes well beyond that by disclosing the 50 MB size ceiling, the exact supported formats, that stored_outside_lms files are unreadable, that images and scanned PDFs yield little or no text, and that page_count is capped at 50. These are real operational constraints an agent cannot infer from the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core capability and the file_url prerequisite are front-loaded, followed by constraints and then paging instructions, so the agent hits the important information first. Every sentence carries information, though the dense single paragraph mixing format support, size limits, and pagination could be grouped more cleanly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter extraction tool with no output schema, the description covers purpose, prerequisites, format and size limits, failure modes, and the pagination continuation protocol. Since it even names the next_start_page return field, an agent has everything needed to call it correctly and to loop for more pages.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry the load, and it does for the most part: it pins down file_url provenance (must originate from get_course_materials), caps page_count at 50, and explains the paging behavior where a subsequent call resumes at next_start_page. It never explicitly defines start_page's default/role, and next_start_page is a response field rather than an input parameter, so the paging loop is described slightly loosely.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: reading LMS file text page by page, with the stated purpose of summarizing or answering questions about materials. It clearly implies a text-extraction read rather than a download, which separates it from siblings like download_file and get_file_link, though those siblings are never named as alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear use case (summarizing / answering questions about course material) plus a hard prerequisite: file_url must come from get_course_materials. It also explains the continuation condition (if next_start_page is returned and you still need more, call again from that page). It stops short of explicitly routing the agent to download_file when the raw file rather than text is wanted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
v0.1.0- First observed
download_file - First observed
get_course_materials - First observed
get_file_link - First observed
get_profile - First observed
get_upcoming_deadlines - First observed
list_courses - First observed
read_file_text
TDQS
Scored across 7 tools
Each tool targets a distinct action on a distinct resource, and the three file-facing tools (read_file_text, get_file_link, download_file) are explicitly differentiated in their descriptions by what they do with the file. The only mild overlap is that all three file tools take the same file_url from get_course_materials, but the boundary between reading, linking, and downloading is clear.
All seven names follow a consistent snake_case verb_noun pattern (get_profile, list_courses, get_course_materials, read_file_text, download_file). Verb choice is semantically meaningful and predictable: get_/list_ for metadata, read_ for content, download_ for local copy.
Seven tools is a tight, well-scoped set for an LMS course/materials assistant, with no redundant or filler operations. Each tool maps to a step in a plausible workflow (profile -> courses -> materials -> read/link/download), plus a deadline view.
The read path is complete end-to-end (courses, materials, file reading, linking, downloading, deadlines), but the surface is purely read-only with no grade listing, assignment submission, or announcement/forum access, which are core LMS workflows an agent would likely be asked about. These gaps will force workarounds or dead ends for common student requests.
Maintenance
Related MCP Connectors
Persistent memory, hybrid search and a goal graph for AI agents, over stdio or remote HTTP.
Talk to your public-facing AI from any MCP client — Claude, ChatGPT, Cursor, Cline, Windsurf.
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceA Model Context Protocol (MCP) server that connects AI coding agents to your Moodle LMS. Fetch assignments, grades, deadlines, and sync everything to Obsidian automatically.-
- FlicenseNot gradedqualityBmaintenanceEnables AI assistants to query and manage Moodle LMS data, including assignment deadlines, unread messages, unfinished quizzes, and enrolled courses, using natural language via OpenAI or local LLMs.-
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to sign into a real Moodle LMS and handle the student workflow end to end: browsing courses, schedules, forums and grades, converting assignments and attachments into markdown, and uploading and submitting work as drafts or finalized submissions. Ships as a single static binary with write actions confirmed by the user and quiz-taking deliberately excluded.27MIT
- AlicenseBqualityAmaintenanceConnects MCP-compatible AI clients to a university Moodle campus locally so users can query courses, assignments, materials, grades, forums, and calendar events, including reading attachments and PDFs. It is a read-only beta that does not modify the campus or store passwords.404MIT