# Extending the module

> A Droost tool is a Tool API plugin. Write one in any module, and every route into Droost reaches it: drush, Drupal AI and MCP.

A tool is a [Tool API](https://www.drupal.org/project/tool) plugin under
`src/Plugin/tool/Tool/`, in droost or in any module of yours.

1. Carry Tool API's `#[Tool]` attribute: the id, label, description, the
   operation, a permission group and the input definitions.
2. Extend `DroostToolBase` for droost's envelope and its record of the
   call, or `DestructiveToolBase` for a tool that changes the site, which
   adds the `gate()` check. Set services in `create()`: Tool API's
   constructor is final.
3. Implement `run(array $arguments): mixed` and return
   `$this->succeed($message, $data)` or `$this->fail($message)`.

```php
#[Tool(
  id: 'droost_example',
  label: new TranslatableMarkup('Droost: Example'),
  description: new TranslatableMarkup('Returns a greeting. Read-only.'),
  operation: ToolOperation::Read,
  permission: 'use droost content tools',
  output_definitions: [
    'data' => new OutputDefinition(data_type: 'any', label: new TranslatableMarkup('Data'), description: new TranslatableMarkup('The greeting.'), required: FALSE),
  ],
)]
final class Example extends DroostToolBase {

  protected function run(array $arguments): mixed {
    return $this->succeed('Hello from Droost.', ['greeting' => 'hello']);
  }

}
```

Pick the permission by what the tool touches: `use droost content tools`
for what an editor manages, `use droost build tools` for site building,
`use droost developer tools` for the site's internals.

## Hooks

`droost.api.php` documents two hooks:

- `hook_droost_tool_tags()`: tag your tools by intent (introspection,
  config, entity…), so `drush droost:tool`'s listing groups them with
  droost's own.
- `hook_droost_config_set_validate()`: hold a configuration write to your
  own rule. [Droost UI Kit](https://droost.org/docs/droost-ui-kit.md) uses it so a display binding
  written through `droost_config_set` meets the same rule as its composer.

Tool API's `hook_tool_info_alter()` alters any tool's definition.

## Tests

Run droost's tests from a site, with the site's own PHPUnit configuration:

```bash
vendor/bin/phpunit -c phpunit.xml web/modules/contrib/droost
```
