rpc
Vovk.ts RPC client — how `vovk generate` turns controllers into type-safe client modules, composed vs segmented clients, call shape (`apiRoot`, `params`…
Skill by finom
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/finom-rpc
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: frontend, backend, security, writing
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/rpc
What's inside
- Skill name
rpc- Description
- Vovk.ts RPC client — how `vovk generate` turns controllers into type-safe client modules, composed vs segmented clients, call shape (`apiRoot`, `params`, `body`, `query`, `meta`, `init`, `disableClientValidation`, `validateOnClient`, `interpretAs`, `transform`, `fetcher`), customizing generation via `outputConfig.imports.fetcher` + `createFetcher` (auth headers, retries, tracing, dynamic `onSuccess` / `onError` subscribers), configuring clients in `vovk.config.mjs` (`composedClient` / `segmentedClient`), error rethrow (`HttpException`, `HttpStatus.NULL`), `VovkInput`/`VovkOutput` against RPC modules, React Query integration (`queryKey`, `streamedQuery`), RPC method surface (`.withDefaults`, `.getURL`, `.queryKey`, `.schema`, `.isRPC`). Use whenever user asks to call API from browser / mobile / other server ("fetch users from the client", "call the API from Next.js client component", "typed API client", "why is my RPC call failing", "add auth token to every request", "custom headers on RPC calls", "retry on 401", "why is the client stale"), regenerate client (`vovk generate`), choose between composed vs segmented clients, or wire up `@/client` imports. Does NOT cover writing procedures / handlers → hand off to `procedure` skill. Does NOT cover segment registration / `initSegment` → hand off to `segment` skill. Does NOT cover JSON Lines streaming clients → hand off to `jsonlines` skill.
- License
- MIT
- Instructions
- 437 lines in SKILL.md · view on GitHub
Agent Skills spec issues
- description: longer than 1024 characters
Files (1)
- SKILL.md
SKILL.md (first lines)
# Vovk.ts RPC client
Every controller procedure with HTTP decorator automatically gets typed client counterpart. `vovk generate` produces these client modules from segment schemas, emitting TypeScript into the project:
- **Composed client** (default): one client for all segments at `composedClient.outDir` (default `./src/client`, or `./client` when the app isn't in `src/app`). Import from `'@/client'` (standard Next.js alias; alias-less projects use a relative path).
- **Segmented client**: per-segment subdirs of `segmentedClient.outDir` (same default dir). Import from `'@/client/<segment>'`.
**Key identity**: client module name = **key** used in `initSegment`'s `controllers` map, regardless of import path.
```ts
// server
initSegment({ controllers: { UserRPC: UserController } });
// client (composed)
import { UserRPC } from '@/client';
await UserRPC.getUser({ params: { id: '42' } });
```
Not `UserControllerRPC`. Not `UserController`. Whatever the key is.
## Generating client
```bash
npx vovk generate
```
What it does:
- Reads `.vovk-schema/**/*.json` for every segment (nested segments live in subdirectories, e.g. `.vovk-schema/customer/static.json`).
- Emits generated code into configured `outDir` using selected `fromTemplates` preset (default `['ts']`).
- Composed client (default): emits `index.ts`, `schema.ts`, `openapi.ts`, `openapi.json` at `outDir` root (default `./src/client`, or `./client` when the app isn't in `src/app`). Project's own tsc handles the files; import from `'@/client'`.
- Segmented client: same four files per segment under `<outDir>/<segment>/`; import from `'@/client/<segment>'`.
- Generated dir is gitignored by `vovk init` and rebuilt by the `prebuild` script (`vovk generate`); no need to commit it.
See "Client layout and import paths" below.
**`vovk generate` does NOT rebuild schemas from controller source.** Schema emission = separate step: `vovk dev` runs alongside Next.js dev server, hits each segment's `_schema_` endpoint (only available when `NODE_ENV === 'development'`), writes JSON into `.vovk-schema/`. `vovk generate` reads whatever's there.
Consequence: if backend changed and client looks stale, running `vovk generate` alone isn't enough — `.vovk-schema/` hasn't been refreshed. One shot: `PORT=<port> npx vovk dev --next-dev --exit` starts Next.js, writes `.vovk-schema/` and the client, stops, and exits with 1 on failure. While developing, `npm run dev` keeps both fresh.
When to run:
- **Automatic**: `prebuild` script installed by `vovk init` runs `vovk generate` before `next build`. During `npm run dev`, dev watcher refreshes `.vovk-schema/` on backend changes, client regenerates.
- **Explicit**: before integration tests, after checking out branch, if client method appears missing ("compiled fine, why is `UserRPC.createUser` undefined?"). If method just written is missing, schema probably stale — run `vovk dev --next-dev --exit` (or restart `npm run dev`) rather than re-running `vovk generate`.
## Call shape
Same signature across every RPC method. Core options first, advanced below:
```ts
await ModuleRPC.methodName({
// data
params?: { ... }, // path params — typed
query?: { ... }, // query string — typed
body?: { ... } | FormData | ..., // narrows by contentType — see "Body by content type"
meta?: { [key: string]: any }, // serialized as x-meta header — see meta-isolation gotcha
// transport
apiRoot?: string, // override the generation-time default
init?: RequestInit, // headers, credentials, signal, next.revalidate, etc. — see "init" below
// validation
disableClientValidation?: boolean,
validateOnClient?: ..., // per-call validator override
// advanced
interpretAs?: string, // force response interpretation, e.g. 'application/jsonl' when server didn't set it
transform?: (data, response) => any, // post-process the parsed response
// plus any custom options declared via createFetcher<TOptions>({...}) — see Fetcher section
});
```
Return type = `Promise` of whatever procedure's `output` schema resolves to, or whatever `transform` returns if present. Override per call:
```ts
const user = await UserRPC.updateUser<SomeType>({ /* ... */ });
```
### Body by content type
`body`'s accepted type narrows to procedure's `contentType`: `FormData` for `multipart/form-data`, `URLSearchParams` or `FormData` for `application/x-www-form-urlencoded`, `File` / `Blob` / `ArrayBuffer` / `Uint8Array` for binary (`image/*`, `video/*`, `*/*`). Schema-typed objects always accepted. Full matrix → **`procedure`** skill.
```ts
const form = new FormData();
form.append('file', file);
await UserRPC.uploadAvatar({ body: form }); // multipart/form-data procedure
```
Never hand-set `Content-Type` — fetcher derives it (multipart boundary included). Manual headers = usual HTTP 415 trigger.
### `apiRoot`
`apiRoot` **baked in at generation time**: defaults to `/${rootEntry}` (`rootEntry` defaults to `'api'`, so default baked-in value = `/api`). When `outputConfig.origin` is set, bake produces full URL like `http://localhost:3000/api`. Per-call `apiRoot` fully replaces baked-in value for that call — config-level changes still require `vovk generate`.
In browser, relative `/api` resolves against page origin, so same call works from `/dashboard` and `/settings`. On server (Node, integration tests) relative URLs don't resolve — pass full URL per call, bake one in via `outputConfig.origin`, or use `withDefaults({ apiRoot })`.
### `init`
`RequestInit` forwarded to `fetch` — `headers`, `credentials`, `mode`, `cache`, Next.js-specific `next: { revalidate: number }` all pass through.
**`init.signal` aborts the call.** The fetcher ties it to its own per-call `AbortController` (without `AbortSignal.any`, as in React Native and Safari before 17.4, the signal aborts that controller). A pending JSON call rejects with the signal's reason as is (an `AbortError` when `abort()` gets no reason); a stream stops with an error whose `cause` is the reason. A streaming call's async iterable also exposes `.abortController` (and `abortSilently()`) to stop that one stream.
### `transform`
Receives parsed response data and original `Response`. Return anything — including tuple if you want `Response` exposed to caller:
```ts
const [user, response] = await UserRPC.updateUser({
/* ... */
transform: (data, response) => [data, response] as const,
});
response satisfies Response;
```
### `interpretAs`
Forces fetcher's content-type dispatch. Useful when server returns JSON Lines but omits `content-type: application/jsonl` (common behind some proxies or when streaming through Next.js): `interpretAs: 'application/jsonl'` makes client treat response as async iterable anyway.From finom/vovk, MIT.
More from finom/vovk
- 0.664score
jsonlines
finom
Vovk.ts JSON Lines streaming — generator handlers (`function*`, `async function*`), the `iteration` validation option, `validateEachIteration`, the…
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
decorators
finom
Vovk.ts decorators — built-in (`@prefix`, `@operation`, `@get/@post/@put/@patch/@del`, `.auto()`) and custom via `createDecorator`.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
config
finom
Vovk.ts configuration — vovk.config.{mjs,cjs,js} shape, every config key + default (rootEntry, schemaOutDir, libs, exposeConfigKeys, logLevel, devHttps…
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
multitenant
finom
Multi-tenant / multitenancy patterns in Vovk.ts — hosting multiple tenants from one Next.js app via subdomain routing.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
bundle
finom
Vovk.ts `vovk bundle` CLI — packages composed TypeScript client as zero-dep publishable npm package.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
base
finom
Vovk.ts essentials — ALWAYS load first for any Vovk.ts task, including building a back end or API in a project that has vovk.config.* or .vovk-schema/.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
tools
finom
Building LLM tools with Vovk.ts — `deriveTools()` (procedures → tools) returning a `StandardToolV0[]` array, standalone tools via the `standard-tool` package…
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
python
finom
The Vovk.ts Python client — generating a typed Python package from a Vovk API with `vovk-python`, the `py` / `pySrc` templates, `TypedDict` shapes, JSON +…
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
init
finom
Initialize a backend — via Vovk.ts, a TypeScript-first RPC/API framework plugging into Next.js App Router, using official vovk-cli.
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
mixins
finom
Vovk.ts OpenAPI mixins — importing third-party OpenAPI 3.x schemas as typed client modules that share the same call signature as native Vovk RPC modules.
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
procedure
finom
Vovk.ts procedures in depth (`base` already has a complete endpoint, validation, errors and status codes) — atomic unit of server-side logic in Vovk project.
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
segment
finom
Vovk.ts segments in depth (`base` already covers the one root segment and its `route.ts`) — the unit of backend slicing in a Vovk project.
SkillAFreshness: A★ 54Claude Code +9
Signals
- Stars
- 54
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Oct 13, 2026 (14 days ago)
- Last release
- Oct 22, 2026 (6 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/finom/vovk
- Website
- vovk.dev
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from finom
- 0.664score
config
finom
Vovk.ts configuration — vovk.config.{mjs,cjs,js} shape, every config key + default (rootEntry, schemaOutDir, libs, exposeConfigKeys, logLevel, devHttps…
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
multitenant
finom
Multi-tenant / multitenancy patterns in Vovk.ts — hosting multiple tenants from one Next.js app via subdomain routing.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
bundle
finom
Vovk.ts `vovk bundle` CLI — packages composed TypeScript client as zero-dep publishable npm package.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
jsonlines
finom
Vovk.ts JSON Lines streaming — generator handlers (`function*`, `async function*`), the `iteration` validation option, `validateEachIteration`, the…
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
decorators
finom
Vovk.ts decorators — built-in (`@prefix`, `@operation`, `@get/@post/@put/@patch/@del`, `.auto()`) and custom via `createDecorator`.
SkillAFreshness: A★ 54Claude Code +9 - 0.664score
base
finom
Vovk.ts essentials — ALWAYS load first for any Vovk.ts task, including building a back end or API in a project that has vovk.config.* or .vovk-schema/.
SkillAFreshness: A★ 54Claude Code +9
Cite this page
rpc skill. Agent Mart. https://agentmart.dev/skills/finom-rpc (last updated 2026-10-24)