MCP server that provides access to InterviewReady platform data including courses, blog posts, resources, and reminders
InterviewReady MCP Server shows moderate definition quality with inconsistent patterns across tools. All 10 tools have descriptions and basic schemas using Zod validation, but descriptions are often too brief (10-40 chars, below the 50-200 char baseline for LLM optimization), parameter descriptions lack detail about constraints and formats, and output schemas are not documented. The server uses consistent verb-noun naming ('get-*', 'create-reminder') which is good, but parameter annotations are sparse. Error handling exists via withError middleware but provides only generic JSON responses without actionable recovery guidance. No tool annotations (readOnlyHint/destructiveHint) are present despite having READ_ONLY and WRITE risk classifications. Schema definitions use Zod which compiles to JSON Schema but lack explicit documentation of output structures, limiting downstream tool chaining and LLM planning.
Get content of a blog post by title
Set a reminder for an upcoming class or deadline
Get a blog post by keywords
Get a blog post by slug
Get a blog post by title
Get all blog posts on interviewready platform
Get a course by id
Descriptions too brief and not LLM-optimized. 4 tools ('get-blog-posts', 'get-courses', 'get-resources', 'get-reminders') have descriptions under 30 characters. Baseline is 50-200 chars for LLM decision-making. Example: 'Get all blog posts on interviewready platform' (47 chars) lacks context on when to use vs alternatives like 'blog-content' or why the agent would call this tool.
Output schemas not documented. All tools return {content: [{type: 'text', text: string}]} but the actual field structure inside 'text' is not documented. For example, 'get-blog-posts' returns JSON-stringified objects with fields like 'slug', 'title', 'keywords', 'url', but this is invisible to LLMs planning downstream tool calls. Agents cannot extract returned data reliably without knowing the schema.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 55 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 51 | - | v1 |
Get all courses on interviewready platform
Get all reminders
Get all external resources recommended by interviewready platform
Parameter descriptions lack constraint details. 'slug' in 'get-blog-post-by-slug' has description 'The slug of the blog post to get' but no format examples, length limits, or character restrictions. 'datetime' in 'create-reminder' requires ISO format but description just says 'ISO datetime for the reminder' without specifying why ISO (vs Unix timestamp) or example format '2024-01-15T14:30:00Z'. Baseline: 72 chars for param annotations.
No tool annotations despite documented risk classifications. Tools are marked READ_ONLY or WRITE in the risk model, but no readOnlyHint, destructiveHint, or idempotentHint annotations are present in the code. This prevents LLMs from understanding which tools are safe to retry on failure vs which have irreversible side effects. 'create-reminder' especially needs a destructiveHint=true to signal it modifies state.
Error handling provides no recovery guidance. withError middleware wraps all tools but returns generic JSON responses without actionable next steps. For example, when 'get-blog-post-by-slug' returns 'No blog post found', the LLM does not know if it should retry, try a different slug, or call 'search-blog-posts' first. Error responses should classify as retryable/user-fixable/fatal and suggest alternatives.
Missing pagination for list tools returning unbounded results. 'get-blog-posts', 'get-courses', and 'get-resources' have no limit, offset, or page parameters and no documented result count limits. If a platform has 100+ blog posts or courses, returning all items in one call will exhaust context windows and degrade LLM reasoning. Baseline: production tools cap results at 20-50 with pagination.
Naming ambiguity: 'blog-content' vs 'get-blog-post-by-title'. Both accept a title parameter and return blog data, but 'blog-content' specifically returns plaintext body while 'get-blog-post-by-title' returns full structured metadata. The distinction is not obvious from names alone. LLMs may conflate them or choose wrong tool. Should rename to 'get-blog-post-body' or 'get-blog-post-plaintext' to clarify intent.