This MCP server exposes 33 tools for interacting with a school portal (N Lobby). While tool names follow verb_noun conventions and most have basic descriptions, the implementation has significant quality gaps: (1) Input schemas are sparse or missing for most tools, most parameters lack type definitions or are declared as generic 'object' types; (2) Descriptions are frequently vague, generic, or under 50 characters, violating the 10 - 1024 character guideline and lacking WHEN/WHY context that LLMs need for tool selection; (3) Output schemas are entirely undocumented, there is no evidence of structured return types or field documentation; (4) Parameter descriptions are minimal or absent for optional parameters; (5) Error handling is generic (McpError with brief messages) without recovery guidance; (6) No clear idempotency semantics or confirmation patterns for destructive operations. The server appears functional for basic use cases but falls short of production-grade tool quality expected for agent integration.
Tools (33)
debug_connectionread only47/100
Debug connection issues and authentication state
download_news_attachmentwriteauth50/100
Download an attachment from a news item
finish_exam_day_modewriteauth43/100
Exit exam day mode
get_account_info_from_scriptread onlyauth48/100
Extract account information from page scripts
get_cookie_statusread only50/100
Check authentication cookie status and synchronization
get_designated_schoolread onlyauth47/100
Get information about designated schools
get_exam_one_time_passwordread onlyauth45/100
Get one-time password for exam access
get_google_calendar_eventsread onlyauth50/100
Get Google Calendar events synchronized with school calendar
Input schemas severely incomplete: 25 of 33 tools declare parameters as generic 'object' type with no field-level type or structure definition. Example: get_news accepts {'options': {'type': 'object', 'description': 'Optional filters...'}}, no nested schema, no field names, no enums or constraints.
Expand every parameter schema from 'type: object' to a full JSON Schema with field definitions, types, and descriptions. Example: Instead of {'options': {'type': 'object'}}, define {'options': {'type': 'object', 'properties': {'limit': {'type': 'integer', 'minimum': 1, 'maximum': 100, 'default': 20, 'description': 'Number of items to return'}, 'offset': {'type': 'integer', 'minimum': 0, 'description': 'Starting position for pagination'}}, 'additionalProperties': false}}.
Rewrite tool descriptions to be 50 - 200 characters and answer WHAT/WHEN/WHY. Example: Instead of 'Get information about unread news items', write 'Fetch a summary of unread news items including count and preview. Use this to tell the user how many unread notifications they have without fetching full details.'
Document output schemas for each tool in the tool definition or a separate schema document. Include field names, types, and examples. Example: 'Returns {"items": [{"id": string, "title": string, "date": string (ISO 8601), "read": boolean}], "total": integer, "unread_count": integer}'.
Add nested parameter descriptions with format constraints. For 'dateRange', specify: '{"start": string (ISO 8601, required), "end": string (ISO 8601, required)}' and explain what dates outside the range mean.
Implement idempotent operation patterns for write tools: add an 'idempotent' flag or 'operation_id' field to set_cookies, mark_news_as_read, finish_exam_day_mode, and update_last_access. Document that repeated calls with the same ID produce no side effects.
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Score history
Overall score trend
First recorded score · v2 rubric
40/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-23
F
40
<=2025-11-25
v2
get_interest_weightsread onlyauth43/100
Get weighted scores for user interests
get_learning_resourcesread onlyauth50/100
Get learning materials, assignments, and study resources
get_lobby_calendar_filtersread onlyauth43/100
Get available calendar filter options
get_main_navigationsread onlyauth45/100
Get main navigation menu categories
get_newsread onlyauth50/100
Fetch latest school news and announcements
get_news_detailread onlyauth50/100
Get detailed information about a specific news item
get_notification_messagesread onlyauth45/100
Get notification messages from the system
get_required_coursesread onlyauth45/100
Get list of required courses and academic information
get_scheduleread onlyauth50/100
Get school schedule and calendar events
get_schedule_by_dateread onlyauth50/100
Get schedule for a specific date
get_schoolingread onlyauth48/100
Get list of schooling entries and learning activities
get_schooling_detailread onlyauth50/100
Get detailed information about a specific schooling entry
get_student_card_screenshotread onlyauth45/100
Capture a screenshot of the student ID card from secure portal
get_unread_news_inforead onlyauth47/100
Get information about unread news items
get_user_inforead onlyauth47/100
Get current user information and profile details
get_user_interestsread onlyauth45/100
Get user interest preferences
health_checkread onlyauth47/100
Perform health check on server connectivity
interactive_loginwrite50/100
Perform interactive browser-based login to N Lobby
is_exam_dayread onlyauth50/100
Check if a specific date is an exam day
mark_news_as_readwriteauth50/100
Mark a news item as read
set_cookieswrite50/100
Set authentication cookies for API access
test_calendar_endpointsread onlyauth45/100
Test calendar endpoint connectivity and data retrieval
Tool descriptions lack depth and context. Most are 35 - 50 characters and do not answer WHAT/WHEN/WHY or dependencies. Example: 'Get information about unread news items' (43 chars) tells the agent nothing about when to call it vs get_news(), what fields are returned, or what the data structure looks like.
No documented output schemas. The code shows tools return results via 'return await handler(this.ctx, args)' but there is no type documentation, field reference, or example structure visible. LLMs cannot plan downstream tool calls or extract fields without knowing the response shape.
Parameter descriptions are missing or trivial for many optional parameters. Examples: 'dateRange' in get_schedule described only as 'Optional date range filter' (33 chars), no guidance on format, structure, or field names. 'endpoint' in get_account_info_from_script described only as 'Optional endpoint to extract from (default '/')' (59 chars), no hint about valid values or URL format.
No idempotency or confirmation semantics for destructive operations. Tools like mark_news_as_read, finish_exam_day_mode, set_cookies, and update_last_access modify state but lack idempotent hints, dry-run support, or confirmation-before-execute patterns. An agent retry could cause unintended side effects.
Error handling is generic and non-actionable. All tools throw McpError(ErrorCode.InternalError, 'Tool execution failed: <message>') with no recovery guidance, categorization (retryable vs user-fixable), or context about what went wrong. Examples: 'Failed to read resource: Unknown error' provides no hint for the agent to retry or adjust parameters.
Naming clarity issue: get_main_navigations, get_notification_messages, get_user_interests, get_interest_weights are domain-specific names that conflate multiple concerns or lack distinction. For example, 'get_user_interests' vs 'get_interest_weights' are not clearly differentiated, the descriptions do not explain the functional distinction or when to call each.
Testing/debug tools mixed with production tools. get_schedule, test_calendar_endpoints, test_page_content, test_trpc_endpoint, health_check, debug_connection are testing utilities that should not be exposed to end-user agents. They add cognitive load and no value to production workflows.
No pagination or result limits documented. Tools like get_news, get_schedule, get_learning_resources, and get_schooling accept 'options' parameters but do not document limit/offset/cursor behavior. If these return dozens of items, the response could blow token budgets with no guidance on pagination.
Enhance error handling to return typed errors with recovery guidance. Example: Instead of 'Tool execution failed: User not found', return '{"error": "user_not_found", "message": "User could not be retrieved. Try calling get_user_info() first to verify credentials, or check that the user ID is correct. Available alternatives: <list>}'.
Remove or gate testing/debug tools (test_calendar_endpoints, test_page_content, test_trpc_endpoint, health_check, debug_connection) behind a feature flag or separate tool list. These should not be exposed to production agent interactions.
Document pagination behavior explicitly. For tools accepting 'options', add examples: 'Example: {"limit": 20, "offset": 0} returns 20 items starting at position 0. If total > 20, use offset += 20 to fetch the next page.'
Use enums for finite-choice parameters. Example: For calendarType in get_schedule, use {'type': 'string', 'enum': ['PERSONAL', 'SCHOOL'], 'description': '...'} instead of a free-form string description.
Split tools with ambiguous names. Example: 'get_interest_weights' should be 'get_user_interest_scores' or 'compute_interest_ranking' to clarify it returns computed scores, not raw preferences.