Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/backend/.env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PROCESS_NAME=actionhero-server
PROCESS_NAME=keryx
PROCESS_NAME_TEST=test-server
PROCESS_SHUTDOWN_TIMEOUT=30000

Expand Down
35 changes: 35 additions & 0 deletions launch/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Product Hunt launch — Keryx

Working folder for the Keryx PH launch. Lives in git so the copy can be reviewed and revised before launch day.

## What's here

| File | Purpose |
|---|---|
| `tagline.md` | The shortlist of taglines (60-char cap). Pick one before submitting. |
| `description.md` | The PH description (256 chars). Final, ready to paste. |
| `maker-comment.md` | First comment from the maker. Posts as soon as the listing goes live. |
| `topics.md` | The 4 PH topics to pick when submitting. |
| `gallery-spec.md` | What each of the 5 gallery slots is, current state, and what's still needed. |
| `runbook.md` | Pre-launch timeline, launch-morning playbook, comment-response templates, cross-post copy. |

## Gallery assets

| Slot | Status | Files |
|---|---|---|
| 1 — Thumbnail (one action, every transport) | Done | `producthunt-thumbnail.svg` + `.png` |
| 2 — Quickstart (terminal) | Done | `producthunt-slot2-quickstart.svg` + `.png` |
| 3 — Claude Desktop calling MCP | Done | `producthunt-slot3-claude.svg` + `.png` (sources real screenshot `screenshot-claude-desktop.png`) |
| 4 — Typed frontend | Open | needs editor screenshot |
| 5 — Demo gif | Optional | needs short loom or gif |

## Regenerating PNGs

```bash
cd launch
rsvg-convert -w 1270 producthunt-thumbnail.svg -o producthunt-thumbnail.png
rsvg-convert -w 1270 producthunt-slot2-quickstart.svg -o producthunt-slot2-quickstart.png
rsvg-convert -w 1270 producthunt-slot3-claude.svg -o producthunt-slot3-claude.png
```

Requires `librsvg` (`brew install librsvg`).
16 changes: 16 additions & 0 deletions launch/description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Description

Product Hunt soft limit: ~260 characters.

## Final

> Keryx is a TypeScript framework built on Bun where one action class is your HTTP endpoint, your WebSocket handler, your CLI command, your background task, and your MCP tool. Same logic, validation, middleware, and response type. MCP and OAuth 2.1 are built in.

**260 chars.** Right at the PH soft limit.

## Why this version

- Leads with the mechanic — one action class is five things — same hook as the thumbnail.
- Names the stack (Bun, TypeScript) so dev-tools browsers know what they're looking at.
- "Same logic, validation, middleware, and response type" generalizes the promise (not specific to Zod) — broader than the previous version.
- Closes on MCP/OAuth, the differentiator vs. any other Node framework on PH.
53 changes: 53 additions & 0 deletions launch/gallery-spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Gallery spec

PH supports up to 5 media items in the gallery. First slot is the thumbnail; it does ~80% of the work.

All slots are 1270×760 PNG, dark background, matching visual language (Inter + JetBrains Mono, horn logo top-left, "keryxjs.com" top-right, footer stack line).

## Slot 1 — Thumbnail: One action. Every transport.

**Status:** Done.
**Files:** `producthunt-thumbnail.svg`, `producthunt-thumbnail.png`

Headline: *One action. Every transport.*
Subhead: *The TypeScript framework where your API is also your MCP server.*

Code block on the left showing a single `UserCreate` action class. Five arrows fanning out to five transport pills on the right: HTTP / WebSocket / CLI / Task / MCP tool. The MCP pill is visually emphasized (blue border, blue accent text on "+ OAuth 2.1") since that's the differentiator.

## Slot 2 — Quickstart: From zero to MCP server in 248ms.

**Status:** Done.
**Files:** `producthunt-slot2-quickstart.svg`, `producthunt-slot2-quickstart.png`

Headline: *From zero to MCP server in 248ms.*
Subhead: *Five commands. HTTP, WebSocket, MCP, background tasks, and a Postgres-backed API.*

Single full-width terminal mockup showing `bunx keryx new my-app` → `cd && cp .env` → `bun install` → `bun dev` → the dev-server output listing all the URLs (HTTP, WebSocket, MCP, OpenAPI, Workers, Database). URLs render in blue to look clickable.

## Slot 3 — Claude Desktop calling MCP

**Status:** Done.
**Files:** `producthunt-slot3-claude.svg`, `producthunt-slot3-claude.png`, `screenshot-claude-desktop.png` (source)

