Skip to content

McpSource.ListMcpToolsAsync

C# · package Toolnexus · SPEC §2 · McpSource.cs

public static Task<McpSource.McpInventory> ListMcpToolsAsync(object input, CancellationToken cancellationToken = default)

Connects to every enabled server, lists its tool definitions, and disconnects before returning — no toolkit, no ExecuteAsync wiring, nothing left running. The result is a plain McpInventory { Tools, Status }:

  • Toolsserver → IReadOnlyList<ToolInfo>, each ToolInfo(Name, Description, InputSchema) using the original, unprefixed tool name (not the server_tool name a connected McpSource would expose).
  • Statusserver → "connected" | "disabled" | "failed", same vocabulary as LoadAsync.

The returned inventory is unfiltered by any per-server tools allowlist — it exists to author or validate that allowlist, so it needs to see everything a server offers.

Building a config UI or a CLI that shows “here’s what mcp.json would give you” without paying for a live toolkit. Also the right call for authoring a per-server tools allowlist: list first, see the real names, then write the allowlist against them.

1. A disabled server never connects, and reports no tools

Section titled “1. A disabled server never connects, and reports no tools”
using Toolnexus;
var config = new Dictionary<string, object?>
{
["mcpServers"] = new Dictionary<string, object?>
{
["docs_demo"] = new Dictionary<string, object?>
{
["type"] = "local",
["command"] = new[] { "echo", "hi" },
["enabled"] = false,
},
},
};
var inventory = await McpSource.ListMcpToolsAsync(config);
if (inventory.Status["docs_demo"] != "disabled") throw new Exception(inventory.Status["docs_demo"]);
if (inventory.Tools.ContainsKey("docs_demo")) throw new Exception("a disabled server has no tool list");
Console.WriteLine($"ok: {inventory.Status["docs_demo"]}");

2. A server that can’t spawn is “failed”, not fatal

Section titled “2. A server that can’t spawn is “failed”, not fatal”
using Toolnexus;
var config = new Dictionary<string, object?>
{
["mcpServers"] = new Dictionary<string, object?>
{
["broken"] = new Dictionary<string, object?>
{
["type"] = "local",
["command"] = new[] { "toolnexus-docs-nonexistent-binary-xyz" },
["timeout"] = 2_000,
},
},
};
var inventory = await McpSource.ListMcpToolsAsync(config);
if (inventory.Status["broken"] != "failed") throw new Exception(inventory.Status["broken"]);
if (inventory.Tools.ContainsKey("broken")) throw new Exception("a failed server has no tool list");
Console.WriteLine($"ok: {inventory.Status["broken"]}");

3. Inventory the shared fixture, gated for a hermetic run

Section titled “3. Inventory the shared fixture, gated for a hermetic run”
using Toolnexus;
var repo = Environment.GetEnvironmentVariable("TOOLNEXUS_REPO") ?? ".";
var fixture = Path.Combine(repo, "examples", "mcp.json");
// Parse the real fixture, then gate every server off so this doc example never dials out —
// the shape (parse -> gate -> inventory) is what an "author the allowlist" tool would run.
var config = McpSource.ParseConfig(fixture);
foreach (var (_, value) in config)
((IDictionary<string, object?>)value!)["enabled"] = false;
var inventory = await McpSource.ListMcpToolsAsync(config);
if (inventory.Status.Values.Any(s => s != "disabled"))
throw new Exception($"unexpected: {string.Join(",", inventory.Status.Values)}");
if (inventory.Tools.Count != 0) throw new Exception("no server connected, so no tool lists");
Console.WriteLine($"ok: {string.Join(", ", inventory.Status.Keys.OrderBy(k => k))} all disabled");
Field Type What it is
McpInventory.Tools IReadOnlyDictionary<string, IReadOnlyList<ToolInfo>> Per-server tool defs, unfiltered by any allowlist.
McpInventory.Status IReadOnlyDictionary<string, string> server → "connected" | "disabled" | "failed".
ToolInfo.Name string The original, unprefixed MCP tool name.
ToolInfo.Description string
ToolInfo.InputSchema IDictionary<string, object?> The built JSON-Schema object (same shape LoadAsync uses).
  • McpSource.LoadAsync — Read an mcp.json, connect every local stdio and remote streamable-HTTP server, expose each server tool as a Tool.
  • McpSource.LoadAsync — The ctx-aware load: bound connection time and cancel a slow or hung server without leaking a child process.
  • McpSource.ParseConfig — Parse and validate config without connecting — the fast fail for a malformed or misspelled server block.
  • McpSource.ElicitationToRequest — Map an MCP server’s elicitation request onto the §10 suspension contract, and map the answer back.