MCP-Native
Every action is automatically an MCP tool. AI agents authenticate via built-in OAuth 2.1, get typed errors, and call the same validated endpoints your HTTP clients use โ zero extra configuration.
One action class. Five transports. Your API is automatically an MCP server for AI agents, a WebSocket handler, a CLI tool, and a background task runner. Built on Bun, powered by Zod.
One action class. It's your HTTP endpoint, your CLI command, your WebSocket handler, and your background task โ all at the same time.
export class Status implements Action {
name = "status";
description = "Return the status of the server";
inputs = z.object({});
web = { route: "/status", method: HTTP_METHOD.GET };
task = { queue: "default", frequency: 60000 };
async run() {
return {
name: api.process.name,
uptime: Date.now() - api.bootTime,
};
}
}That's it. Same validation, same error handling, same response shape โ whether the request comes from a browser, a CLI, or a cron job.
This is one action:
export class UserCreate implements Action {
name = "user:create";
description = "Create a new user";
inputs = z.object({
name: z.string().min(3),
email: z.string().email(),
password: secret(z.string().min(8)),
});
web = { route: "/user", method: HTTP_METHOD.PUT };
task = { queue: "default" };
async run(params: ActionParams<UserCreate>) {
const user = await createUser(params);
return { user: serializeUser(user) };
}
}That one class gives you:
HTTP โ PUT /api/user with JSON body, query params, or form data:
curl -X PUT http://localhost:8080/api/user \
-H "Content-Type: application/json" \
-d '{"name":"Evan","email":"evan@example.com","password":"secret123"}'WebSocket โ send a JSON message over an open connection:
{
"messageType": "action",
"action": "user:create",
"params": {
"name": "Evan",
"email": "evan@example.com",
"password": "secret123"
}
}CLI โ flags are generated from the Zod schema automatically:
./keryx.ts "user:create" --name Evan --email evan@example.com --password secret123 -q | jqBackground Task โ enqueued to a Resque worker via Redis:
await api.actions.enqueue("user:create", {
name: "Evan",
email: "evan@example.com",
password: "secret123",
});MCP โ exposed as a tool for AI agents automatically:
{
"mcpServers": {
"my-app": {
"url": "http://localhost:8080/mcp"
}
}
}Same validation, same middleware chain, same run() method, same response shape. The only thing that changes is how the request arrives and how the response is delivered.
Most backends start simple โ an HTTP framework โ then bolt on a WebSocket server, a CLI tool, a job queue, and now an MCP layer. Each one has its own handler, its own validation, its own auth. You end up maintaining five implementations of the same logic.
Keryx flips that: write your controller once, and the framework delivers it across every transport.
| Feature | Keryx | Hono | Elysia | NestJS | FastAPI | Django |
|---|---|---|---|---|---|---|
| HTTP | yes | yes | yes | yes | yes | yes |
| WebSocket | yes | adapter | yes | yes | yes | channels |
| CLI commands | yes | โ | โ | limited | โ | yes |
| Background tasks | yes | โ | โ | Bull | Celery | Celery |
| MCP tools | yes | โ | โ | โ | โ | โ |
| Unified controller | yes | โ | โ | โ | โ | โ |
| Type-safe responses | yes | yes | yes | partial | yes | โ |
| OAuth 2.1 built-in | yes | โ | โ | Passport | โ | allauth |
| Per-session agents | yes | โ | โ | โ | โ | โ |
The MCP SDK gives you the protocol. Keryx gives you the framework โ actions, validation, middleware, auth, database, and background tasks alongside your MCP tools.
Keryx is the only TypeScript framework where your API is automatically an MCP server. No separate tool definitions, no duplicated auth, no schema mapping.
ErrorType values, not generic failure messages. They can distinguish validation errors from auth failures.Claude Desktop, VS Code Copilot, Cursor, Windsurf, and any other MCP client can discover and call your actions out of the box.
tsconfig gymnasticsbun test with watch mode, no extra dependencies.ts imports without configurationfetch included natively โ great for testing your own APIbunx keryx new my-app
cd my-app
cp .env.example .env
bun install
bun devRequires Bun, PostgreSQL, and Redis. See the Getting Started guide for full setup instructions.
Bun ยท Zod ยท Drizzle ยท Redis ยท PostgreSQL ยท OpenTelemetry