Skip to Content
Reference[AgentTool]

[AgentTool] Attribute Reference

AgentToolAttribute marks a controller method (or an entire controller class) as an MCP-callable tool. It provides the Ithil source generator with the metadata needed to build the tool schema and governance rules at compile time.

Namespace

using Ithil.Attributes;

Placement

[AgentTool] is applied to individual controller action methods. Each decorated method becomes one MCP tool.

Parameter reference

ParameterTypeDefaultDescription
description (positional)string(required)Human-readable description shown to the agent in the MCP tool manifest. The model reads this to decide whether to call the tool — be specific.
AllowWriteboolfalseWhen false, the gateway rejects tool calls that would mutate state (POST, PUT, PATCH, DELETE). Set to true for intentional write tools.
MaxResponseTokensint2000Token ceiling on the response body. The gateway truncates or rejects responses exceeding this limit before they reach the agent.
RequiredScopesstring[]nullOAuth scopes the calling agent’s JWT must contain. The gateway returns 403 if any required scope is absent.
CategorystringnullGrouping label shown in the Ithil Dashboard’s tool library. Useful for organizing large tool sets.

Examples

Read-only tool (default settings)

[AgentTool("Returns the current inventory count for a given SKU")] [HttpGet("inventory/{sku}")] public IActionResult GetInventory(string sku) { var count = _inventoryService.GetCount(sku); return Ok(new { sku, count }); }

Write tool with scope and token limit

[AgentTool("Creates a new support ticket and returns the ticket ID", AllowWrite = true, MaxResponseTokens = 500, RequiredScopes = new[] { "support:write" }, Category = "Support")] [HttpPost("tickets")] public IActionResult CreateTicket([FromBody] TicketRequest req) { var ticket = _supportService.Create(req); return Ok(new { ticketId = ticket.Id }); }

How the source generator uses it

At compile time, the Ithil Roslyn source generator:

  1. Collects every method and class decorated with [AgentTool]
  2. Resolves the HTTP verb from [HttpGet], [HttpPost], etc.
  3. Resolves the full route template from [Route] on the class and method
  4. Builds the full tool schema for each method including the JSON Schema for its parameters
  5. Emits a SchemaRegistry static class containing a Tools collection

The gateway reads SchemaRegistry.Tools via the GET /ithil/schema endpoint at startup. No reflection occurs at runtime.

Writing good descriptions

The description is the single most important field. It is what the AI model reads to decide whether and when to call your tool.

WeakerStronger
"Gets an order""Returns full order details including line items, status, and shipping address for a given order ID"
"Updates inventory""Decrements the available inventory count for a SKU by a specified quantity. Fails if count would go negative."
"Sends a message""Sends an email notification to a customer. Requires the customer's email address and a message body."

Be specific about:

  • What the tool returns
  • What inputs it requires
  • Any side effects (mutations, external calls, notifications)
  • Any failure conditions the agent should know about

A vague description causes the model to call the wrong tool or hallucinate arguments. Treat the description as part of your public API contract.

Last updated on