MCP server providing access to Codeforces API for retrieving contest information, user statistics, submissions, and ratings
The server defines 9 tools with reasonable naming convention (verb_noun pattern) but suffers from significant gaps in schema quality, output documentation, and error handling. All tools are read-only with clear intent, but descriptions are terse (10-30 chars), parameter descriptions lack format guidance, and output schemas are completely undocumented. Tools return raw JSON strings rather than structured responses, and error handling is minimal (catch-all 'Error: {str(e)}' responses). No input validation, pagination limits, or recovery guidance. This is a typical community-grade server, functional but missing production-grade polish.
Get list of contests
Get rating changes after a contest
Get contest standings
Get contest submissions
Get list of rated users
Get recent submissions
Get user information
Output schema completely undocumented. All tools return `str` (raw JSON). LLMs cannot infer the structure of contest data, user objects, or standings. No documentation of which fields to expect or how to chain results to downstream tools.
Descriptions are critically short (10 - 30 chars), below the 34-char minimum for production tools. Examples: 'Get rating changes after a contest' (34 chars, borderline), 'Get user information' (19 chars), 'Get list of contests' (19 chars). LLMs receive minimal context for tool selection.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 41 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 45 | - | v1 |
Get user's rating history
Get user's submissions
Parameter descriptions are missing or incomplete. Example: `from_rank` has description 'Starting rank for results' but lacks format guidance (is this 1-indexed? 0-indexed? integer range?). `handles` parameter lacks format hint (comma-separated, max count?). No min/max constraints documented for numeric parameters (count, from_index).
Error handling is primitive. All tools catch exceptions and return a string 'Error: {str(e)}'. No distinction between retryable (network timeout) vs user-fixable (invalid contest_id) vs fatal errors. No recovery guidance (e.g. 'Contest not found. Try get_contest_list() first'). Bare exception strings are not LLM-actionable.
No pagination documentation or enforcement. Tools like get_recent_submissions(count) and get_contest_standings(count) accept arbitrary counts with no documented limits. LLMs could request 10,000 results, blowing up token usage and context windows. No total count, next_cursor, or offset patterns returned.
Tool responses are unstructured JSON strings, not parsed objects. Return type is `str` for all tools. LLMs must parse raw JSON manually, which is error-prone, wastes tokens, and blocks field-level extraction. Should return structured Pydantic models or dicts with typed fields.
Parameter 'count' in get_recent_submissions and get_user_submissions is required with no default. LLMs must always guess an appropriate value. Should provide a sensible default (e.g. count: int = 20) so simple calls work without reasoning overhead.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). While all tools are read-only, explicit annotations would clarify this to clients and enable optimization. Spec alignment deduction applies.