Actions
defineAction, app-only visibility, and namespaced backing tools.
Actions are backing tools the View can call. They are hidden from the model.
import { z } from "zod";
import { defineAction } from "bitmcp";
export const refresh = defineAction({
description: "Reload forecast points",
input: z.object({ city: z.string() }),
async execute({ city }) {
return { city, summary: `Updated forecast for ${city}`, points: [] };
},
});defineAction is defineTool with visibility: ["app"].
Naming
Place named exports in actions.ts beside the tool:
src/tools/forecast/
tool.ts
view.tsx
actions.ts export const refresh = defineAction(...)The registered name is forecast.refresh.
From the View
callTool("forecast.refresh", { city: result.city });Each call is a new stateless tools/call. Pass handles or ids explicitly when resuming work.
Why actions exist
Iframe clicks should not pollute tools/list with UI-only helpers. The model sees the main tool. The View sees refresh, filter, or pagination helpers.
This uses the official Apps visibility field, not a bitmcp invention.