An exposed recipe shows up in the tool catalog. The built-in chat and every connected agent read that catalog. The model sees only three things when it picks a tool: the name, the description, and the variables. Exposing is a choice about where the recipe is offered. It is the same recipe. It still runs from the panel, from a schedule, or from a trigger, just like before.
#Decide what to expose
Set chat_exposed: true on purpose. Recipes you wrote yourself on this
server are offered to chat by default. Recipes installed from packs stay
hidden unless the author turned them on. Every exposed entry makes the catalog
longer, and the model must read all of it. So expose recipe by recipe, not
all at once.
Expose a recipe when all three of these are true:
- The job is something you would ask for in words. "What is overdue?" "Draft the intro." "Watch for the quote from Peter."
- It runs from its arguments alone. It needs no page context. It needs nothing the model cannot give it.
- It is the starting point of its workflow.
Keep these hidden: silent producers, the reactive half of a watcher pair, and cleanup tools. A silent producer is a recipe that quietly makes facts for other recipes. Also hide acting recipes that only make sense when started from a proposal or a review. Never hand a model a lever when it cannot see what must be true first. A workflow with many recipes usually exposes two: its starting recipe and its review recipe. Nothing else.
#Arguments: flat and easy to read
Chat fills in variables like flags on a command line. Keep them flat:
single values, true/false, and lists. Never an object that hides the real
shape:
"variables": {
"expected_sender_email": { "label": "Sender email", "type": "string" },
"subject_contains_any": { "label": "Subject terms", "type": "array",
"default": [] }
}Do not add a connection setting. A step that calls a pack uses the
connection chosen for that pack. When a pack has more than one, chat can
pick another for one run with the connections argument.
Give everything a label. Add help when a value has a set format. A value
with no optional and no default is a must-have. Use that shape only for
true must-haves. Give the rest defaults that work. (There is no required
field. Recued refuses it when you install.) A call on
pure defaults should work, or it should stop with a clear message. It should
never half-run. And do not ask for raw vendor record ids as arguments if the
recipe can find them itself. It can find them from something a person knows,
like an email or a date range. The model rarely has ids.
#Write the description so the model picks right
The model chooses between many tools using only the name and description.
- Name the recipe with a verb, and be specific:
audit-subscriptions-from-mail, notsubscription-helper. - Say what it reads and what it never does. "Read-only; never sends or deletes" lets the model pick the safe tool with confidence.
- Say if it runs now or runs on a schedule. A recipe that sets a watch for one future event must say that it waits. It must say it is not a repeating schedule. That is what steers the model between running it and scheduling it.
- Name the inputs it needs. Then the model asks you for missing values instead of guessing.
#What chat gets back
The tool result is the recipe's output.render. Those are the same sections
the panel shows. Start with a summary. Mark copyable blocks: a drafted
reply, a generated snippet, the things you will paste somewhere else. Offer
the next step as a button action that points at the acting recipe. Do not
offer it as prose that the model would have to read and guess at.
If a run reaches a held approval, the result shows that it is waiting for approval. It finishes later, when you decide, not because the model tries again.
#Writes still ask
A run started from chat goes through the same gate as everything else. Reads run under their grants. A write shows you an approval. You can fix the details before you say yes. A burst of identical writes asks once for the whole batch. You can relax the per-action ask for one session. You can relax it for exactly this action, for a batch, or for a whole class of operation. Only you can turn a repeated approval into a standing rule. See Grants and approvals.
Write the recipe with the ask in mind. The step that pauses should carry enough labeled context that the approval reads as a real decision. Think recipient, subject, and amount. And never split one real action into many small operations to sneak under the approval. The audit diary shows it anyway.
#Schedules from chat
Chat can also set a schedule for an installed recipe. Each schedule carries its own settings. Make your variables cover the things people will change per schedule. Keep the description honest about what a run with nobody watching does. The rules in Triggers and watchers apply just the same.
#Where exposure reaches
All of this reaches past the built-in chat. The MCP door offers the same exposed recipes as tools. Claude Desktop, Cursor, and any connected agent get them, under that door's grants. See AI chat and MCP and Connect to Recued.
#Checklist
- Expose on purpose. Starting recipes and review recipes: on. Producers, reactive halves, and proposal-only actors: off.
- Arguments flat, labeled, with defaults. Prefer things people know over raw ids.
- Description: starts with a verb. Says what it reads, writes, and never does. Says run-now or schedule. Names the inputs.
- A call on defaults only works, or it stops cleanly.
- Results start with a summary. Next steps are buttons.
- Test the pick: ask chat to do the job with some look-alike tools around. Check that it picks your recipe and fills it in right.