Skip to content

Tool System

The tool system lets you define, validate, and execute tools that the agent can invoke during its ReAct loop.

Defining Tools

typescript
import { ToolRegistry } from '@opensin/sdk'

const tools = new ToolRegistry()

tools.register({
  name: 'read_file',
  description: 'Read the contents of a file',
  parameters: {
    type: 'object',
    properties: {
      path: {
        type: 'string',
        description: 'Absolute or relative file path',
      },
      encoding: {
        type: 'string',
        enum: ['utf-8', 'base64'],
        default: 'utf-8',
      },
    },
    required: ['path'],
  },
  execute: async ({ path, encoding = 'utf-8' }) => {
    const content = await fs.readFile(path, encoding)
    return { content }
  },
})

Built-in Tools (CLI)

The OpenSIN CLI ships with 11 built-in tools:

ToolDescription
bashExecute shell commands (with execFile for safety)
readRead file contents with line numbers
writeCreate or overwrite files
editExact string replacement in files
grepSearch file contents (literal by default, opt-in regex)
globFind files by pattern matching
web_fetchFetch content from URLs
web_searchSearch the web and return results
todo_writeManage a structured task list
worktreeGit worktree management
plan_modeStructured planning mode

JSON Schema Validation

Tool parameters are validated against their JSON Schema before execution:

typescript
// This will throw a validation error
await tools.execute('read_file', { path: 123 }) // path must be string

// This passes validation
await tools.execute('read_file', { path: 'src/app.ts' })

Tool Results

Tools return structured results:

typescript
interface ToolResult {
  content: string       // Text content for the LLM
  isError?: boolean     // Whether the execution failed
  metadata?: Record<string, unknown>  // Additional structured data
}

MCP Tool Integration

Load tools from MCP (Model Context Protocol) servers:

typescript
import { MCPStdioClient } from '@opensin/sdk'

const mcp = new MCPStdioClient({
  command: 'node',
  args: ['path/to/mcp-server.js'],
})

await mcp.connect()

// List available tools
const mcpTools = await mcp.listTools()

// Register MCP tools in the tool registry
for (const tool of mcpTools) {
  tools.registerMCP(tool, mcp)
}

Custom Tool Categories

Organize tools by category for better LLM context:

typescript
tools.register({
  name: 'query_database',
  category: 'database',
  description: 'Run a SQL query',
  // ...
})

tools.register({
  name: 'insert_record',
  category: 'database',
  description: 'Insert a record',
  // ...
})

// Get tools by category
const dbTools = tools.getByCategory('database')

Error Handling

Tool errors are caught and returned to the LLM as error results:

typescript
tools.register({
  name: 'risky_tool',
  // ...
  execute: async (args) => {
    try {
      const result = await riskyOperation(args)
      return { content: result }
    } catch (error) {
      return {
        content: `Error: ${error.message}`,
        isError: true,
      }
    }
  },
})

The agent loop will see the error and can decide to retry, try a different approach, or report the failure to the user.

Released under the Apache 2.0 License.