Tool Registration for OpenRegister Agents
This guide explains how to create and register custom tools for OpenRegister agents. Tools enable AI agents to perform actions through function calling, allowing them to interact with your app's data and functionality.
Overview
OpenRegister provides a plugin architecture for tools that allows any Nextcloud app to register custom functions that agents can use. Tools are automatically discovered and made available to all agents through a central registry.
Key Concepts
- Tool: A collection of related functions that an agent can call
- ToolRegistry: Central service that manages all available tools
- ToolRegistrationEvent: Event dispatched when tools are being collected
- ToolInterface: Contract that all tools must implement
Architecture
Creating a Tool
Step 1: Implement the ToolInterface
Create a new tool class in your app that implements the OCA\OpenRegister\Tool\ToolInterface:
<?php
declare(strict_types=1);
namespace OCA\MyApp\Tool;
use OCA\OpenRegister\Tool\ToolInterface;
use OCA\OpenRegister\Db\Agent;
use OCA\MyApp\Service\MyService;
use Psr\Log\LoggerInterface;
class MyCustomTool implements ToolInterface
{
private ?Agent $agent = null;
public function __construct(
private MyService $myService,
private LoggerInterface $logger
) {
}
public function getName(): string
{
return 'My Custom Tool';
}
public function getDescription(): string
{
return 'Allows agents to interact with MyApp data';
}
public function setAgent(Agent $agent): void
{
$this->agent = $agent;
}
public function getFunctions(): array
{
return [
[
'name' => 'myapp_create_item',
'description' => 'Create a new item in MyApp',
'parameters' => [
'type' => 'object',
'properties' => [
'name' => [
'type' => 'string',
'description' => 'Name of the item to create'
],
'description' => [
'type' => 'string',
'description' => 'Optional description'
]
],
'required' => ['name']
]
],
[
'name' => 'myapp_list_items',
'description' => 'List all items in MyApp',
'parameters' => [
'type' => 'object',
'properties' => [
'limit' => [
'type' => 'integer',
'description' => 'Maximum number of items to return'
]
],
'required' => []
]
]
];
}
public function executeFunction(string $functionName, array $parameters, ?string $userId = null): array
{
try {
switch ($functionName) {
case 'myapp_create_item':
$item = $this->myService->createItem(
$parameters['name'],
$parameters['description'] ?? '',
$userId
);
return [
'success' => true,
'data' => ['id' => $item->getId(), 'name' => $item->getName()]
];
case 'myapp_list_items':
$items = $this->myService->listItems(
$parameters['limit'] ?? 10,
$userId
);
return [
'success' => true,
'data' => ['items' => $items]
];
default:
return [
'success' => false,
'error' => 'Unknown function: ' . $functionName
];
}
} catch (\Exception $e) {
$this->logger->error('[MyCustomTool] Error executing function', [
'function' => $functionName,
'error' => $e->getMessage()
]);
return [
'success' => false,
'error' => $e->getMessage()
];
}
}
}
Step 2: Register the Tool
In your app's lib/AppInfo/Application.php, listen to the ToolRegistrationEvent and register your tool:
<?php
namespace OCA\MyApp\AppInfo;
use OCA\OpenRegister\Event\ToolRegistrationEvent;
use OCA\MyApp\Tool\MyCustomTool;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\EventDispatcher\IEventDispatcher;
class Application extends App implements IBootstrap
{
public const APP_ID = 'myapp';
public function __construct()
{
parent::__construct(self::APP_ID);
}
public function register(IRegistrationContext $context): void
{
// Register the tool registration listener
$context->registerEventListener(
ToolRegistrationEvent::class,
\OCA\MyApp\Listener\ToolRegistrationListener::class
);
}
public function boot(IBootContext $context): void
{
// Boot logic here
}
}