bots-garden/mini-mepublic Fork
⑂ feature/go-1.27.3
Commits
⬇ Clone ▾
git clone https://git.rickub.com/bots-garden/mini-me.git
git clone ssh://git@rickub.com/bots-garden/mini-me.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP
🛟 Updated. 5988c55 · on feature/go-1.27.3 · k33g · 11d ago
declare-a-custom-tool.md · 61 lines · 3.3 KBmarkdown
Blame HistoryOpen raw

How to declare a custom tool

This guide shows how to turn a script or a program into a tool the model sees on every turn, with typed parameters, by declaring it in the agent file. It assumes you have an agent YAML file and a command you already run by hand.

Use it for a frequent, precise action — run the tests of a package, prepare a release, query a service. For a procedure in several steps, or know-how the model should read before acting, write a skill instead.

Steps

  1. Make sure the command works from the directory mm runs in:

    ./scripts/release.sh 1.4.2 beta
    
  2. Add a tools: block to the agent file, with one entry per command. Name the tool after the action, describe what it does and when to use it, declare one parameter per argument, and write the command as a list — the program first, then one entry per argument, with {{parameter}} where a value goes:

    tools:
      - name: release
        description: Prepare a release of the project for a given version and channel.
        parameters:
          version: { type: string, description: "e.g. 1.4.2" }
          channel: { type: string, enum: [stable, beta, nightly] }
        command: ["./scripts/release.sh", "{{version}}", "{{channel}}"]
    
  3. Start mm and check that the banner lists the tool among the others (release here). A mistake in the block stops mm with a [config error: …] naming the entry; the configuration reference lists them.

  4. Ask for the action in your own words:

    mm -p "Prepare release 1.4.2 on the beta channel."
    

    The terminal shows the call and its output:

    🧰 release: ./scripts/release.sh 1.4.2 beta
       │ release done: 1.4.2 beta
    

Variants

  • A number, an integer or a flag. Give the parameter a type: number, integer or boolean. A boolean usually goes inside an entry: "--dry-run={{dryRun}}".

  • An optional argument. Add required: false. Left out by the model, an entry that is only "{{p}}" disappears from the command; give a default to pass a value anyway:

    retries: { type: integer, required: false, default: 3 }
    
  • A command longer than bashTimeout. Add timeout: 2m to the entry.

  • Ask before each call. Set yolo: false: the declared tools then ask like bash does. With yolo: true they run without asking.

  • A shell feature (pipe, redirection, &&). The command runs without a shell, so write it in a script and declare the script. Passing ["bash", "-c", "…{{p}}…"] would put the model's value back into a shell line.

  • The same action as an MCP tool. A declared tool cannot take the name of an MCP tool: it is skipped with a start-up warning. Rename one of them.

  • Restrict what runs before or after. preToolCall and postToolCall hooks apply to declared tools; use the tool's name as matcher.

See also

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# How to declare a custom tool

This guide shows how to turn a script or a program into a tool the model sees on every turn, with typed parameters, by declaring it in the agent file. It assumes you have an agent YAML file and a command you already run by hand.

Use it for a frequent, precise action — run the tests of a package, prepare a release, query a service. For a procedure in several steps, or know-how the model should read before acting, write a [skill](add-a-skill.md) instead.

## Steps

1. Make sure the command works from the directory mm runs in:

   ```bash
   ./scripts/release.sh 1.4.2 beta
   ```

2. Add a `tools:` block to the agent file, with one entry per command. Name the tool after the action, describe what it does and when to use it, declare one parameter per argument, and write the command as a list — the program first, then one entry per argument, with `{{parameter}}` where a value goes:

   ```yaml
   tools:
     - name: release
       description: Prepare a release of the project for a given version and channel.
       parameters:
         version: { type: string, description: "e.g. 1.4.2" }
         channel: { type: string, enum: [stable, beta, nightly] }
       command: ["./scripts/release.sh", "{{version}}", "{{channel}}"]
   ```

3. Start mm and check that the banner lists the tool among the others (`release` here). A mistake in the block stops mm with a `[config error: …]` naming the entry; the [configuration reference](../reference/configuration.md#validation-errors) lists them.

4. Ask for the action in your own words:

   ```bash
   mm -p "Prepare release 1.4.2 on the beta channel."
   ```

   The terminal shows the call and its output:

   ```
   🧰 release: ./scripts/release.sh 1.4.2 beta
      │ release done: 1.4.2 beta
   ```

## Variants

- **A number, an integer or a flag.** Give the parameter a `type`: `number`, `integer` or `boolean`. A boolean usually goes inside an entry: `"--dry-run={{dryRun}}"`.
- **An optional argument.** Add `required: false`. Left out by the model, an entry that is only `"{{p}}"` disappears from the command; give a `default` to pass a value anyway:

  ```yaml
  retries: { type: integer, required: false, default: 3 }
  ```

- **A command longer than `bashTimeout`.** Add `timeout: 2m` to the entry.
- **Ask before each call.** Set `yolo: false`: the declared tools then ask like `bash` does. With `yolo: true` they run without asking.
- **A shell feature (pipe, redirection, `&&`).** The command runs without a shell, so write it in a script and declare the script. Passing `["bash", "-c", "…{{p}}…"]` would put the model's value back into a shell line.
- **The same action as an MCP tool.** A declared tool cannot take the name of an MCP tool: it is skipped with a start-up warning. Rename one of them.
- **Restrict what runs before or after.** `preToolCall` and `postToolCall` [hooks](guard-the-agent-with-hooks.md) apply to declared tools; use the tool's name as `matcher`.

## See also

- A complete example with four tools and every parameter type: `demos/declared-tools/`
- Every key, type and error: [configuration reference](../reference/configuration.md#tools-keys) and [declared tools](../reference/tools.md#declared-tools)
- Why typed tools beside skills, and what was measured: [Declared tools](../explanation/declared-tools.md)