Skip to main content
Glama

Medify UCAT MCP Server

medify-mcp-server MCP server License: MIT

Model Context Protocol (MCP) server for Medify UCAT accounts. It authenticates as a member, pulls completed mock scores and practice analytics, and exposes tools for score trends, question-type weaknesses, timing sinks, and practice recommendations.

Medify does not publish a documented public API. This server talks to the same authenticated courses-api endpoints the Medify web app uses (member email/password or session cookie).

Unofficial. Not affiliated with or endorsed by Medify. Use only with accounts you own. Credentials stay on your machine.

Listed on Glama. Maintainer claim / release steps: docs/glama-release.md.

Features

  • List completed full / mini mocks with VR, DM, QR (and SJ when present)

  • Trend analysis: totals, section averages, recent vs earlier, best / worst

  • Topic analytics: subtype accuracy vs Medify population (e.g. logic puzzles, tables)

  • Question timing: clock usage, early/mid/late thirds, time sinks, fast guesses

  • Focus recommendations with optional cognitive target (e.g. 2250)

  • Local session + score cache under ~/.medify-mcp-server

Related MCP server: League of Legends MCP Server

Tools

Tool

Description

check_connection

Verify Medify authentication

list_completed_mocks

List completed mocks (full / mini / all)

get_mock_details

Detail for one mock by id or title

analyze_score_trends

Totals + section trends over time

analyze_section_performance

Rank VR / DM / QR (+ SJ when present)

analyze_topic_performance

Rank question subtypes vs population

analyze_question_timing

Timing / tag analysis from recent full mocks

recommend_focus_areas

Prioritised practice suggestions

compare_mocks

Diff two mocks

refresh_scores

Force re-fetch (bypass cache)

Requirements

  • Node.js 18+

  • A Medify UCAT membership with completed mocks

Setup

git clone https://github.com/ankitforcode/medify-mcp-server.git
cd medify-mcp-server
npm install
cp .env.example .env
# edit .env — set MEDIFY_EMAIL + MEDIFY_PASSWORD (or MEDIFY_SESSION_COOKIE)
npm run build

Environment

Variable

Required

Description

MEDIFY_EMAIL

one of email+password or cookie

Medify member email

MEDIFY_PASSWORD

with email

Medify password

MEDIFY_SESSION_COOKIE

alternative

Value of _medify_session_ from a logged-in browser

MEDIFY_CACHE_DIR

no

Cache directory (default ~/.medify-mcp-server)

MEDIFY_CACHE_TTL_MINUTES

no

Score cache TTL (default 15)

Prefer a session cookie if password login is blocked (captcha / MFA).

Cursor / MCP client config

Add a stdio MCP server entry (path and env are examples):

{
  "mcpServers": {
    "medify-ucat": {
      "command": "node",
      "args": ["/absolute/path/to/medify-mcp-server/dist/index.js"],
      "env": {
        "MEDIFY_EMAIL": "you@example.com",
        "MEDIFY_PASSWORD": "your-password"
      }
    }
  }
}

Or point env at a dotenv file you load yourself, and keep secrets out of the MCP config.

Restart the MCP client after changing config or rebuilding.

npx (after publish)

{
  "mcpServers": {
    "medify-ucat": {
      "command": "npx",
      "args": ["-y", "medify-mcp-server"],
      "env": {
        "MEDIFY_EMAIL": "you@example.com",
        "MEDIFY_PASSWORD": "your-password"
      }
    }
  }
}

Example prompts

  • “Check my Medify connection and list completed UCAT mocks.”

  • “Analyse score trends and section strengths for full mocks only.”

  • “Which question types am I weakest on vs the Medify population?”

  • “Where do I lose time in VR, DM, and QR on recent full mocks?”

  • “Recommend focus areas for a 2250 cognitive target; ignore SJ.”

  • “Compare Mock 10 and Mock 11.”

Development

npm run build
npm test
npm start          # stdio MCP server

Project layout:

src/
  index.ts           # MCP stdio entry
  medify/            # auth client, fetch, normalize
  analysis/          # trends, topics, timing, recommendations
  tools/             # MCP tool schemas + handlers
.cursor/skills/
  medify-ucat-analysis/   # agent skill: run score/timing reports via MCP
  medify-mcp-maintain/    # agent skill: change this codebase safely

When you add or change MCP tools, update both skills (and tools-reference.md) in the same PR.

How it works

  1. Authenticate via Devise login or an injected _medify_session_ cookie.

  2. Read scaled scores from /courses-api/mock-scores-stats?course=ucat.

  3. Optionally load JSON:API scripts from /courses-api/mock-exam-scripts for timing.

  4. Read practice analytics from /courses-api/courses/ucat/topic-performances.

  5. Cache mocks locally; analysis tools run on the cached / freshly fetched data.

Security

  • Never commit .env or session cookies.

  • Treat Medify credentials like any other account secret.

  • This tool only reads account data needed for score analysis; it does not submit mocks.

License

MIT — see LICENSE.

Available Tools

10 tools
analyze_question_timingA

