tools
Building LLM tools with Vovk.ts — `deriveTools()` (procedures → tools) returning a `StandardToolV0[]` array, standalone tools via the `standard-tool` package…
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-tools
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: backend, cloud, ml, security
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/tools
What's inside
- Skill name
tools- Description
- Building LLM tools with Vovk.ts — `deriveTools()` (procedures → tools) returning a `StandardToolV0[]` array, standalone tools via the `standard-tool` package, `@operation.tool({ name, title, description, hidden, meta })` decorator, `x-tool` metadata, `ToModelOutput` formatters (`DEFAULT`, `MCP`, `RAW`), the merged `inputSchema`, the `meta` option for passing context to procedures, `withDefaults` for baking auth into third-party API tools, and the `pick` / `omit` pattern for selecting specific procedures. Use whenever the user asks to expose an API to an LLM, wire up tool calling, build an MCP server, "let Claude / GPT call this", "turn my controllers into tools", "function calling with Vercel AI SDK", "standalone tool", "hide a procedure from the LLM", "tool that wraps a third-party SDK", or any variation. Does NOT cover procedure authoring → `procedure` skill. Does NOT cover the OpenAPI spec beyond `@operation`/`x-tool` → `openapi` skill. Does NOT cover third-party OpenAPI mixin setup → `mixins` skill.
- License
- MIT
- Instructions
- 487 lines in SKILL.md · view on GitHub
Before installing
- Instructions call the network
Files (1)
- SKILL.md
SKILL.md (first lines)
# Vovk.ts LLM tools
**`deriveTools({ modules })`** turns existing procedures (controllers, RPC modules, OpenAPI mixins) into tools automatically. It returns an **array** of tools, each satisfying [`StandardToolV0`](https://standard-tool.js.org/) — `{ name, title?, description, inputSchema?, outputSchema?, execute }`.
Standalone tools (no procedure backing — SDK wrappers, calculators, file ops) are plain objects of the same shape; the `standard-tool` package's `standardTool()` helper adds input/output validation. Both mix freely in one array and feed to OpenAI / Anthropic / Vercel AI SDK / MCP servers.
> **v4 removed `createTool`, `VovkTool`, `parameters`, `type` and `inputSchemas`.** Tools are the standard-tool shape now: one merged `inputSchema` instead of `parameters` + `inputSchemas`, and `deriveTools` returns the array directly instead of `{ tools, toolsByName }`.
**Out of scope:** procedure authoring (**`procedure`**), `@operation` for OpenAPI docs (**`openapi`**), third-party OpenAPI mixin setup (**`mixins`**). MCP server transport / hosting outside Vovk; **for Next.js, use `createMcpHandler` from the official MCP SDK (`@modelcontextprotocol/server`)** — example below.
> **Import path note.** Code samples import from `'@/client'`: the composed client generated into `src/client` (or `client/` when the app isn't in `src/app`). Custom `composedClient.outDir` changes the path. With segmented client, import from `@/client/<segment>`. Call shape identical. See **`rpc`** skill.
## `deriveTools` — core shape
```ts
import { deriveTools } from 'vovk';
import { TaskRPC, PetstoreAPI } from '@/client';
import UserController from '@/modules/user/user-controller';
const tools = deriveTools({
modules: { UserController, TaskRPC, PetstoreAPI },
});
```
`modules` accepts record of:
- **Controllers** — execute via `.fn()` in-process, no HTTP.
- **RPC modules** (from `@/client`, or `@/client/<segment>` for segmented layout) — execute via HTTP using standard fetcher.
- **OpenAPI mixins** (same client surface) — execute via HTTP against third-party API. See **`mixins`** skill.
Each module yields one tool per procedure with `@operation` schema, not `hidden`.
### Return shape
```ts
const tools = deriveTools({ modules: { TaskRPC } }); // StandardToolV0[]
// Need name-keyed dispatch? Build the map yourself — v4 dropped `toolsByName`.
const byName = Object.fromEntries(tools.map((t) => [t.name, t]));
const result = await byName[call.name].execute(call.arguments);
```
### Each tool's fields
The type comes from the `standard-tool` package (`import type { StandardToolV0 } from 'standard-tool'`); `vovk` doesn't export it.
```ts
type StandardToolV0 = {
name: string; // default: `${moduleName}_${handlerName}` — e.g. UserController_getUser
title?: string; // from x-tool.title or operation.summary
description: string; // x-tool.description, OR `${summary}\n${description}`, OR handlerName fallback
inputSchema?: StandardSchemaV1 & StandardJSONSchemaV1; // merged body/query/params, see below
outputSchema?: StandardSchemaV1 & StandardJSONSchemaV1; // procedure's output schema if declared
meta?: Record<string, unknown>; // verbatim from x-tool.meta — static data for consumers
execute: (input, context?) => Promise<unknown>; // HTTP for RPC/mixins, .fn() for controllers
};
```
**`inputSchema` is one merged schema, nested not flat.** Each slot sits under its own key:
```ts
inputSchema['~standard'].jsonSchema.input({ target: 'draft-2020-12' })
// {
// type: 'object',
// properties: { body?: <body schema>, query?: <query schema>, params?: <params schema> },
// required: [...], // slots that exist in properties
// additionalProperties: false,
// }
```
So `execute` is called as `tool.execute({ body, query, params })`, not `tool.execute({ ...flat })`.
It is simultaneously a **Standard Schema** (`~standard.validate`) and a **Standard JSON Schema** (`~standard.jsonSchema.input()`), so consumers take whichever they support without a conversion step.
**What its `validate` actually checks depends on the module kind:**
| Module kind | Slot schemas | `validate` behavior |
|---|---|---|
| Controllers / procedures | Your original Zod / Valibot / ArkType schemas | Envelope **and** slot values |
| RPC modules, OpenAPI mixins | Reconstructed from generated JSON Schema | **Envelope only** — required slots present, no unknown keys; values validated during execution |
Mixins therefore *do* produce usable tools including for MCP — see "Mixins and MCP" below.
## Customizing tool name + description
Default `name = ${ModuleName}_${handlerName}`, default `description = ${summary}\n${description}` from `@operation`. Override via `@operation.tool({ … })` (recommended cleaner form):
```ts
import { prefix, get, operation, procedure } from 'vovk';
@prefix('user')
export default class UserController {
@operation.tool({
name: 'get_user_by_id', // overrides UserController_getUser
title: 'Get user by ID', // shown in MCP clients
description: 'Retrieves a user by their unique ID, including name and email.',
})
@operation({ summary: 'Get user by ID', description: 'Retrieves a user by their unique ID.' })
@get('{id}')
static getUser = procedure({ /* ... */ });
}
```
Equivalent long form: `@operation({ ..., 'x-tool': { name, title, description, hidden, meta } })`. Keys (all optional):
| Key | Effect |
|---|---|
| `hidden: true` | Procedure excluded from `deriveTools` output. |
| `name` | Overrides default `ModuleName_handlerName`. |
| `title` | Optional title — used by MCP clients in tool-list UI. |
| `description` | Overrides `summary\ndescription` concatenation. |
| `meta` | Static `Record<string, unknown>` copied to `tool.meta` for consumers to read. Not sent to the model. |
Don't confuse `x-tool.meta` (static, per tool, ends up on `tool.meta`) with `deriveTools({ meta })` (runtime context handed to every procedure, readable via `req.vovk.meta()`).
## Hide procedures
Canonical: `hidden: true`.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.660score
rust
finom
The Vovk.ts Rust client — generating a typed Rust crate from a Vovk API with `vovk-rust`, the `rs` / `rsSrc` templates, the generated async call shape using…
SkillAFreshness: A★ 54Claude Code +9 - 0.660score
openapi
finom
Vovk.ts OpenAPI generation — how the OpenAPI 3.x spec is derived from procedures + validation schemas, the `@operation` decorator family (`@operation({...})`…
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 - 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
Signals
- Stars
- 54
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Oct 20, 2026 (7 days ago)
- Last release
- Oct 22, 2026 (5 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
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
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
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
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
tools skill. Agent Mart. https://agentmart.dev/skills/finom-tools (last updated 2026-10-24)