Yoke

Tools & toolchains

MCP, CLI, HTTP API, OpenAPI, and custom tools.

A tool is the interface to a single callable capability. A toolchain is a named set of tools exposed to agents.

Tools

import type { Tool } from "yoke";

const addTool: Tool = {
  name: "add",
  description: "Add two numbers.",
  schema: z.object({ a: z.number(), b: z.number() }),
  async run(args, ctx) {
    return { result: args.a + args.b };
  },
};

Tools run inside the runtime and receive a context — the runtime handle, the calling agent, and more. They can be async and can call back into the runtime: send a message to an agent, publish an event, or read the store.

Register a tool directly:

runtime.tool(addTool);

or as part of a toolchain:

runtime.toolchain({ name: "math", tools: [addTool] });

Calling tools

// from an actor or agent context
const out = await ctx.tools.add({ a: 1, b: 2 });

// from anywhere you have a runtime handle
const out = await ctx.runtime.callTool("add", { a: 1, b: 2 });

Building toolchains

Any set of tools is a toolchain. Helpers exist for each source:

HelperSource
toolchainFromMCP / mcpToolchainFromStdioMCP servers (real, stdio)
toolchainFromUsageSpec / toolchainFromUsageSpecPathCLI usage specs
toolchainFromAPIHTTP APIs
toolchainFromOpenAPI / toolchainFromOpenAPISpecPathOpenAPI 3.x specs
toolchainFromCustomCustom collections

OpenAPI toolchains

Generate tools directly from an OpenAPI 3.x spec (JSON or YAML) — one tool per operation, with zod input schemas derived from parameters and request body, and URL/query/body construction. No hand-written glue.

import { toolchainFromOpenAPISpecPath } from "yoke";

const forecast = await toolchainFromOpenAPISpecPath("./forecast.yml");
runtime.toolchain({ name: "forecast", tools: forecast });

Options: includeParams / excludeParams to slim the surface, and looseEnums to shrink giant enum schemas.

Used in the demo

apps/demo builds its open-meteo forecast toolchain straight from open-meteo's own OpenAPI spec — a live example of the weather bot. See demo.

CLI toolchains via usage specs

CLI toolchains are driven by usage specs (https://usage.jdx.dev). Write the CLI's spec in usage format (TOML/JSON) and let Yoke generate the tools. Bun imports TOML natively, so no parser dependency is needed:

import { toolchainFromUsageSpecPath } from "yoke";

const cli = await toolchainFromUsageSpecPath("./my-cli.usage.toml");
runtime.toolchain({ name: "my-cli", tools: cli });

MCP toolchains

Yoke speaks the Model Context Protocol. mcpToolchainFromStdio spawns an MCP server and exposes its tools:

import { mcpToolchainFromStdio } from "yoke";

const mcp = mcpToolchainFromStdio({
  command: "npx",
  args: ["-y", "@modelcontextprotocol/server-filesystem"],
});
runtime.toolchain({ name: "fs", tools: mcp.tools });

On this page