server.api
Assemble the router, guards and request context into the api object you mount.
server.api({ router, guards, requestContext, jobs }) binds the router and guards into the API object an adapter mounts.
import { server } from './server';
import { router } from './router';
import { requireUser, requireMember } from './guards';
export const api = server.api({
router,
guards: {
user: requireUser,
member: requireMember,
},
});guards is keyed by identity name and, when provided, must cover every identity the auth map uses. Mount the returned object with the adapter's mount verb:
| Adapter | Mount |
|---|---|
| Express | api.mount(app) |
| Fastify | await api.mount(app) |
| Hono | api.mount(app) |
| Next.js | api.mount() |
See the Mounting guide for full setup with each adapter.
jobs
A contract that declares scheduled jobs needs their handlers here, bound with server.jobs:
export const api = server.api({
router,
jobs: jobHandlers,
guards: {
scheduler: requireScheduler,
},
});api.mount then serves the two job endpoints, and every handler receives a typed jobs runner so a route can run one in process.
plugins
A plugin comes in two halves. The declaration is installed on new Kizuna(), and its server half goes here under the same key:
import { mcpPluginServer } from '@ts-kizuna/mcp/server';
import { openApiPluginServer } from '@ts-kizuna/openapi/server';
export const api = server.api({
router,
plugins: {
mcp: mcpPluginServer(),
openApi: openApiPluginServer(),
},
});Every plugin the contract declares needs its server half here, and server.api throws if one is missing, naming the module to import. Anything live the plugin needs, such as a store or a transport, is passed to that server half:
plugins: {
audit: auditPluginServer({ store }),
}api.mount serves every plugin's routes alongside yours, and whatever a plugin exports arrives on each handler under plugins, keyed by name.