@quiz-builder/mcp-server
v0.1.0
Published
MCP server for the Quiz Builder GraphQL API. Lets AI agents (Claude Desktop, Cursor) operate quizzes scoped to one Organization via an OrgApiKey.
Maintainers
Readme
@quiz-builder/mcp-server
MCP server for the Quiz Builder GraphQL API. Lets AI agents (Claude Desktop, Cursor, any MCP-compatible client) operate quizzes scoped to one Organization via an OrgApiKey.
What it does
Once configured with an API key, the agent can:
- list / read / clone / create quizzes
- update a quiz's screen scheme (with server-side validation)
- publish / unpublish quizzes
- list themes, pricing packages, tracking pixels
- read built-in quiz templates
All operations are scoped to the Organization the API key was issued for. The server has no way to access data from other tenants — that boundary is enforced server-side, not on the client.
Setup
- Sign in to your Quiz Builder admin panel as an
ADMIN. - Open API Keys (
/admin/api-keys). - Click Create API key, give it a name (e.g. "Tolya's Claude Desktop"), pick scopes, optionally set an expiry.
- Copy the plaintext key from the success modal — it is only shown once.
- Add to your MCP client config:
Claude Desktop / Cursor
Heads-up: the
@quiz-builder/mcp-serverpackage is not yet published to the public npm registry. Until it is, install from a local clone:git clone https://github.com/egoraleron/quiz_builder cd quiz_builder/src/quiz-builder/packages/mcp-server-quiz-builder pnpm install && pnpm build npm link # makes `npx -y @quiz-builder/mcp-server` resolve from your machineOr skip the link and point
commandat the absolute path of the builtdist/index.js. If you just want to smoke-test the API key, the curl tab in the post-create modal of the admin panel works without any of this.
~/Library/Application Support/Claude/claude_desktop_config.json (Claude Desktop on macOS) or your editor's MCP config:
{
"mcpServers": {
"quiz-builder": {
"command": "npx",
"args": ["-y", "@quiz-builder/mcp-server"],
"env": {
"QUIZ_BUILDER_API_KEY": "qb_yourorg_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"QUIZ_BUILDER_API_URL": "https://builder.betterly.academy/api/graphql"
}
}
}
}The post-create modal in the admin panel pre-fills exactly this snippet with your key — copy and paste it directly.
Restart your MCP client. The agent now has tools prefixed list_flows, clone_flow, publish_flow, etc.
Environment variables
| Variable | Required | Default | Notes |
| ----------------------- | -------- | ------------------------------------------------ | ------------------------------------------- |
| QUIZ_BUILDER_API_KEY | yes | — | Must start with qb_. |
| QUIZ_BUILDER_API_URL | no | https://builder.betterly.academy/api/graphql | Override for staging or self-hosted setups. |
Tools
| Tool | Scope required | Description |
| --------------------- | --------------------- | ------------------------------------------------------------------------------------ |
| list_flows | flow:read | List quizzes (optional status filter). |
| get_flow | flow:read | Fetch a quiz with its full scheme by id or slug. |
| clone_flow | flow:clone / flow:create | Duplicate a quiz with a new slug. |
| create_flow | flow:create | Create a new quiz from a template id or scheme/config. |
| update_flow_scheme | flow:update | Replace a quiz's screen array. Server validates with Zod before persisting. |
| publish_flow | flow:publish | Publish: validates, uploads to CDN, snapshots a version. Optional changelog string. |
| unpublish_flow | flow:unpublish | Revert a published quiz to DRAFT and remove its CDN config. |
| list_themes | theme:read | List visual themes available to this org. |
| list_packages | package:read | List pricing packages. |
| list_pixels | pixel:read | List tracking pixels. |
| list_templates | template:read | List built-in quiz templates. |
| get_template | template:read | Fetch a template (with scheme) by slug. |
If a key is missing the required scope, the tool call fails with API key missing scope: <scope> — fix by revoking and re-issuing the key with the right scopes.
Out-of-scope (intentionally)
delete_flow— not exposed; deletes are permanent and should go through the admin UI.force_unlock— not exposed; takeover-of-someone-else's-edit-lock requires explicit admin intent.- Cross-org operations — every API key is mono-tenant.
- Image uploads — separate path that hasn't been wrapped yet.
These can be added to a key's scopes later if the workflow demands them; the server already supports the underlying GraphQL operations.
Local development
cd packages/mcp-server-quiz-builder
pnpm install
pnpm typecheck
pnpm dev # runs against process.env directly
pnpm build # emits dist/index.jsTo smoke-test against a local API:
QUIZ_BUILDER_API_KEY=qb_default_xxxx \
QUIZ_BUILDER_API_URL=http://localhost:3000/api/graphql \
node dist/index.jsThen connect from any MCP client pointed at the binary. The first list_tools request returns the catalog above.
Security model
- Plaintext keys are never stored — only their SHA-256 hash. Lose the key → revoke and re-issue.
- Keys carry an org id and a scope list. There is no escalation path: a key with
flow:readcannot publish a flow even if the agent tries. - Authentication failures (revoked / expired / unknown key) reject the request without falling through to anonymous access.
- Logs identify the principal as
apikey:<id>so abuse can be traced to a specific key without exposing the plaintext.
License
Internal — not published yet. Will go to npm under @quiz-builder/mcp-server once the product brand is finalised.
