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:
| Helper | Source |
|---|---|
toolchainFromMCP / mcpToolchainFromStdio | MCP servers (real, stdio) |
toolchainFromUsageSpec / toolchainFromUsageSpecPath | CLI usage specs |
toolchainFromAPI | HTTP APIs |
toolchainFromOpenAPI / toolchainFromOpenAPISpecPath | OpenAPI 3.x specs |
toolchainFromCustom | Custom 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 });