Defining Commands
A command is an async function with an ID. The @Command decorator binds a class method to a command ID, and registerCommands() attaches every decorated method on a service instance to the registry.
The basic shape
Section titled “The basic shape”import { Command, CommandRegistry, registerCommands } from '@coralstack/cmd-ipc'
class MathService { @Command('math.add', 'Add two integers') add({ a, b }: { a: number; b: number }): number { return a + b }}
const registry = new CommandRegistry({ id: 'main' })registerCommands([new MathService()], registry)Declaring the schema
Section titled “Declaring the schema”Commands become fully type-safe when paired with a Valibot schema map. The registry validates requests/responses at runtime and TypeScript infers the types at the call site.
import * as v from 'valibot'import type { CommandSchemaMap } from '@coralstack/cmd-ipc'
export const MathSchema = { 'math.add': { description: 'Add two integers', request: v.object({ a: v.number(), b: v.number() }), response: v.number(), },} as const satisfies CommandSchemaMap
const registry = new CommandRegistry({ id: 'main', schemas: { commands: MathSchema },})See Type Safety for loose / strict / mixed modes.
Private commands
Section titled “Private commands”Commands whose ID starts with _ are private — they stay local to the registering process and are never announced to connected channels or exposed as MCP tools.
class LocalOps { @Command('_main.log', 'Internal logger') log({ message }: { message: string }) { console.log(message) }}