|
| 1 | +# mpak Technical Assessment |
| 2 | + |
| 3 | +**Date:** 2026-02-10 |
| 4 | +**Assessor:** Cold-start codebase analysis |
| 5 | +**Scope:** Full project (schemas, SDK, CLI, registry, web, scanner, docs, deploy) |
| 6 | + |
| 7 | +## Reconciliation |
| 8 | + |
| 9 | +**Reconciled:** 2026-02-10, code review against codebase. |
| 10 | + |
| 11 | +Findings: |
| 12 | +- 5 items already fixed in code (#3, #4, #7, #9, #10) that the original assessment missed |
| 13 | +- CI pipeline (#2) exists with lint/typecheck/test jobs |
| 14 | +- TOCTOU (#6) mitigated with pre-check + transaction wrapping |
| 15 | + |
| 16 | +Work completed in this session: |
| 17 | +- #1: Registry test suite added (62 tests across 5 files: errors, oidc, bundles, scanner, health) |
| 18 | +- #5: Filename sanitization added to announce endpoint (path traversal, extension, length checks) |
| 19 | +- #8: ZIP bomb protection added to CLI bundle extraction (500MB uncompressed size limit) |
| 20 | +- #12: CODE_OF_CONDUCT.md created (SECURITY.md already existed) |
| 21 | +- #15: Shell completions added for bash, zsh, fish |
| 22 | +- #16: Rate limiting added (global 100/min, scoped 10/min for /v1/bundles and /v1/skills) |
| 23 | +- 6 items remain open (#11, #13, #14, #17, #18, #19, #20, #21) |
| 24 | + |
| 25 | +## Executive Summary |
| 26 | + |
| 27 | +mpak is a purpose-built package registry for MCP servers with security scanning as a first-class feature. The architecture is thoughtful (layered monorepo, OIDC-only publishing, 25-control trust framework), but the project is pre-launch (14 commits, single contributor, v0.0.0). Core gaps are: no registry tests, no CI pipeline, and several security hardening items that should be resolved before production traffic. |
| 28 | + |
| 29 | +## Strengths |
| 30 | + |
| 31 | +- Clean layered architecture (schemas -> SDK -> CLI, registry standalone) |
| 32 | +- OIDC-only publishing eliminates long-lived API keys |
| 33 | +- Sophisticated scanner with MCP-specific controls (prompt injection detection, undeclared permission scoping) |
| 34 | +- Production deployment story (Helm chart with HPA, security contexts, rate limiting) |
| 35 | +- Comprehensive documentation (36 Starlight pages) |
| 36 | +- Skills concept (knowledge distribution alongside tool distribution) |
| 37 | + |
| 38 | +## Gaps by Priority |
| 39 | + |
| 40 | +### P0: Ship-Blocking |
| 41 | + |
| 42 | +| # | Issue | Location | Effort | Status | |
| 43 | +|---|-------|----------|--------|--------| |
| 44 | +| 1 | Registry server has ~0 test coverage | `apps/registry/tests/` | Large | DONE | |
| 45 | +| 2 | No CI pipeline beyond docs deploy | `.github/workflows/` | Small | DONE | |
| 46 | +| 3 | Scanner callback uses non-constant-time string comparison | `apps/registry/src/routes/scanner.ts` | Trivial | FIXED | |
| 47 | + |
| 48 | +### P1: Pre-Production Quality |
| 49 | + |
| 50 | +| # | Issue | Location | Effort | Status | |
| 51 | +|---|-------|----------|--------|--------| |
| 52 | +| 4 | JWKS not cached in OIDC verification | `apps/registry/src/lib/oidc.ts` | Trivial | FIXED | |
| 53 | +| 5 | Announce endpoint accepts unvalidated os/arch/filename | `apps/registry/src/routes/v1/bundles.ts` | Small | DONE | |
| 54 | +| 6 | TOCTOU race in web publish flow | `apps/registry/src/routes/packages.ts` | Small | MITIGATED | |
| 55 | +| 7 | Search endpoints accept negative limit/offset | `apps/registry/src/routes/v1/bundles.ts` | Trivial | FIXED | |
| 56 | + |
| 57 | +### P2: Security Hardening |
| 58 | + |
| 59 | +| # | Issue | Location | Effort | Status | |
| 60 | +|---|-------|----------|--------|--------| |
| 61 | +| 8 | ZIP extraction has no decompression bomb protection | `packages/cli/src/commands/packages/run.ts` | Small | DONE | |
| 62 | +| 9 | Scanner callback has no idempotency check | `apps/registry/src/routes/scanner.ts` | Trivial | FIXED | |
| 63 | +| 10 | README rendering should explicitly disable HTML | `apps/web/src/pages/PackageDetailPage.tsx` | Trivial | FIXED | |
| 64 | +| 11 | 10 of 25 scanner controls are stubs | `apps/scanner/` | Large | OPEN | |
| 65 | + |
| 66 | +### P3: DX & OSS Readiness |
| 67 | + |
| 68 | +| # | Issue | Location | Effort | Status | |
| 69 | +|---|-------|----------|--------|--------| |
| 70 | +| 12 | Missing SECURITY.md and CODE_OF_CONDUCT.md | repo root | Small | DONE | |
| 71 | +| 13 | Web app has zero tests | `apps/web/` | Medium | OPEN | |
| 72 | +| 14 | CSR-only web app hurts discoverability | `apps/web/` | Large | OPEN | |
| 73 | +| 15 | No shell completions for CLI | `packages/cli/` | Small | DONE | |
| 74 | +| 16 | No API rate limiting at application level | `apps/registry/` | Small | DONE | |
| 75 | +| 17 | No release cut (v0.1.0) | repo root | Trivial | OPEN | |
| 76 | + |
| 77 | +### P4: Polish |
| 78 | + |
| 79 | +| # | Issue | Location | Effort | Status | |
| 80 | +|---|-------|----------|--------|--------| |
| 81 | +| 18 | CLI error messages lack suggestions | `packages/cli/` | Small | OPEN | |
| 82 | +| 19 | Download count tracking not transactional | `apps/registry/src/routes/` | Trivial | OPEN | |
| 83 | +| 20 | Missing package.json metadata on schemas | `packages/schemas/package.json` | Trivial | OPEN | |
| 84 | +| 21 | No architecture decision records | repo root | Medium | OPEN | |
| 85 | + |
| 86 | +## Quick Wins (< 1 hour each) |
| 87 | + |
| 88 | +Items 17, 19, 20 remain as quick wins. Items 2, 3, 4, 7, 9, 10 were already resolved before this session. Items 1, 5, 8, 12, 15, 16 were resolved in this session. |
| 89 | + |
| 90 | +## Architecture Notes |
| 91 | + |
| 92 | +- **Monorepo:** pnpm workspaces + Turborepo |
| 93 | +- **Dep graph:** schemas -> SDK -> CLI; schemas -> registry; web standalone; scanner standalone Python |
| 94 | +- **Auth:** Clerk (web), GitHub OIDC (publish) |
| 95 | +- **Storage:** Local (dev) / S3+CloudFront (prod) |
| 96 | +- **Scanner:** Python 3.13+, runs as K8s Job, 25 MTF controls across 5 domains |
| 97 | +- **Web:** React SPA (Vite + Tailwind 4 + TanStack Query + Clerk) |
| 98 | +- **Docs:** Astro Starlight on GitHub Pages |
0 commit comments