Skip to main content
These four processors are optional: LLM_CALL needs the llm-call module, MCP_LIST_TOOLS and MCP_TOOL_CALL need mcp-tool-call, and SESSION_MEMORY needs session-memory. See Built-in plugins for how a build selects them. To build workflows from them, read AI and agents. Options that accept ${...} variables say so. For the syntax, and for decrypted:<key> secrets, see Variables and expressions.
An API key or token written in a node’s config is stored and returned as written by the workflow APIs. Write decrypted:<key> instead. The server then reads the secret from the environment variable YUKTA_SECRET_<KEY> (the key in upper case, other characters turned into underscores).

LLM_CALL

Calls a chat model and emits its answer. It supports OpenAI and OpenAI-compatible endpoints (set baseUrl for Groq, vLLM and similar), Anthropic and Ollama. Output ports: default, or success and failure when routeByStatus is on.

messages

messages is either a literal list of turns, [{"role": "user", "content": "..."}], or a string that is an expression evaluated against the incoming message, such as payload['history']. Do not write it as ${...}: that form turns a list into text. Roles are user, assistant and tool. An assistant turn can carry the actions of its answer, and a tool turn ({"role": "tool", "toolCallId": "...", "toolName": "...", "content": "..."}) gives the result of one call, so the model sees a proper tool exchange.

Output

On success the payload is: The metadata gets llmSuccess set to true. A model may also write JSON inside <agent_action> tags in its text. Those blocks are parsed into actions too. With failureMode CONTINUE, a failed call emits the original payload unchanged, with the metadata llmSuccess set to false and the reason in llmError. With routeByStatus on, send failure to a second LLM_CALL node with another model to fail over.

tools

tools is a list of {"name", "description", "inputSchema"}, or an expression that gives one, such as payload.tools after an MCP_LIST_TOOLS node. The model may then answer with calls to these tools. They come back in actions and are not run by this node. Wire the actions to an MCP_TOOL_CALL node.

budget

The ledger is shared by every LLM_CALL and MCP_TOOL_CALL node of the same execution (and agent name). The check runs before each call and the usage is added after it, so one call can overshoot, and calls running at the same time can each pass the check. When the budget is used up, the next call fails like a failed call and failureMode applies. With hardStop set, the next call instead ends the whole execution: the engine does not retry it, drop it or route it as a dead letter, and failureMode does not absorb it. Budgets are kept in the memory of the server. They start again from zero after a restart and are not carried over when an execution is resumed. The server remembers the most recent 10,000 budget keys.

Server settings

A refused call fails the node like any other failed call. These settings apply to every LLM_CALL and decision node on the server.

Timeout and concurrency

Default timeout: (timeout + 1) * (retries + 1) + 5 seconds plus the backoff, about 127 seconds with the defaults. Up to 256 messages are handled at once, with results emitted in order.

MCP_LIST_TOOLS

Lists the tools of a remote MCP server so a model can choose among them. The server must speak MCP over streamable HTTP. Output port: default. The payload becomes {"tools": [{"name", "description", "inputSchema"}], "count": n}. It replaces the incoming payload, so keep anything you still need elsewhere. The plugin follows the server’s paging for up to 50 pages and fails if the list does not end by then. Messages are handled one at a time. Default timeout: timeout plus 5 seconds.

MCP_TOOL_CALL

Calls one tool on a remote MCP server for each message and emits the result. Use it as the “act” step of an agent loop, or to call another agent. Output ports: default, or success and failure when routeByStatus is on. The payload is {"success", "tool", "text", "content", "structured", "error"}: text is the text result, content the full list of result parts, structured the structured result if the tool gives one. The metadata gets mcpSuccess, mcpTool and mcpLatencyMs. A tool that reports an error with CONTINUE is emitted with success false and the message in error. Every call carries the message id and the attempt number in its request metadata (yukta/messageId and yukta/attempt), so a tool server can recognise a repeated call. The node keeps one MCP session per server and set of credentials and sends progress as heartbeats so a long call is not timed out while it reports progress. An approval works like WAIT_FOR_SIGNAL: answer the waiting node with the signal endpoint of its execution, using name equal to approvalSignal. A decision of reject refuses the call and any other decision allows it. See Approvals and signals.

Server settings

Default timeout: timeout plus 5 seconds, plus approvalTimeoutSeconds when requireApproval is set. Up to 256 messages are handled at once.

SESSION_MEMORY

Keeps chat history per conversation id, so a model sees earlier turns. Use two nodes: one in load mode before the model and one in append mode after it. Output port: default. load reads the stored turns first, then records the user turn. The payload is the incoming payload (an object; any other payload becomes {"input": <payload>}) plus history, a list of {"role", "content"}. The metadata gets sessionId, which lets a later append node find the conversation. Feed the history to the model with "messages": "payload['history']" and "prompt": "${payload.message}". append records the reply and passes the message on unchanged. If the model call fails after load, the user turn is already stored without an answer. The conversation id is the whole key: histories are shared across all sessions and workflows on the server. Where history is kept is a server setting: See Persistence. Up to 256 messages are handled at once; the default timeout is 30 seconds.

Limits and defaults