Headline: *Claude calls your API directly.*
Subhead: *Add Keryx to Claude Desktop. Every action becomes an MCP tool with OAuth 2.1.*

Real Claude Desktop screenshot on the left showing two tool calls in one turn (status check + message creation, with "Loaded tools, used keryx-local integration" badges visible). Four annotation bullets on the right: Discovered, OAuth 2.1, Read AND write, No second server.

## Slot 4 — Typed frontend

**Status:** Done.
**Files:** `producthunt-slot4-types.svg`, `producthunt-slot4-types.png`, `screenshot-frontend-types.png` (source)

Headline: *Typed end-to-end. No codegen.*
Subhead: *Your backend action becomes the frontend type. Hover any response — the shape is there.*

Side-by-side screenshot of `message.ts` (backend `MessagesList` action) and `ChatPage.tsx` (frontend), with a VS Code tooltip showing the inferred `Message` type via `ActionResponse<MessagesList>["messages"][number]`. Four annotation bullets on the right: Backend is the source, No generated client, ActionResponse&lt;T&gt;, Refactor-safe.

## Slot 5 — Demo gif (optional)

**Status:** Open. Skip for first launch if pressed for time.

Idea: 20–30 second loop showing the full quickstart — `bunx keryx new` → `bun dev` → `curl` hitting the new action → same action being called from Claude Desktop. Loom or gif format. If gif, keep under 5MB.

PH supports MP4 / Loom embeds, which look better than gifs in the gallery.
51 changes: 51 additions & 0 deletions launch/maker-comment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Maker comment

First comment under the launch listing. Posts the moment the launch goes live.

## Final

> Hey — I'm Evan, the maker.
>
> If you've shipped an MCP server in the last year, you've probably noticed you're writing your API twice. Your REST endpoints have Zod schemas, auth middleware, error handling, logging. Then you write a parallel MCP server that re-declares all of it with slightly different shapes, a different auth model, and its own way of returning errors. The two drift. Bugs only show up in one. It's the same duplication problem REST and WebSocket had a decade ago.
>
> Keryx is the framework I wanted for that. You write one **action** class, and it's automatically your HTTP endpoint, your WebSocket handler, your CLI command, your background task, and your MCP tool. Same Zod inputs, same middleware chain, same response shape. The only thing that changes is how the request arrives.
>
> ```ts
> export class UserCreate implements Action {
> name = "user:create";
> inputs = z.object({ name: z.string().min(3), email: z.string().email() });
> web = { route: "/user", method: HTTP_METHOD.PUT };
> task = { queue: "default" };
> async run(params) { return { user: await createUser(params) }; }
> }
> ```
>
> That class is now a `PUT /api/user` endpoint, a WebSocket action, a CLI command with `--name` and `--email` flags generated from the schema, a Resque-backed background job, and an MCP tool that Claude Desktop discovers and calls with OAuth 2.1 — no extra wiring, no second server.
>
> The stack underneath: Bun for runtime (native TS, no build step, fast test runner), Zod for validation, Drizzle for the database with auto-migrations, Resque for jobs, and a Vite + React example frontend with end-to-end typed responses via `ActionResponse<MyAction>`. First-party plugins for OpenTelemetry tracing and a Resque admin UI ship in the same repo.
>
> Quick start:
>
> ```bash
> bunx keryx new my-app
> cd my-app && bun install && bun dev
> ```
>
> v0.30 — pre-1.0 but real. I'm running it in production, the docs at keryxjs.com are complete, and the example app is a working chat with channels, files, sessions, and the React frontend wired up. (For the Node.js old-timers: this is the spiritual successor to ActionHero, rewritten ground-up on Bun with MCP as a first-class transport.)
>
> Happy to answer anything in the comments — especially curious to hear from people who've hit the "writing MCP twice" wall.
>
> — Evan ([@evantahler](https://x.com/evantahler))

## Why this version

- Leads with the **duplicated-MCP-server pain**, not ActionHero history. New visitors care about today's problem.
- Code block early so the mechanic lands before anyone scrolls past.
- ActionHero is one parenthetical sentence near the end, framed as credentialing for Node old-timers rather than the lead.
- ~370 words — long but every paragraph is doing work. Don't trim unless the listing is getting low engagement.

## Quick stats

- Word count: ~370
- Code blocks: 2 (one for the action class, one for quickstart)
- Links: 1 (X handle at the end)
Binary file added launch/producthunt-slot2-quickstart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading