---
title: "Composition · Finch Agent"
description: "Agent tools, interaction/service capabilities, and bundled skills"
source: https://finchwork.app/en/docs/minitools-composition
---

# Composition

A package can contain three kinds of things, aimed at three different consumers:

## Agent tools

Functions the model can call. Two hard rules by design.

**Rule one: keep the number of tools as small as possible.** Every registered tool gets injected into the model's context on every turn — more tools means more tokens and a higher chance the model picks the wrong one.

**Rule two: merge related operations into a single tool with an `action` parameter.**

```ts
ctx.tools.register({
  name: 'pjblog_post',
  title: 'PJBlog Post',
  description: `Manage blog posts.
action:
  list    — list all posts
  create  — create a new draft
  update  — update an existing post
  publish — publish a draft`,
  inputSchema: {
    type: 'object',
    properties: {
      action: { type: 'string', enum: ['list', 'create', 'update', 'publish'] },
      slug: { type: 'string' },
      title: { type: 'string' },
    },
    required: ['action'],
  },
  risk: 'medium',
  async execute(input, exec) { /* switch (input.action) */ },
});
```

`description` must enumerate every `action` — it's the model's only manual for how to use the tool.

Tool names are fixed lowercase snake\_case, in the form `<mini_tool_name>_<function_name>`. Avoid generic short names like `init` or `status`.

If you genuinely need more than 10 tools, switch to a local MCP server for on-demand loading — see [MCP integration](/en/docs/minitools-mcp).

**Long-running task progress**: `exec.progress.report({ message })` shows an indeterminate progress indicator; add `percent` for a determinate one. Progress isn't the result — the tool still must return a final `ToolResult`.

## Interaction & service capabilities

The parts not aimed at the model, triggered by the user or the system instead: Composer buttons, dialogs, forms, session containers, OAuth login, MCP bridging, background polling. This is the mini tool's "service surface" — see [Standardized UI](/en/docs/minitools-ui), [Accounts, settings & OAuth login](/en/docs/minitools-oauth), [Session containers](/en/docs/minitools-containers), and [Session Loop](/en/docs/minitools-sessions).

## Bundled skills

A package can bundle skills, active while enabled and gone once disabled:

```text
my-mini-tool/
└── skills/
    └── my-workflow/
        └── SKILL.md
```

Declare `contributes.skills: true` in the manifest — no need to do anything else. They are never copied into the global skills directory.
