Liking cljdoc? Tell your friends :D

toolnexus

Building any agentic framework? Build it on toolnexus. Fast tool calling, any number of MCP servers, any agent skill and media generation, for any LLM, in eight languages.

CI npm PyPI NuGet Maven Central Hex.pm Clojars crates.io Go Go Reference docs.rs Docs license Discord

One vendor-neutral agent library, ported by hand to JavaScript, Python, Go, Java, C#, Elixir, Clojure and Rust, held to one conformance contract (SPEC.md) so the shared examples/ produce the same output in every port.

The idea: it is all the same thing to an LLM

An MCP server tool, an agent skill, your own function, a remote HTTP endpoint, a built-in shell/file tool, a remote A2A agent and an in-process sub-agent are all the same thing to a model: a named, described, schema'd callable (an insight borrowed from opencode). toolnexus puts every one of them behind one Tool interface, emits the schema in OpenAI / Anthropic / Gemini shape, and drives any model with them through one client loop.

Install (0.28.0)

npm i toolnexus                                   # JavaScript / TypeScript (npm)
pip install toolnexus                             # Python (PyPI)
go get github.com/muthuishere/toolnexus/golang    # Go
dotnet add package Toolnexus                       # C# / .NET (NuGet)
{:toolnexus, "~> 0.28"}                             # Elixir (mix.exs deps, Hex)
# Java (Maven Central): io.github.muthuishere:toolnexus:0.28.0
# Clojure (deps.edn, Clojars): net.clojars.muthuishere/toolnexus {:mvn/version "0.28.0"} (JVM and cljgo)
cargo add toolnexus                                # Rust (crates.io)

Zero to agent

Point it at an mcp.json (the standard Claude-desktop-style config) and a skills/ folder of SKILL.md files, then run:

import { createToolkit, createClient } from "toolnexus"

const tk = await createToolkit({ mcpConfig: "./mcp.json", skillsDir: "./skills" })
const agent = createClient({ baseUrl: "https://openrouter.ai/api/v1", style: "openai", model: "openai/gpt-4o-mini" })

const { text } = await agent.run("Refund order 4021 using the policy.", { toolkit: tk })

The key comes from OPENROUTER_API_KEY because the host is openrouter.ai: a key is only ever sent to the host it belongs to. A local server or proxy needs apiKey or apiKeyEnv (recipe). The same shape in every language: Quickstart.

What you get

  • MCP, 2026-07-28 and legacy — client for stdio and streamable-HTTP servers, and a server: expose your toolkit over MCP. Elicitation, OAuth and per-server readiness included; Rust runs stdio servers on its own client. MCP
  • Agent skills — the open SKILL.md standard, loaded on demand through one skill tool. Skills
  • Native, HTTP and built-in tools — your functions, remote endpoints, shell/file tools. Native · HTTP · Built-ins
  • A2A — call remote agents as tools, or serve your toolkit as one. A2A
  • ACP and the in-process client — drive a local coding agent over ACP, or any function, as the client's model; tool-call arguments stream as events, and setMode / setModel switch a running agent without a restart. In-process client
  • Typed decisions — createClassifier and judge adapters: yes/no, pick-one and score answers as typed values, on any System One endpoint or OpenAI's Decisions API. Typed decisions · Backends
  • Media generation — images, video and speech from a JSON style, as typed calls and as agent tools. Media
  • Human in the loop — any tool can suspend on a Request; a waitFor host resolves it, or the run returns pending and resumes later. Suspension
  • The loop — parallel and chained tool calls, hooks (including an afterRound hook), streaming with retry events, retries and resilience, opt-in model fallback on overload, stop-reason recovery, reactive compaction on context overflow, prompt caching and tool tiers, sub-agents, observability. Streaming · Resilience · Sub-agents
  • Memory — a memory hierarchy for persona agents, with built-in dreaming: a pass that checks memory against the transcripts and fixes or prunes it. Memory · Dreaming
  • Run without a model — a key-free local mock server for every wire toolnexus speaks: chat, streaming, tool calls, classifiers, media and faults. Mock server

Exact per-port spellings and any port-specific gaps are in CHANGELOG.md and each port's API reference.

Benchmarks

Measured against 21 frameworks on a zero-cost mock model, per language. Honest summary: lowest per-request overhead over MCP in Python, JavaScript, C# and Rust, level with Eino in Go, and on the JVM 5% behind LangChain4j in the five-round table but ahead of it (1.63 vs 1.84 ms p50) in a separate 7-round sitting after the in-house Java stdio MCP client (#204). Every row, loss included: Nov 2026 standing.

What it is not

  • Not a graph orchestrator. No graph, builder or workflow DSL; compose agents as tools.
  • Not a hosted platform. A library you embed; nothing to sign up for.
  • Not a RAG / vector store. That is the sister project citenexus (S3-first, with pgvector support).

The eight ports

languagepackagedocs
JavaScript / TypeScripttoolnexusjs/ · API
Pythontoolnexuspython/ · API
Gogithub.com/muthuishere/toolnexus/golanggolang/ · API
Javaio.github.muthuishere:toolnexusjava/ · API
C# / .NETToolnexuscsharp/ · API
Elixirtoolnexuselixir/ · API
Clojurenet.clojars.muthuishere/toolnexusclojure/ · API
Rusttoolnexusrust/ · API

Built on toolnexus

  • wfnexus: typed pipelines for coding agents. Each step is a whole agent with scoped tools, a budget, guardrails and a JSON-schema output.

Built something on toolnexus? Open a PR adding one line here.

Docs and contract

Community

Join the AgentNexus Discord.

License

MIT — see LICENSE.

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close