Analyse per-question timing from recent full mocks: section clock usage, early/mid/late thirds, weakest tags, time sinks (slow zeros), and fast guesses (sub-budget zeros). Use when the user asks about pacing, running out of time, or rushing. Not a substitute for score trends or topic accuracy rankings. limit = number of recent full mocks to inspect (1–15, default 10). minN filters tag rankings. forceRefresh refreshes the mock list first. Read-only. Loads script details (questions + timings) from Medify courses-api; may be slower than score-only tools.

Inputs: minN, limit, forceRefresh.

analyze_section_performanceA

Rank VR, DM, and QR strengths and weaknesses from completed Medify UCAT mocks, with an SJ band summary when SJ scores exist. Use to answer “which section is weakest?” before recommending drills. Does not break down question subtypes — use analyze_topic_performance for that. kind selects full/mini/all mocks (default all). forceRefresh bypasses cache. Read-only. Returns ranked sections with averages and relative standing; SJ is summarised separately and not folded into cognitive totals.

Inputs: kind, forceRefresh.

analyze_topic_performanceA

Rank Medify UCAT question subtypes (e.g. logic puzzles, tables, VR without keywords, text/visual inference) by personal accuracy versus Medify population averages. Best tool for “what should I drill?” at the question-type level. Complements analyze_section_performance (sections) and analyze_question_timing (clock). includeSj defaults false (omit Situational Judgement). minN drops sparse subtypes (default 10 attempts). Read-only. Fetches live topic-performances from Medify (includes practice history aggregated by Medify, not only mocks).

Inputs: minN, includeSj.

check_connectionA

Verify that Medify authentication works and the UCAT courses-api score endpoint is reachable for this account. Call this first when setup fails, after changing MEDIFY_EMAIL/MEDIFY_PASSWORD/MEDIFY_SESSION_COOKIE, or before trusting other tools. Returns ok/authenticated flags, whether email or cookie env is configured, and a human-readable message. Does not list mocks or modify cache. Requires network access to app.medify.co; succeeds from a persisted session jar even if env credentials are unset.

Inputs: no named parameters.

compare_mocksA

Compare two completed Medify UCAT mocks section-by-section and by cognitive total (VR+DM+QR). Use when the user names two sits (ids or titles). For overall history use analyze_score_trends; for one mock use get_mock_details. idA and idB accept mock id, compositeId, or exact title. forceRefresh reloads the list before resolving idA. Read-only. Returns found=false with missing ids if either mock cannot be resolved; otherwise a structured section/total diff.

Inputs: idA (required), idB (required), forceRefresh.

get_mock_detailsA

Get detailed scores for one completed Medify UCAT mock looked up by id, compositeId, or exact title. Use after list_completed_mocks when you need a single sit (e.g. “Mock 12”). For side-by-side diffs use compare_mocks instead. Returns section scores, totals, dates, and optional raw fields. Missing id throws; unknown id returns not-found style result from the handler. Read-only. forceRefresh refreshes the mock list cache before lookup.

Inputs: id (required), includeRaw, forceRefresh.

list_completed_mocksA

List completed Medify UCAT mocks for the signed-in account with section scores (VR/DM/QR, SJ when present) and cognitive totals. Use for inventory (“what have I sat?”) before trends or comparisons. Prefer analyze_* tools when you need ranked insights rather than a raw list. kind filters full mocks, mini-mocks, or all (default all). forceRefresh bypasses the local cache; includeRaw adds Medify payload fields for debugging. Read-only. Returns mocks plus cached/fetchedAt metadata. Empty list means no completed mocks or auth failed — call check_connection.

Inputs: kind, includeRaw, forceRefresh.

recommend_focus_areasA

Recommend prioritised UCAT practice focus areas from mock history (weakest sections, declining trends, optional gap to a cognitive target). Use for a practice plan. For evidence behind the plan, also call analyze_topic_performance and/or analyze_question_timing. kind filters mocks. includeSj defaults true for SJ advice — set false for cognitive-only plans. targetTotal (e.g. 2250) adds a VR+DM+QR gap recommendation. Read-only. Returns ordered recommendations with reasons/suggestions plus a short summary. Does not create Medify practice sets.

Inputs: kind, includeSj, targetTotal, forceRefresh.

refresh_scoresA

Force re-fetch completed mock scores from Medify and update the local cache under MEDIFY_CACHE_DIR (default ~/.medify-mcp-server). Call after finishing a new mock when other tools still show stale data, or when cache TTL has not expired yet. Returns fetch metadata (count/fetchedAt). Does not analyse scores — pair with analyze_score_trends or list_completed_mocks afterward. Requires valid Medify auth. Overwrites the cached mock list only; does not change Medify account data.

Inputs: no named parameters.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.8/5.0

    Scored across 10 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose: auth check, list mocks, get details, various analyses (trends, sections, topics, timing), recommendations, comparison, and cache refresh. No overlap.

    Naming Consistency5/5

    All tools follow a consistent verb_noun pattern in snake_case (e.g., check_connection, list_completed_mocks, analyze_score_trends). Naming is predictable and clear.

    Tool Count5/5

    10 tools is well-scoped for UCAT analysis, covering browsing, detailed inspection, multiple analytical angles, recommendations, and cache management without redundancy.

    Completeness5/5

    The tool surface comprehensively covers the domain: listing, details, trends, section/topic/timing analysis, comparison, recommendations, and cache refresh. No obvious gaps for a read-only analysis server.

    Maintenance

    ActivityInactive
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers