MCP server reference#
QuizBase exposes the public catalog over Model Context Protocol — Streamable HTTP transport, MCP spec 2025-11-25.
| Endpoint | https://quizbase.runriva.com/mcp |
| Auth | Authorization: Bearer qb_(test\|live)_(pk\|sk)_* |
| Discovery | /.well-known/oauth-protected-resource (RFC 9728) |
| Transport | Streamable HTTP, JSON response (no SSE streaming — tools are synchronous) |
| Rate limit | Same as REST. 1 tools/call = 1 request against your tier (free 10/10s, indie 30/10s, pro 200/10s). |
For step-by-step setup in Claude.ai / Cursor / Inspector see the MCP guide.
Tools (11)#
Every tool wraps the matching /api/v1/* endpoint with the same query semantics. EN-only descriptions for LLM-aware language; output language is controlled by the lang argument.
| Tool | Wraps | Input shape (selected) |
|---|---|---|
quizbase_random | /v1/questions/random | amount (1-50), lang, category, difficulty, type, subcategory, tags_any, topics_any, exclude |
quizbase_list | /v1/questions | lang, filter set, cursor, limit (1-100), updated_since, count (estimate | exact | none) |
quizbase_question_by_id | /v1/questions/:id | id (UUID), lang |
quizbase_stats | /v1/stats | lang |
quizbase_topics | /v1/topics | q, kind (tag|subcategory), cursor, limit (1-500) |
quizbase_topic_by_slug | /v1/topics/:slug | slug, lang |
quizbase_tags | /v1/tags | q, cursor, limit |
quizbase_subcategories | /v1/subcategories | q, cursor, limit |
quizbase_categories | /v1/categories | lang |
quizbase_languages | /v1/languages | lang |
quizbase_report | POST /v1/report | one of (questionId, questionText, questionUrl), type, comment, reporterEmail |
Output format#
Every tool returns CallToolResult with both representations for client compatibility:
content[0].text— JSON-stringified payload (for clients on SDK older than 1.18)structuredContent— typed object (preferred, parsed withoutJSON.parse)
Tools quizbase_random / quizbase_list return aggregated attribution on the top level:
{
"questions": [{ "id": "…", "text": "…", "correctAnswer": "…", … }],
"attribution": [
{ "source": "opentdb", "license": "CC-BY-SA-4.0", "authors": ["…"], "count": 3 }
],
"meta": { "count": 3, "language": "pl", "nextCursor": null }
} quizbase_question_by_id keeps per-question full attribution (modifications, sourceId, url, lastModified) — aggregation makes no sense for a single record.
Tool errors#
When a tool can’t fulfil a request (e.g. UUID not found, invalid input, rate limit), the result is marked with isError: true and the payload contains an error code:
{
"isError": true,
"content": [{ "type": "text", "text": "{ "error": "not_found", "message": "…" }" }],
"structuredContent": { "error": "not_found", "message": "…", "id": "…" }
} Codes: not_found, invalid_input, rate_limit_exceeded, internal_error. Auth failures (401) and rate-limit on the API key (429) are handled at the HTTP layer — your MCP client surfaces them as protocol errors.
Resources (3)#
Static MCP resources cached by URI. For non-default language use the matching tool with a lang argument.
| URI | Returns |
|---|---|
mcp://quizbase/categories | List of 24 top-level categories (English labels) |
mcp://quizbase/languages | Supported languages whitelist + question counts |
mcp://quizbase/topics/top-100 | Top-100 curated topics by question count (English labels) |
mimeType is always application/json.
Prompts (3)#
Curated workflow templates for LLM agents. Arguments are strings (per MCP spec); the prompt template injects them into a user message with a step-by-step plan invoking the tools above.
| Prompt | Arguments | What it does |
|---|---|---|
build_quiz | topic, lang, difficulty?, rounds, questions_per_round | Multi-round quiz orchestration. Resolves the topic, then fetches questions per round, collects aggregated attribution. |
explore_topic | topic, lang | Discursive topic exploration — facets (byCategory, byDifficulty, coOccurringTags) + sample questions. |
warmup_round | topic?, lang | Lightweight 5-question icebreaker. Single tool call, no multi-round orchestration. |
Authentication and security#
- Use
pkkeys for Custom Connectors.skkeys work but are intended for server-side agents. - DNS rebinding — only
quizbase.runriva.com,localhost(:port), and*.up.railway.appHostheaders are accepted; others get 403. - CORS — allow-list of
claude.ai,app.cursor.sh, andlocalhost. Server-side clients (noOriginheader) are unaffected. WWW-Authenticateon 401 — includes aresource_metadatalink to the RFC 9728 PRM endpoint so clients can discover where to obtain credentials.
Versioning#
The MCP server tracks the same major version as /api/v1/*. Tool inputs / outputs are additive within a major; a breaking change would bump to a new path (/mcp/v2/). The current spec is 2025-11-25; the SDK we run is @modelcontextprotocol/sdk@^1.29.
See also#
- MCP guide — step-by-step setup for Claude.ai / Cursor / Inspector
- Authentication — key types and rotation