Tools

Tool definitions stored on a version, in whatever shape your provider expects, and how compile hands them back for you to wire into your tool-calling loop.

tools is an array a version carries alongside its messages. In the dashboard it's edited as raw JSON.

The shape is yours

Trodo does not enforce a tool schema. Every provider spells a tool differently, OpenAI nests under function.parameters, Anthropic uses a flat input_schema, Gemini wants functionDeclarations, and new ones keep appearing. Enforcing one layout would reject definitions that are correct for the model you're actually calling.

The only rules are the ones that stop a value breaking downstream: tools must be an array of objects. What those objects contain is up to you, and it's stored and returned byte-for-byte.

So this is valid:

tools: OpenAI native
[
  {
    "type": "function",
    "function": {
      "name": "get_order_status",
      "description": "Look up an order",
      "parameters": {
        "type": "object",
        "properties": { "order_id": { "type": "string" } },
        "required": ["order_id"]
      }
    }
  }
]

…and so is the Trodo envelope below, which is what the mcp_tool reference builds on and what the examples on this page use.

Function tools

A function tool in the Trodo envelope is self-contained: a name and an input_schema. Nothing is resolved at run time: the whole definition lives on the version.

tools
[
  {
    "kind": "function",
    "name": "get_order_status",
    "input_schema": {
      "type": "object",
      "properties": {
        "order_id": { "type": "string", "description": "The order to look up" }
      },
      "required": ["order_id"]
    }
  }
]

What compile returns

compile() returns the tool references on the tools field: it doesn't execute anything. You take those references, register them with your provider's tool-calling API, and run the loop yourself.

const { messages, model, tools } = prompt.compile({ question: 'refund status?' });

// Map the function tools into your provider's tool format, then run the loop.
const openaiTools = tools
  .filter((t) => t.kind === 'function')
  .map((t) => ({ type: 'function', function: { name: t.name, parameters: t.input_schema } }));

const answer = await openai.chat.completions.create({
  model: model.model ?? 'gpt-4o',
  messages,
  tools: openaiTools,
});
compiled = prompt.compile(question="refund status?")

openai_tools = [
    {"type": "function", "function": {"name": t["name"], "parameters": t["input_schema"]}}
    for t in compiled.tools
    if t["kind"] == "function"
]

answer = openai.chat.completions.create(
    model=compiled.model.get("model", "gpt-4o"),
    messages=compiled.messages,
    tools=openai_tools,
)

On this page