PrepDeckBLOCK
A self-hosted exam prep platform with practice questions, mock exams, AI-powered explanations, and personalized progress tracking, built on Cloudflare.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
PrepDeck is a self-hosted, multi-exam study platform for a small invited group. Build a question bank, practice at your own pace, take timed mock exams, and turn mistakes into notes you can revisit. Study in the browser or connect an AI agent through dedicated User and Admin MCP endpoints.
The whole application runs on one Cloudflare Worker, with D1, R2 and KV. Direct Google sign-in and an application-managed allow-list control membership. AI explanations use your own OpenAI or Anthropic key.
Explore the features · Run locally · Architecture · Documentation · Contribute
Practice your way
Each exam has its own workspace, question bank and personal progress. Switch exams from the sidebar without losing your place, and pick the mode that suits the moment:
- Practice — untimed sessions filtered by domain, difficulty and source: every question, only unattempted ones, your bookmarks or your past mistakes. Get feedback after each answer or a summary at the end, skip back and forth freely, and stop whenever you like.
- Mock exam — a randomly drawn, timed run with a deadline the server enforces. Flag questions to revisit, ste
f022b6df464aOBSERVED · 2026-10-11Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control.
claude mcp add shared -- npx -y @prepdeck/[email protected]
{
"mcpServers": {
"shared": {
"command": "npx",
"args": [
"-y",
"@prepdeck/[email protected]"
]
}
}
}Exposed tools (1)
1 read · 0 write · 0 destructive.
| Tool | Risk | Description |
|---|---|---|
name | read | description |
Trust audit
BLOCKgrade F · trust 48/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (4 observation(s))
- Network
- declared (10 observation(s))
- Shell
- declared (4 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (25)
exec(input?: (string | URLPatternInit), baseURL?: string): URLPatternResult | null;
exec(cmd: string[], options?: ContainerExecOptions): Promise<ExecProcess>;
exec(query: string): Promise<D1ExecResult>;
console.log(`Local admin: ${ACCOUNT.email} / ${ACCOUNT.password}\nLocal user: ${USER_ACCOUNT.email} / ${USER_ACCOUNT.password}`);await page.goto(`http://127.0.0.1:${server.address().port}`);await page.goto(`http://127.0.0.1:${server.address().port}`); await ready();const base = `http://127.0.0.1:${server.address().port}`;await page.goto(`http://127.0.0.1:${server.address().port}`);await page.goto(`http://127.0.0.1:${server.address().port}`); await ready('A');const SECRET = "synthetic-test-session-key";
const SECRET = "0x4AAAAAAA-synthetic-secret-for-tests";
const TOKEN = "synthetic.turnstile.token.value";
streamable-http
.dev.vars.example
for target in ["absent.md", "../../prepdeck-admin/SKILL.md"]:
import { normalizeImportFile } from "../../../packages/shared/src/question-components.ts";const componentRows = ["code", "case-with-figure", "combination"].flatMap(name => normalizeImportFile(JSON.parse(readFileSync(new URL(`../../../tests/fixtures/components/${name}.json`, import.meta.urlimport { exportComponentPackage, normalizeImportFile } from '../../../packages/shared/src/question-components.ts';const complex = normalizeImportFile(JSON.parse(readFileSync(new URL('../../../tests/fixtures/components/case-with-figure.json', import.meta.url), 'utf8'))).questions[0];const binary = atob(b64);
const binary = atob(b64);
const binary = atob(b64);
const binary = atob(b64);
const binary = atob(b64);
"/questions/0/stem": ""
Gates applied: no_behavioural_pass.
f022b6df464afull audit observations/trust-audit/mcp-server/yizhongyue__prepdeck.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-11 | f022b6df464a | BLOCK | F | 48 | first audit |
Questions
What is the PrepDeck MCP server?
A self-hosted exam prep platform with practice questions, mock exams, AI-powered explanations, and personalized progress tracking, built on Cloudflare.
What tools does PrepDeck expose?
1 in total: 1 read-only, 0 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.
Is PrepDeck safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (48/100) and found 3 critical or high issues in the source. Each one is listed on this page with the file and line it is on.
What credentials does PrepDeck need?
No credential environment variables were found in its source, so it appears to need none.
How does PrepDeck run?
It speaks streamable-http, so it runs as a service you connect to over the network. It is published on npm as @prepdeck/shared at 0.1.0.
How current is this page?
The grade is for one exact copy of the source (f022b6df464a), read on 2026-10-11. The repository is watched and re-audited when it changes.