ai-clients
v0.1.0
Published
Standard Schema schemas and config helpers for every AI coding client on clients.dev.
Maintainers
Readme
ai-clients
Standard Schema schemas and config helpers for every AI coding client catalogued on clients.dev.
Each client ships its config surfaces (MCP, skills, rules, hooks, commands,
settings) as typed schemas plus filesystem CRUD helpers so you can
validate, read, and write the real config files an agent reads — ~/.codex/config.toml,
~/.cursor/mcp.json, and so on — without hand-rolling the format for every tool.
All data is generated from clients.dev, so the package stays in sync with the open catalog.
Install
bun add ai-clients
# or: npm i ai-clients / pnpm add ai-clientsQuick start
import { clients, codex, validate } from "ai-clients";
// `clients` is the full array; each client is also a named export.
console.log(clients.length); // → every catalogued client
// Standard Schema (a Zod schema) for one MCP server entry.
const entry = validate(codex.mcp!.schema, {
command: "npx",
args: ["-y", "@upstash/context7-mcp"],
});
// Read/write the real config file (~/.codex/config.toml).
await codex.mcp!.addEntry("context7", entry);
const servers = await codex.mcp!.listEntries();
await codex.mcp!.removeEntry("context7");API
Clients
import {
clients,
clientsById,
getClient,
getClientsForSurface,
} from "ai-clients";
import { codex, cursor, claudeCode, geminiCli } from "ai-clients"; // individual imports
clients; // Client[] — every client
clientsById["codex"]; // Record<string, Client>
getClient("codex"); // Client | undefined
getClientsForSurface("mcp"); // Client[] declaring an MCP surfaceIdentifiers are the clients.dev ids camel-cased (claude-code → claudeCode).
Reserved words get a Client suffix (continue → continueClient).
A client
codex.id; // "codex"
codex.name; // "Codex"
codex.vendor; // "OpenAI"
codex.configPaths; // [{ surface, path, scope, format, key }, ...]
codex.mcpConfigSchema; // shortcut for codex.mcp?.schema
codex.settingsSchema; // shortcut for codex.settings?.schema
codex.surfaces; // Partial<Record<SurfaceId, Surface>>
codex.mcp; // Surface | undefined (also .skills, .rules, .hooks, .commands, .settings)A surface
Every surface exposes its documented shape and filesystem CRUD bound to that surface's config files:
const mcp = codex.mcp!;
mcp.schema; // Zod / Standard Schema for one entry (or the document)
mcp.fields; // documented fields
mcp.configFiles; // [{ path, scope, format, key, note }]
await mcp.resolvePath({ scope: "global" }); // absolute path (~ expanded)
await mcp.read(); // whole file → object ({} if missing)
await mcp.write(data); // serialize + write (mkdir -p)
await mcp.listEntries(); // entries under the file's `key`
await mcp.getEntry("context7");
await mcp.addEntry("context7", value); // validates against `schema`
await mcp.removeEntry("context7");Every method accepts a locator to choose which config file to touch:
{ scope?: "project" | "global" | "enterprise",
path?: string, // explicit file (format inferred from extension)
cwd?: string, // base for project-scoped relative paths (default: process.cwd())
home?: string } // expands a leading "~" (default: os.homedir())Resolution order: explicit path → matching scope → first declared file.
addEntry also takes { validate?: false } to skip schema validation.
Validation helpers
schema is a Standard Schema, so it works with
any compatible validator. The package also ships thin helpers:
import {
validate,
validateAsync,
safeValidate,
SchemaValidationError,
} from "ai-clients";
validate(schema, input); // returns parsed value, throws SchemaValidationError
await validateAsync(schema, input);
const result = safeValidate(schema, input); // { value } | { issues }Standalone config IO
The format-aware functional core is exported too, for when you want to operate
on a ConfigFile directly:
import {
readConfig,
writeConfig,
listEntries,
putEntry,
deleteEntry,
} from "ai-clients";Supported formats
| Format | Read | Write | Notes |
| ---------------- | :--: | :---: | ---------------------------------------------- |
| json/jsonc | ✅ | ✅ | Comments are not preserved on write. |
| toml | ✅ | ✅ | |
| yaml | ✅ | ✅ | |
| markdown/mdc | — | — | Document surfaces (skills/rules); CRUD throws. |
How it's built
The package is fully generated from clients.dev:
scripts/fetch-catalog.ts— fetchhttps://clients.dev/api/catalog.json(or--localto read a siblingclients-devcheckout) intodata/catalog.json.scripts/generate.ts— compile the catalog intosrc/generated/**: one module per client, with a Zod schema per surface derived from the documented field types.scripts/rebuild.ts— fetch + generate + bump the version + format + typecheck- build, in one command.
bun run rebuild # patch bump (default)
bun run rebuild minor # minor bump
bun run rebuild none # regenerate without bumping
bun run rebuild --local # source from a sibling clients-dev repo
bun run rebuild patch --release # also commit, tag (vX.Y.Z) and create the GitHub releaseA new GitHub release triggers the trusted-publishing workflow, which publishes to npm with provenance via OIDC (no tokens).
License
MIT © Andre Landgraf
