Skip to Content
Getting StartedQuickstart

Quickstart

Go from zero to a working Ithil gateway with an annotated ASP.NET API in under 10 minutes.

Prerequisites

  • .NET 10 SDK 
  • Docker (for Redis)
  • An existing ASP.NET Web API project, or the Ithil sample project

Run Redis

Ithil requires Redis for budget tracking and the semantic cache. Start it with Docker:

docker run -d -p 6379:6379 redis

If you see a long string of letters and numbers printed, Redis is running.

Add Ithil.Hosting to your API

Install the NuGet package:

dotnet add package Ithil.Hosting

Add four lines to your existing Program.cs (marked with // ADD THIS):

using Ithil.Generated; // ADD THIS using Ithil.Hosting; // ADD THIS var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddIthilHosting(); // ADD THIS // ... your existing services ... var app = builder.Build(); app.MapControllers(); app.MapIthilSchema(SchemaRegistry.Tools); // ADD THIS app.Run();

Annotate a controller method

Add [AgentTool] to any controller method you want the AI agent to be able to call:

using Ithil.Attributes; [ApiController] [Route("api/placeholder")] public class JsonPlaceholderController(IHttpClientFactory httpClientFactory) : ControllerBase { private HttpClient Client => httpClientFactory.CreateClient("jsonplaceholder"); [AgentTool("Returns a single post by ID")] // ADD THIS [HttpGet("posts/{id:int}")] public async Task<IActionResult> GetPost(int id) => Ok(await Client.GetFromJsonAsync<object>($"posts/{id}")); }

The [AgentTool] attribute is the only change to your existing code. The source generator emits SchemaRegistry at compile time — no reflection, no runtime overhead.

Run Ithil.Gateway

Docker (recommended):

docker run -d \ -p 5100:8080 \ -e Ithil__LicenseKey="your-license-key" \ -e Ithil__Jwt__SigningKey="your-32-byte-or-longer-signing-key" \ -e Ithil__ToolRegistry__DownstreamBaseUrl="http://host.docker.internal:5200" \ -e ConnectionStrings__Redis="host.docker.internal:6379" \ ithilsoftware/gateway:latest

Manual:

Get a free license key at ithil.software/register  before running — the gateway will refuse to start without one.

dotnet run --project src/Ithil.Gateway

Minimum appsettings.json for the gateway:

{ "Ithil": { "LicenseKey": "your-license-key", "Jwt": { "SigningKey": "your-32-byte-or-longer-signing-key" }, "ToolRegistry": { "DownstreamBaseUrl": "http://localhost:5200" } }, "ConnectionStrings": { "Redis": "localhost:6379" } }

Verify the tool appears

In development, get a short-lived agent JWT from the gateway’s dev token endpoint:

curl http://localhost:5100/dev/token

Initialize an MCP session:

curl -si http://localhost:5100/mcp \ -H "Authorization: Bearer <token-from-above>" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"0.1"}}}'

In the response headers, find the Mcp-Session-Id line — it looks like this:

Mcp-Session-Id: ugsxZkcDzylMsjpfYTEc6w

Copy that value, then list your tools:

curl -s http://localhost:5100/mcp \ -H "Authorization: Bearer <token-from-above>" \ -H "Mcp-Session-Id: <value-from-Mcp-Session-Id-header>" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'

You should see your tool listed in the response.

Make a tool call

curl -s http://localhost:5100/mcp \ -H "Authorization: Bearer <token-from-above>" \ -H "Mcp-Session-Id: <value-from-Mcp-Session-Id-header>" \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "GetPost", "arguments": { "id": 1 } } }'

You should see the post data returned in the response.

What just happened

The gateway received the MCP request, validated the agent’s JWT, checked the agent’s daily token budget, forwarded the call to your ASP.NET API’s GET /api/placeholder/posts/1 endpoint, filtered the response through the privacy rules, and returned the result back to the agent — all transparently.

Next steps

Last updated on