Skip to content

feat: expose password generator as an MCP server (remote + stdio)#1

Merged
JakeAve merged 3 commits into
mainfrom
feat/mcp-server
May 30, 2026
Merged

feat: expose password generator as an MCP server (remote + stdio)#1
JakeAve merged 3 commits into
mainfrom
feat/mcp-server

Conversation

@JakeAve

@JakeAve JakeAve commented May 30, 2026

Copy link
Copy Markdown
Owner

What

Exposes the password generator as a Model Context Protocol server alongside the existing REST API, sharing one generation core. Two tools: generate_password and list_charset_presets, available over both transports.

Changes

  • Core: lib/password-core.ts — transport-agnostic generatePasswords/listPresets with typed errors + bounds. The REST route is now a thin adapter over it.
  • MCP: lib/mcp-server.ts (createServer()), mcp/stdio.ts (local stdio), routes/mcp.ts (remote Streamable HTTP, stateless + JSON mode).
  • SDK glue: lib/mcp-sdk.ts centralizes the @deno-types workaround for the SDK's broken exports types wildcard; vite.config.ts adds ssr.external so dev SSR can load the SDK; main.ts exempts /mcp from the page CSP.
  • Fix: /api/generate now uses Fresh 2's ctx.req (was relying on a Request/Context .url coincidence). The unit-test mock now passes a Context, so it genuinely guards the signature.
  • Tests: new e2e/ suite exercising stdio, prod-build, and vite-dev /mcp over real MCP clients. deno task test (unit) and deno task test:e2e (build + e2e) are now separate.
  • CI: GitHub Actions — check + unit and e2e jobs.
  • Docs: README "MCP server" section for both transports.

Verification

  • deno task check clean · 60 unit tests · 3 e2e tests (11 steps) · live REST + MCP checked against a real deno serve.
  • The dev e2e test was confirmed to fail without ssr.external and pass with it.

🤖 Generated with Claude Code

JakeAve and others added 3 commits May 30, 2026 00:06
Add a Model Context Protocol server alongside the existing REST API,
sharing a single generation core. Two tools: generate_password and
list_charset_presets.

- lib/password-core.ts: transport-agnostic generatePasswords/listPresets
  with typed errors and bounds; the REST route becomes a thin adapter
- lib/mcp-server.ts: createServer() registering both tools
- mcp/stdio.ts: local stdio entry point
- routes/mcp.ts: remote Streamable HTTP endpoint (stateless, JSON mode)
- lib/mcp-sdk.ts: centralizes the SDK's @deno-types workaround for the
  broken exports types wildcard
- vite.config.ts: ssr.external for the SDK so dev SSR can load it
- main.ts: exempt /mcp from the page-oriented CSP

Also:
- fix: use Fresh 2's ctx.req in /api/generate (it was relying on a
  Request/Context .url coincidence); the unit-test mock now passes a
  Context so it genuinely guards the signature
- test: add e2e suite (e2e/) exercising stdio, prod-build, and vite-dev
  /mcp over real MCP clients; split `deno task test` (unit) from
  `deno task test:e2e`
- ci: add GitHub Actions workflow (check+unit and e2e jobs)
- docs: README "MCP server" section for both transports

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
vite's dev server is slow/flaky to start in a headless CI runner (it timed
out reporting its port within 30s), while CI already validates the
deployment artifact via the prod-build and stdio e2e tests plus the
`vite build` step. The dev test's real purpose is guarding `ssr.external`
during local development, so it now runs everywhere except CI.

Also: the server helper now includes the child's recent output in its
timeout error and allows 60s, so a slow/failed startup is debuggable.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@JakeAve JakeAve merged commit c9fa0dd into main May 30, 2026
3 checks passed
@JakeAve JakeAve deleted the feat/mcp-server branch May 30, 2026 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant