Extending the Agent
You can extend your agent by adding custom tools and integrating with other services.
Custom Tools
Custom tools are built using the DynamicStructuredTool
class from LangChain, which provides:
- Type-safe inputs: Define your tool’s parameters using Zod schemas
- Self-documenting: Tools describe themselves to the LLM for appropriate use
- Structured outputs: Return consistent data structures from your tools
Example Tool Implementation
Here’s an example of how to create a custom tool:
import { createLogger } from '@autonomys/agent-core';
import { DynamicStructuredTool } from '@langchain/core/tools';
import { z } from 'zod';
// Create a logger for your tool
const logger = createLogger('custom-tool');
/**
* Creates a custom tool for your agent
* @param config - Configuration options for your tool
* @returns A DynamicStructuredTool instance
*/
export const createCustomTool = (config: any) => {
return new DynamicStructuredTool({
name: 'custom_tool_name',
description: `
Description of what your tool does.
USE THIS WHEN:
- Specify when the agent should use this tool
- Add clear usage guidelines
OUTPUT: Describe what the tool returns
`,
schema: z.object({
// Define your input parameters using Zod
parameter1: z.string().describe('Description of parameter1'),
parameter2: z.number().describe('Description of parameter2'),
parameter3: z.boolean().optional().describe('Optional parameter'),
// For enum parameters:
parameter4: z
.enum(['option1', 'option2', 'option3'])
.default('option1')
.describe('Parameter with predefined options'),
}),
func: async ({ parameter1, parameter2, parameter3, parameter4 }) => {
try {
// Log the function call
logger.info('Custom tool called with parameters', {
parameter1,
parameter2,
parameter3,
parameter4,
});
// Implement your tool logic here
// ...
// Return a structured response
return {
success: true,
result: {
message: 'Operation completed successfully',
data: {
// Your output data
},
},
};
} catch (error) {
// Log and handle errors
logger.error('Error in custom tool:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error',
};
}
},
});
};
Using MCP Tools
Model Context Protocol (MCP) tools provide a standardized way to integrate external services with your agent. Here’s an example for Notion integration:
import { createMcpClientTool } from '@autonomys/agent-core';
import { StdioServerParameters } from '@modelcontextprotocol/sdk/client/stdio.js';
import { StructuredToolInterface } from '@langchain/core/tools';
export const createNotionTools = async (
integrationSecret: string,
): Promise<StructuredToolInterface[]> => {
const notionServerParams: StdioServerParameters = {
command: process.execPath,
args: ['node_modules/.bin/notion-mcp-server'],
env: {
OPENAPI_MCP_HEADERS: `{\"Authorization\": \"Bearer ${integrationSecret}\", \"Notion-Version\": \"2022-06-28\" }`,
},
};
const tools = await createMcpClientTool('notion-mcp', '0.0.1', notionServerParams);
return tools;
};
Installing Pre-Built Tools
You can easily install pre-built tools from the Autonomys registry using the agent-os CLI:
# Search for available tools
agent-os search <search-term>
# Install a tool
agent-os install <tool-name>
# Install specific version
agent-os install <tool-name> -v <version>
After installation, import and register the tool:
import { createTool } from './tools/<tool-name>';
// Add it to your agent's tools
const agent = new Agent({
tools: [createTool(), ...otherTools],
// other agent configuration
});