TimHanewich.Ollama is a lightweight .NET library for interfacing with local language models running via Ollama. It provides a clean, strongly-typed interface for chatting with models, making tool (function) calls, and receiving structured JSON outputs.
- 💬 Chat Completions: Simple, strongly-typed request/response model for the Ollama Chat API.
- 🛠️ Function Calling: Native support for defining tools and handling tool calls from the model.
- 📦 JSON Mode: Built-in support for structured JSON outputs from the model.
- 🧠 Thinking Tokens: Access model reasoning/thinking tokens when available.
TimHanewich.Ollama is available on NuGet! Install it by running:
dotnet add package TimHanewich.Ollama
Below are some examples on how to use this library. These examples assume you have Ollama installed and running locally on the default port (11434).
using TimHanewich.Ollama;
ChatRequest req = new ChatRequest();
req.Model = "qwen3.5:0.8b";
req.Messages.Add(new Message(Role.user, "Why is the sky blue?"));
OllamaClient ollama = new OllamaClient();
ChatResponse resp = await ollama.ChatAsync(req);
Console.WriteLine("Model: " + resp.Model);
Console.WriteLine("Input tokens: " + resp.InputTokens.ToString());
Console.WriteLine("Output tokens: " + resp.OutputTokens.ToString());
Console.WriteLine("Response: " + resp.Message.Content);You can define tools the model can call and then handle the results:
using TimHanewich.Ollama;
using Newtonsoft.Json.Linq;
ChatRequest req = new ChatRequest();
req.Model = "qwen3.5:0.8b";
req.Messages.Add(new Message(Role.user, "What is the temperature in Chicago?"));
// Define a tool
Tool t = new Tool("check_weather", "Check the weather for any city.");
t.Parameters.Add(new ToolInputParameter("city", "The name of the city to check the weather for"));
req.Tools.Add(t);
// Call the model
OllamaClient ollama = new OllamaClient();
ChatResponse resp = await ollama.ChatAsync(req);
// Handle tool calls
foreach (ToolCall tc in resp.Message.ToolCalls)
{
if (tc.ToolName == "check_weather")
{
JProperty? prop_city = tc.Arguments.Property("city");
if (prop_city != null)
{
string city = prop_city.Value.ToString();
Console.WriteLine("Model wants weather for: " + city);
}
}
}After the model makes a tool call, provide the result and re-prompt:
// Add the assistant's message (with tool calls) back into the conversation
req.Messages.Add(resp.Message);
// Add the tool response
Message tool_response = new Message();
tool_response.Role = Role.tool;
tool_response.Content = "Weather in Chicago: 72°F and sunny.";
req.Messages.Add(tool_response);
// Re-prompt the model with the tool result
ChatResponse resp2 = await ollama.ChatAsync(req);
Console.WriteLine("Response: " + resp2.Message.Content);Force the model to respond with structured JSON:
ChatRequest req = new ChatRequest();
req.Model = "qwen3.5:0.8b";
req.JsonMode = true;
req.Messages.Add(new Message(Role.user, "List three colors and their hex codes as a JSON array."));
OllamaClient ollama = new OllamaClient();
ChatResponse resp = await ollama.ChatAsync(req);
Console.WriteLine(resp.Message.Content); // structured JSON output