CLI reference
kervan create, kervan dev and kervan run. The summary below is the real --help output, minus one line about the optional web UI.
Where this fits: Run and operate. The command line that creates projects and serves specs and code.
On this page
Until the packages are published, run the CLI from a clone as
node packages/cli/bin/kervan.js <command>; afterwards, npx kervan <command>. The CLI refuses
Node.js versions outside 22.23.3 or a later 22.x, or 24.21.0 or later, with one line.
Usage: kervan <command> [options]
Commands:
create <dir> Create a new Kervan MCP server project
--name <name> Package name (default: the directory name)
--pm <manager> npm, pnpm, yarn or bun (default: the one running this command, else npm)
--no-install Skip installing dependencies
dev <entry> Run a server (a .ts/.js entry or a kervan.yaml spec) with hot reload
--http Serve on http://127.0.0.1:<port>/mcp with a REPL (default in a terminal)
--stdio Serve on stdin/stdout (default when started by an MCP client)
--port <port> HTTP port (default 3000)
--drain-timeout <ms> How long a reload waits for running calls (default 10000)
--repl / --no-repl Force the terminal inspector on or off
--no-watch Do not restart on file changes
--env-file <path> Load environment variables (repeatable; set variables win)
--allow-private-network Specs only: let tools reach private and loopback addresses
--allow-insecure-secrets Specs only: let tools send secrets over plain http
--deny-network <cidr> Specs only: an address or range tools may never reach (repeatable)
run <spec> Serve a kervan.yaml spec
--http Serve Streamable HTTP instead of stdio
--port <port> HTTP port (default 3000)
--host <host> HTTP bind address (default 127.0.0.1)
--allowed-host <h> Host name clients use (repeatable; required off localhost)
--env-file <path> Load environment variables (repeatable; set variables win)
--watch Reload the spec when it changes
--allow-private-network Let tools reach private addresses (refused in production)
--allow-insecure-secrets Let tools send secrets over plain http (refused in production)
--deny-network <cidr> An address or range tools may never reach (repeatable)
Options:
-h, --help Show this help
-v, --version Show the versionkervan create
kervan create installs @kervan/core, @kervan/transport and kervan from the npm registry,
where they are not published yet: the install fails, or, once someone else registers those names,
installs their packages. Until the release, use pnpm try:new <dir> from a clone, which installs
the packages built from that clone (quickstart), or pass
--no-install.
Creates a project from the basic template: an app with two tools, a test using
createTestClient, and scripts for dev, start, build and test.
| Option | Description |
|---|---|
--name <name> | npm package name (default: the directory name) |
--pm <manager> | npm, pnpm, yarn or bun (default: the one that ran create, else npm) |
--no-install | Do not install dependencies |
The target directory must be new or empty.
Generated projects run TypeScript directly with Node.js’s built-in type stripping. Kervan’s
tools and generated projects need Node.js 22.23.3 or a later 22.x, or 24.21.0 or later (the oldest releases the whole test suite has
passed on); create, dev and run refuse older versions with one line, and a generated
project’s npm start does too. Relative imports use
the .ts extension, and the tsconfig.json enables rewriteRelativeImportExtensions (so tsc
emits .js imports) and erasableSyntaxOnly (no enums or namespaces, which type stripping
cannot run).
kervan run
Serves a kervan.yaml spec (see @kervan/spec-runtime).
kervan run kervan.yaml # stdio
kervan run kervan.yaml --http --port 8080 # http://127.0.0.1:8080/mcp
kervan run kervan.yaml --http --host 0.0.0.0 --allowed-host mcp.example.com
kervan run kervan.yaml --env-file .env --watch| Option | Description |
|---|---|
--http | Streamable HTTP instead of stdio |
--port, --host | Default 3000 and 127.0.0.1 |
--allowed-host <name> | Host names clients use (repeatable). Required when --host is not localhost. |
--env-file <path> | Variables for {{secrets.X}} (repeatable). Variables already set win. |
--watch | Reload the spec when it changes; an invalid edit keeps the last good version. |
--allow-private-network | Let tools reach internal addresses. Development only; refused with NODE_ENV=production. |
--deny-network <cidr> | An address or range tools may never reach (repeatable); wins over --allow-private-network. |
--allow-insecure-secrets | Let tools send secrets to plain http:// URLs (a local API). Development only; refused with NODE_ENV=production. |
An invalid spec stops run with the file, line and column of every problem. Secret values never
appear in the output. Note: Node.js itself checks --env-file arguments, even after the script
name, and exits with <file>: not found (code 9) when the file is missing.
kervan dev
Runs your server with hot reload. Your code runs in a child process; kervan dev is a stable
MCP server in front of it that clients stay connected to. Given a .yaml/.yml spec instead,
it reloads the spec in its own process (--env-file, --allow-private-network and
--allow-insecure-secrets work as for run).
kervan dev src/index.ts # in a terminal: HTTP on 127.0.0.1:3000 plus a REPL
claude mcp add my-server -- node /path/to/kervan/packages/cli/bin/kervan.js dev /abs/path/src/index.ts # stdio, for MCP clients| Option | Description |
|---|---|
--http / --stdio | Default: HTTP with a REPL in a terminal, stdio when started by a client |
--port <port> | HTTP port (default 3000). The host is always 127.0.0.1. |
--drain-timeout <ms> | How long a reload waits for running calls (default 10000) |
--repl / --no-repl | Force the terminal inspector on or off (HTTP mode) |
--no-watch | Do not restart on file changes |
- Reloads. Saving a
.ts/.js/.jsonfile (outsidenode_modules,dist,.git) starts a new child first; only when it is up doeskervan devswitch to it, so a syntax error keeps the last good version running. Clients getlist_changedonly if the tools actually changed. The server’s own runtime changes (app.tool()at runtime) are followed too. - Running calls. The previous child keeps running until its calls finish, up to
--drain-timeout. Calls still running then fail with “interrupted because the server reloaded”. - Stopping the child never uses signals, which cannot ask a Windows process to shut down:
kervan devcloses the child’s stdin (a stdio MCP server exits on EOF), and if the process is still alive after 2 seconds it kills the process tree (taskkill /T /Fon Windows). - Security. HTTP mode only binds to
127.0.0.1and keeps theHost/Originchecks, so a web page cannot reach your tools through DNS rebinding. Values of secret-looking environment variables (*_TOKEN,*_API_KEY,*PASSWORD*,DATABASE_URL, …) and credentials in URLs are replaced with[redacted]in everythingkervan devprints and in error results it forwards. - Development only.
kervan devrefuses to start withNODE_ENV=production. File watching lives only in this CLI;@kervan/coreand@kervan/transportnever watch files.
REPL commands: tools, call <tool> [json], reload, help, exit. Calls go through the same
app that serves clients, so validation and error masking match what a client sees.