Atlas / MCP servers / yizhongyue / PrepDeck

PrepDeckBLOCK

mcp/yizhongyue/prepdeck

A self-hosted exam prep platform with practice questions, mock exams, AI-powered explanations, and personalized progress tracking, built on Cloudflare.

Verdict
BLOCK
Grade
F
Trust score
48 /100
Exposed tools
1 1r · 0w · 0d
Transport
streamable-http
License
MIT
Stars
0
01

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
Read from source at commit f022b6df464aOBSERVED · 2026-10-11
Advertisement
02

Connect

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-code
claude mcp add shared -- npx -y @prepdeck/[email protected]
claude-desktop
{
  "mcpServers": {
    "shared": {
      "command": "npx",
      "args": [
        "-y",
        "@prepdeck/[email protected]"
      ]
    }
  }
}
03

Exposed tools (1)

1 read · 0 write · 0 destructive.

ToolRiskDescription
namereaddescription
04

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.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (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)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
apps/worker/worker-configuration.d.ts:3187
exec(input?: (string | URLPatternInit), baseURL?: string): URLPatternResult | null;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
apps/worker/worker-configuration.d.ts:3489
exec(cmd: string[], options?: ContainerExecOptions): Promise<ExecProcess>;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
apps/worker/worker-configuration.d.ts:12621
exec(query: string): Promise<D1ExecResult>;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
scripts/local.mjs:110
console.log(`Local admin: ${ACCOUNT.email} / ${ACCOUNT.password}\nLocal user: ${USER_ACCOUNT.email} / ${USER_ACCOUNT.password}`);
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
apps/web/scripts/admin-console.browser.mjs:106
await page.goto(`http://127.0.0.1:${server.address().port}`);
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
apps/web/scripts/answer-state.browser.mjs:129
await page.goto(`http://127.0.0.1:${server.address().port}`); await ready();
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
apps/web/scripts/answer-state.browser.mjs:396
const base = `http://127.0.0.1:${server.address().port}`;
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
apps/web/scripts/component-annotations.browser.mjs:88
await page.goto(`http://127.0.0.1:${server.address().port}`);
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
apps/web/scripts/exam-workspace.browser.mjs:122
await page.goto(`http://127.0.0.1:${server.address().port}`); await ready('A');
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
apps/worker/scripts/session-lifecycle.test.mjs:19
const SECRET = "synthetic-test-session-key";
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
apps/worker/scripts/turnstile.test.mjs:22
const SECRET = "0x4AAAAAAA-synthetic-secret-for-tests";
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
apps/worker/scripts/turnstile.test.mjs:23
const TOKEN = "synthetic.turnstile.token.value";
MEDIUMAuth / authz · mcp.remote_no_auth · CWE-287, CWE-862
streamable-http
Why it matters. a network transport with no auth environment variable found
Fix. require a token
LOWInventory / provenance · inv.hidden_file · CWE-1104
apps/worker/.dev.vars.example
.dev.vars.example
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
.github/scripts/test_validate_skills.py:72
for target in ["absent.md", "../../prepdeck-admin/SKILL.md"]:
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
apps/web/scripts/answer-state.browser.mjs:6
import { normalizeImportFile } from "../../../packages/shared/src/question-components.ts";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
apps/web/scripts/answer-state.browser.mjs:336
const componentRows = ["code", "case-with-figure", "combination"].flatMap(name => normalizeImportFile(JSON.parse(readFileSync(new URL(`../../../tests/fixtures/components/${name}.json`, import.meta.url
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
apps/web/scripts/component-annotations.browser.mjs:9
import { exportComponentPackage, normalizeImportFile } from '../../../packages/shared/src/question-components.ts';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
apps/web/scripts/component-annotations.browser.mjs:18
const complex = normalizeImportFile(JSON.parse(readFileSync(new URL('../../../tests/fixtures/components/case-with-figure.json', import.meta.url), 'utf8'))).questions[0];
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
apps/worker/src/lib/google-oauth.ts:127
const binary = atob(b64);
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
apps/worker/src/lib/jwt-verify.ts:22
const binary = atob(b64);
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
apps/worker/src/lib/password.ts:17
const binary = atob(b64);
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
apps/worker/src/lib/session.ts:28
const binary = atob(b64);
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
apps/worker/src/lib/unsubscribeToken.ts:21
const binary = atob(b64);
LOWObfuscation / stealth · obf.zero_width · CWE-506, CWE-94
tests/fixtures/import-contract.json:566
"/questions/0/stem": ""

Gates applied: no_behavioural_pass.

Audited 2026-10-11 · audit v0.4.1 · source sha f022b6df464afull audit observations/trust-audit/mcp-server/yizhongyue__prepdeck.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-11f022b6df464aBLOCKF48first audit
06

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.

Advertisement