Converts OpenAPI 3.x specs into typed RPC client modules, ensuring consistent call signatures and validation.

Install

mkdir -p .claude/skills/mixins && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/16395" && unzip -o skill.zip -d .claude/skills/mixins && rm skill.zip

Installs to .claude/skills/mixins

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

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. Use whenever the user asks to "call a third-party API from my Vovk app", "mixin an OpenAPI schema", "import an OpenAPI spec as a client", "wrap an external service that only ships an OpenAPI doc", or mentions `openAPIMixin`, `getModuleName`, `getMethodName`, `withDefaults` on a generated API module, or the `Mixins` namespace. Also use to push back when the user reaches for mixins for a vendor with a great official SDK (Stripe, AWS, GitHub via Octokit) — the skill explains when the official client is the better choice. Covers remote/local/inline specs, module + method naming strategies, `apiRoot`, per-mixin fetcher, AJV client validation knobs, and composed/segmented clients. **`deriveTools` works with mixins for OpenAI / Anthropic / Vercel function-calling** (reads `parameters` JSON Schema), but the `mcp-handler` path needs `inputSchemas` Standard Schemas which mixins don't carry — wrap in `createTool({...})` for MCP (see `tools` skill).
1105 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Intermediate

Key capabilities

  • →Import OpenAPI 3.x schemas as typed client modules
  • →Generate RPC modules from third-party APIs
  • →Configure per-mixin fetchers
  • →Integrate external services into Vovk applications
  • →Derive tools for OpenAI/Anthropic/Vercel function-calling

How it works

Mixins convert OpenAPI 3.x specifications into typed client modules that mimic native Vovk RPC modules, providing a consistent call shape and type inference.

Inputs & outputs

You give it
OpenAPI 3.x specification (remote URL, local file, or inline object)
You get back
Typed client module behaving like a native Vovk RPC module

When to use mixins

  • →Importing OpenAPI specs as typed clients
  • →Generating RPC modules from third-party APIs
  • →Configuring per-mixin fetchers
  • →Integrating external services into Vovk

About this skill

Vovk.ts OpenAPI mixins

Mixins turn any OpenAPI 3.x spec into typed client module behaving exactly like native Vovk RPC module — same { params, query, body } call shape, same client surface, same type-inference helpers (VovkBody, VovkOutput, …). Can run mixins standalone (no Next.js) as pure codegen tool.

LLM tool exposure works out of the box. Pass mixin modules straight to deriveTools — for function calling and for MCP. Each derived tool gets a merged inputSchema that is both a Standard Schema and a Standard JSON Schema, rebuilt from the mixin's OpenAPI-derived JSON Schema (jsonSchemasObjectToSingleJSONSchemaOnlySpec in packages/vovk/src/validation/json-schema-only-spec.ts, selected in packages/vovk/src/tools/derive-tools.ts when a handler has no definition).

The one real difference from a procedure-backed controller: that schema's validate checks the { body, query, params } envelope only — required slots present, no unknown keys — and defers slot values to execution time, where the generated client's AJV validation and the remote API enforce them. Controllers validate values up front because they carry your original Zod / Valibot / ArkType schemas.

v3 required hand-written createTool wrappers for the MCP path. That is obsolete: createTool was removed in v4 and mixins now carry the schema MCP needs.

Prefer the official SDK when one exists

