Show HN: Toolnexus for .NET – MCP and agent skills as tools for any LLM

muthuishere1 pts0 comments

NuGet Gallery<br>| Toolnexus 0.1.2

Toolnexus

0.1.2

.NET 10.0

This package targets .NET 10.0. The package is compatible with this framework or higher.

.NET CLI

PMC

PackageReference

CPM

Paket CLI

Script & Interactive

File-Based Apps

Cake

dotnet add package Toolnexus --version 0.1.2

Copy

NuGet\Install-Package Toolnexus -Version 0.1.2

Copy

This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.

Copy

For projects that support PackageReference, copy this XML node into the project file to reference the package.

Directory.Packages.props

Copy

Project file

Copy

For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.

paket add Toolnexus --version 0.1.2

Copy

The NuGet Team does not provide support for this client. Please contact its maintainers for support.

#r "nuget: Toolnexus, 0.1.2"

Copy

#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.

#:package Toolnexus@0.1.2

Copy

#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.

#addin nuget:?package=Toolnexus&version=0.1.2

Install as a Cake Addin

Copy

#tool nuget:?package=Toolnexus&version=0.1.2

Install as a Cake Tool

Copy

The NuGet Team does not provide support for this client. Please contact its maintainers for support.

README

Frameworks

Dependencies

Used By

Versions

toolnexus

Build an agent in a few lines. Point at an mcp.json and a skills/ folder, call RunAsync(),<br>and you have a working agent — MCP servers, agent skills, your own functions, and HTTP endpoints<br>unified as one tool set, driving any LLM.

Right-sized. Not a framework (no builders, no config to wade through), not a toy that falls<br>over the moment you need streaming or a retry. Everything a real agent needs — the loop, hooks,<br>streaming, retries, memory — and nothing it doesn't.

The C#/.NET port of toolnexus — the same library,<br>byte-identical, also in JavaScript, Python, Go, and Java . Built on the official<br>ModelContextProtocol SDK. Targets .NET 10.

Install

dotnet add package Toolnexus

An agent in 3 steps

using Toolnexus;

// 1. tools from an mcp.json + a skills/ folder<br>await using var tk = await Toolkit.CreateAsync(new Toolkit.Options()<br>.WithMcpConfig("./mcp.json")<br>.WithSkillsDir("./skills"));

// 2. point at any OpenAI- or Anthropic-style endpoint<br>var agent = LlmClient.Create(new LlmClient.Options<br>BaseUrl = "https://openrouter.ai/api/v1",<br>Style = "openai", // or "anthropic"<br>Model = "openai/gpt-4o-mini",<br>ApiKey = Environment.GetEnvironmentVariable("OPENROUTER_API_KEY"),<br>});

// 3. run — skills injected into the system prompt, tools called for you, looped to an answer<br>var res = await agent.RunAsync("Refund order 1234 for the customer.", tk);<br>Console.WriteLine(res.Text);

The loop runs call → execute tools → feed back → repeat, with hooks, streaming, retries/backoff,<br>and conversation memory available. res carries Text, ToolCalls, usage, turns, and model.

Add your own tools

using Toolnexus;

// a method → a tool (attribute-based)<br>public sealed class MathTools<br>[ToolMethod("add", "Add two numbers")]<br>public string Add([Param("a")] double a, [Param("b")] double b) => (a + b).ToString();

tk.Register(Tools.FromObject(new MathTools()).ToArray());

// a REST endpoint → a tool<br>tk.Register(HttpTool.Of(new HttpTool.Options<br>Name = "create_ticket", Description = "Create a ticket", Method = "POST",<br>Url = "https://api.example.com/tickets",<br>Headers = new Dictionary { ["Authorization"] = "Bearer ${API_TOKEN}" }, // ${ENV} expands, never logged<br>InputSchema = new Dictionary<br>["type"] = "object",<br>["properties"] = new Dictionary { ["title"] = new Dictionary { ["type"] = "string" } },<br>["required"] = new List { "title" },<br>},<br>}));

You can also pass ExtraTools / AnnotatedObjects straight into Toolkit.Options.

Bring your own loop

var tools = tk.ToOpenAI(); // or tk.ToAnthropic() / tk.ToGemini()<br>var system = tk.SkillsPrompt(); // skills catalog for your system prompt<br>// when the model returns a tool call (name, arguments):<br>var res = await tk.ExecuteAsync(name, args); // -> ToolResult(Output, IsError, Metadata)

The four sources

Source<br>How

MCP servers<br>an mcp.json (mcpServers/servers/mcp); local stdio + remote streamable-HTTP, Headers for auth

Agent skills<br>a folder of /SKILL.md; a skill tool loads each on demand + a system-prompt catalog

Native tools<br>[ToolMethod]/[Param] on a class (Tools.FromObject), or NativeTool.Of(...)

HTTP / REST<br>HttpTool.Of(...) — an endpoint becomes a tool, ${ENV} headers

All four appear as one uniform ITool in tk.Tools().

API

Member<br>Description

Toolkit.CreateAsync(opts)<br>async factory → Toolkit (await using)

LlmClient.Create(opts)<br>the unified host loop...

package toolnexus copy tools agent tool

Related Articles