Tool System

Table of contents

  1. Defining Tools
  2. Attributes Reference
  3. Special Parameters
  4. Registering Tools
    1. With an MCP server
    2. Direct registration (without MCP)
  5. Supported Return Types
  6. Built-in Tools
    1. EmbeddingTools
  7. Example: Multi-tool class

Agentic’s tool system lets you expose .NET methods to the language model using simple attributes. No boilerplate, no schema writing — just decorate your methods and register them.

Defining Tools

Implement IAgentToolSet and annotate methods with [Tool]:

using System.ComponentModel;

public class WeatherTools : IAgentToolSet
{
    [Tool, Description("Get the current weather for a city.")]
    public Task<string> GetWeather(
        [ToolParam("City name")] string city,
        [ToolParam("Unit: celsius or fahrenheit")] string unit = "celsius")
    {
        return Task.FromResult(
            $"The weather in {city} is 22 °{(unit == "fahrenheit" ? "F" : "C")} and sunny.");
    }

    [Tool, Description("List cities with active weather alerts.")]
    public Task<string[]> GetAlerts()
    {
        return Task.FromResult(new[] { "Paris", "London" });
    }
}

Attributes Reference

AttributeTargetDescription
[Tool]MethodMarks the method as an LLM-callable tool
[ToolParam("description")]ParameterDescribes the parameter to the model
[Description("...")]MethodThe tool description shown to the model (from System.ComponentModel)

Special Parameters

These parameter types are injected automatically and are invisible to the model:

TypeDescription
CancellationTokenCancelled when the tool call times out
ToolContextHTTP request headers from the MCP request (see Tool Context)

Registering Tools

With an MCP server

var app = builder.Build();
app.MapMcpServer("/mcp");

var tools = app.Services.GetRequiredService<ToolRegistry>();
tools.Register(new WeatherTools());

Direct registration (without MCP)

var registry = new ToolRegistry();
registry.Register(new WeatherTools());

Supported Return Types

Tools can return any type that can be serialised to JSON:

// String
public Task<string> GetName() => Task.FromResult("Alice");

// Object (serialised to JSON)
public Task<WeatherReport> GetWeather(string city) => ...;

// Collections
public Task<string[]> GetCities() => ...;

// Void (returns confirmation message)
public async Task SaveData(string value) { ... }

Built-in Tools

EmbeddingTools

Provides semantic embedding and similarity comparison tools to the model:

ToolDescription
embedGenerate an embedding vector for a text string
compare_similarityCosine similarity between a reference text and a list of others
toolRegistry.Register(new EmbeddingTools(lm));

Example: Multi-tool class

public class DatabaseTools : IAgentToolSet
{
    private readonly AppDbContext _db;

    public DatabaseTools(AppDbContext db) => _db = db;

    [Tool, Description("Find a customer by name.")]
    public async Task<string> FindCustomer(
        [ToolParam("Customer full name")] string name)
    {
        var customer = await _db.Customers
            .FirstOrDefaultAsync(c => c.Name == name);
        return customer is null
            ? $"No customer found with name '{name}'."
            : $"Found: {customer.Name}, ID: {customer.Id}";
    }

    [Tool, Description("Get all orders for a customer ID.")]
    public async Task<string> GetOrders(
        [ToolParam("Customer ID")] int customerId)
    {
        var orders = await _db.Orders
            .Where(o => o.CustomerId == customerId)
            .ToListAsync();
        return orders.Count == 0
            ? "No orders found."
            : string.Join("\n", orders.Select(o => $"Order #{o.Id}: {o.Total:C}"));
    }
}