Recommend official client library first. Hand-maintained SDKs like stripe, @octokit/rest, @aws-sdk/*, @google-cloud/* ship with auth flows, retries, pagination helpers, webhook signature verification, edge-case handling that generated client can't match — and track upstream API changes faster than any spec snapshot. If vendor publishes official SDK, use it.

Mixins right tool when:

  • No official SDK exists — internal services, niche vendors, legacy APIs that only publish OpenAPI document.
  • LLM tool exposure — deriveTools works directly for function calling and MCP alike (see note at top). For GitHub-style APIs @octokit/rest still better tool body, but mixin remains useful when third-party API has no official SDK.
  • Spec-as-source-of-truth — internal microservices where OpenAPI doc is generated and you want client drift to surface as TypeScript error at build time.

For everything else (Stripe charges, S3 uploads, Octokit pagination), reach for official package.

Scope

Covers:

  • Declaring mixins under outputConfig.segments.<name>.openAPIMixin.
  • source variants: remote URL (with fallback), local file, inline object.
  • getModuleName / getMethodName — preset strategies + function form.
  • apiRoot + authorization via withDefaults.
  • Per-mixin fetcher + AJV strict-mode loosening for messy specs.
  • Mixins namespace for components/schemas types.
  • Composed vs segmented output (pointer to rpc skill).
  • LLM tool exposure: deriveTools direct, for function-calling and MCP alike (pointer to tools skill).

Out of scope:

  • Authoring own procedures → procedure skill.
  • RPC client call shape, customFetcher, per-call init → rpc skill.
  • AI tool derivation details → tools skill.
  • Writing OpenAPI specs by hand — this skill consumes them.

Declaring a mixin

Mixin declared as pseudo-segment under outputConfig.segments.<name>.openAPIMixin. Key (petstore below) becomes segment folder name in segmented-client mode. Generated module name comes from getModuleName (default 'api'), not from segment key.

// @ts-check
/** @type {import('vovk').VovkConfig} */
const config = {
  outputConfig: {
    imports: {
      validateOnClient: 'vovk-ajv', // optional client-side validation
    },
    segments: {
      petstore: {
        openAPIMixin: {
          source: {
            url: 'https://petstore3.swagger.io/api/v3/openapi.json',
            fallback: './.openapi-cache/petstore.json',
          },
          getModuleName: 'PetstoreAPI',
          getMethodName: 'auto',
          apiRoot: 'https://petstore3.swagger.io/api/v3',
        },
      },
    },
  },
};
export default config;

Run npx vovk generate (or keep vovk dev running) → mixin emitted alongside native RPC modules.

import { PetstoreAPI } from '@/client';

const pets = await PetstoreAPI.getPets({ query: { limit: 10 } });

Import path depends on client layout. Code samples here import from '@/client': the composed client generated into src/client (or client/ without a src folder). Custom composedClient.outDir changes the path. With segmented client, each mixin lives in own folder named after pseudo-segment key, e.g. @/client/petstore. Call shape + types identical in both. See rpc skill for full comparison.

Source variants

source is object — pick exactly one shape.

{ url, fallback? } — fetched at generate time. Optional fallback path caches last-seen spec locally; if remote URL unreachable on next generate, Vovk reads fallback. Commit fallback to keep CI green when upstream spec host is down.

source: {
  url: 'https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json',
  fallback: './.openapi-cache/github.json',
}

{ file } — local spec checked into repo. Both JSON + YAML accepted (Vovk sniffs by leading char: { / [ → JSON, else YAML).

source: { file: './openapi/internal.yaml' }

{ object } — inline JS value. Useful when spec built or transformed by another tool in same project.

import spec from './openapi/internal.json' with { type: 'json' };
// ...
openAPIMixin: { source: { object: spec }, ... }

Module and method naming

getModuleName controls JS name of generated module; getMethodName controls each method. Both accept preset string or function.

Preset strings — getModuleName:

ValueEffect
'api' (default)Every operation goes into single api module.
any other literal (e.g. 'PetstoreAPI')Hard-coded single module name — useful for small third-party APIs.

Preset strings — getMethodName:

ValueEffect
'camel-case-operation-id'Always camelCase the operationId. Throws if operationId missing. Use only when every operation has one.
'auto' (default)One mode handles all cases: pass operationId through if already camelCase, camelCase it if snake_case, otherwise synthesize from METHOD + path. Safe for messy specs.

'auto' is itself the auto-detecting mode — no separate layer picks between two presets. Reach for 'camel-case-operation-id' only when you want throw-on-missing behavior; otherwise leave default. For more structured needs (splitting operations across multiple modules, custom prefixes), use function — see below.

Function form — receives { operationObject, method, path, openAPIObject }, returns string. Use when operation IDs are structured + you want to split into multiple modules. GitHub REST API is canonical example for the technique (issues/list-for-org → GithubIssuesAPI.listForOrg) — though for actual GitHub work, prefer @octokit/rest over a mixin:

import camelCase from 'lodash/camelCase.js';
import startCase from 'lodash/startCase.js';

openAPIMixin: {
  source: { url: '...', fallback: '...' },
  getModuleName: ({ operationObject }) => {
    const [ns] = operationObject.operationId?.split('/') ?? ['unknown'];
    return `Github${startCase(camelCase(ns)).replace(/ /g, '')}API`;
  },
  getMethodName: ({ operationObject }) => {
    const [, name] = operationObject.operationId?.split('/') ?? ['', 'ERROR'];
    return camelCase(name);
  },
},

Result: GithubIssuesAPI.listForOrg, GithubReposAPI.removeStatusCheckContexts, etc. — imported from generated client like any native module.

apiRoot and authorization

apiRoot sets default base URL for mixin. Required if OAS document has no servers property; if document has servers, Vovk picks first entry unless overridden.

For auth, prefer withDefaults over per-call plumbing. Every generated API module exposes withDefaults({ init?, apiRoot? }), returns new module with options deeply merged into every call:

import { PetstoreAPI } from '@/client';

const PetstoreAPIWithAuth = PetstoreAPI.withDefaults({
  init: { headers: { Authorization: `Bearer ${process.env.PETSTORE_TOKEN}` } },
  apiRoot: 'https://api.example.com', // optional override
});

await PetstoreAPIWithAuth.updatePet({ body: { name: 'Doggo' } });

Also the preferred pattern for LLM exposure — wrap the module with withDefaults first, then hand the authorized module to deriveTools, so LLM-triggered calls go out authenticated and the token never reaches the model.

Per-call override fine for one-off cases:

await PetstoreAPI.getPetById({
  params: { petId: 1 },
  apiRoot: 'https://staging.example.com',
  init: { headers: { Authorization: `Bearer ${token}` } },
});

Never embed API secrets in browser bundle. Keep authorized calls server-side (server components, route handlers, server actions, controllers, services), or proxy through your own Vovk segment + add auth header there.

Per-mixin fetcher and AJV tuning

For auth needing dynamic logic (token refresh, signing), use custom fetcher scoped to mixin's segment. Fetcher runs request, performs client-side validation, prepares headers — see rpc skill for full contract.

outputConfig: {
  segments: {
    petstore: {
      openAPIMixin: { /* ... */ },
      imports: { fetcher: './src/lib/petstoreFetcher' },
    },
  },
},

Third-party specs often include non-standard keywords that trip AJV's strict mode. Loosen globally:

libs: {
  /** @type {import('vovk-ajv').VovkAjvConfig} */
  ajv: { options: { strict: false } },
},

Client-side validation opt-out per call


Content truncated.

When not to use it

  • →When an official SDK exists for the third-party API
  • →When the primary need is for `mcp-handler` path without `createTool` wrapper
  • →When authoring own Vovk procedures

Limitations

  • →Does not replace official SDKs for well-supported vendors.
  • →Requires wrapping mixin calls in `createTool({...})` for MCP servers.
  • →Does not cover authoring own Vovk procedures.

How it compares

This skill allows integrating any OpenAPI-defined API into Vovk with native-like typing and call signatures, unlike manually writing client code for each API.

Compared to similar skills

mixins side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
mixins (this skill)03moReviewIntermediate
copilot-sdk75moReviewIntermediate
create-bubble28moReviewIntermediate
mcp-builder1365moReviewAdvanced

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

copilot-sdk

github

Build agentic applications with GitHub Copilot SDK. Use when embedding AI agents in apps, creating custom tools, implementing streaming responses, managing sessions, connecting to MCP servers, or creating custom agents. Triggers on Copilot SDK, GitHub SDK, agentic app, embed Copilot, programmable agent, MCP server, custom agent.

763

create-bubble

bubblelabai

Create a new Bubble integration for Bubble Lab following all established patterns and best practices from CREATE_BUBBLE_README.md

23

mcp-builder

anthropics

Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).

136215

turborepo

vercel

Turborepo monorepo build system guidance. Triggers on: turbo.json, task pipelines, dependsOn, caching, remote cache, the "turbo" CLI, --filter, --affected, CI optimization, environment variables, internal packages, monorepo structure/best practices, and boundaries. Use when user: configures tasks/workflows/pipelines, creates packages, sets up monorepo, shares code between apps, runs changed/affected packages, debugs cache, or has apps/packages directories.

61191

telegram-mini-app

davila7

Expert in building Telegram Mini Apps (TWA) - web apps that run inside Telegram with native-like experience. Covers the TON ecosystem, Telegram Web App API, payments, user authentication, and building viral mini apps that monetize. Use when: telegram mini app, TWA, telegram web app, TON app, mini app.

62163

stripe-integration

wshobson

Implement Stripe payment processing for robust, PCI-compliant payment flows including checkout, subscriptions, and webhooks. Use when integrating Stripe payments, building subscription systems, or implementing secure checkout flows.

48165

Search skills

Search the agent skills registry