Skip to main content
Any Framework

An MCP server that catalogs the command-line tools available on the current machine (availability, shadowing, version, capabilities) and suggests how to install missing ones.

Published
Jul 15, 2026
3mo ago
Total Downloads
278
278

Install

dotnet add package CliCatalog.Mcp --version 0.1.0

No framework information available.

README

CLI Catalog MCP Server

An MCP server that catalogs the command-line tools available on the current machine — what exists, where it lives, which copy actually runs, its version/identity, and (on demand) what it can do — and, when a tool is missing, how to install it.

It exposes a single, self-describing tool, get_clis, designed to be cheap enough to keep in an agent's context on every turn.

What it's good for

  • Stop guessing whether a CLI exists. Before an agent runs rg, docker, gh, jq, kubectl, … it can check availability instantly instead of failing on a missing command.
  • Explain shadowing. When the same command lives in several PATH directories, it reports the winner and the shadowed copies — the answer to "why am I getting the wrong python?".
  • Capability discovery. Ask by intent ("json diff", "container runtime") and get a ranked shortlist. When the client supports MCP Sampling, results are ranked semantically by the client's model.
  • Install suggestions. A miss returns typo corrections ("did you mean rg?") and per-manager install commands (winget / scoop / brew / apt) — as advisory text only.
  • Onboarding / environment diagnostics. A fast, structured inventory of a dev box, CI runner, or container.

How it works

Discovery is tiered so callers pay only for the depth they need:

Depth Answers Cost
existence (L1, default) name, absolute path, kind, PATH shadowing instant, no execution
identity (L2) version, file hash, architecture moderate; non-executing sources first
capability (L3) description, subcommands, flags opt-in; --help probing only with allowExec

Safe by default: L1 never executes anything; L2 prefers non-executing sources (Windows PE version resource, file metadata); L3 execution is opt-in, time-boxed, and sandboxed-in-intent (closed stdin, disabled pager, hard timeout, output cap). The server never installs or modifies anything.

Requirements

Build & run

dotnet build list-cli-mcp.slnx -c Release
dotnet run --project src/CliCatalog.Mcp        # starts the stdio server (waits for an MCP client)

Run as a .NET tool (dnx / global install)

The host is published to NuGet.org as a .NET tool (command name cli-catalog-mcp, package id CliCatalog.Mcp), so it can be run without a persistent install via dnx (the .NET 10 one-off tool runner, similar to npx). It is downloaded and cached on first use:

dnx CliCatalog.Mcp --yes           # latest published version
dnx [email protected] --yes     # or pin a specific version

Or install it once and get a cli-catalog-mcp command on your PATH:

dotnet tool install -g CliCatalog.Mcp             # from NuGet.org
cli-catalog-mcp                                    # starts the stdio server

Use it from an MCP client (e.g. VS Code / Copilot)

Point your client at the server over stdio. The smallest config uses dnx, which downloads and runs the published package on demand — no install step. --yes skips the download confirmation prompt (required because the client runs the server non-interactively):

// .vscode/mcp.json
{
  "servers": {
    "cli-catalog": {
      "type": "stdio",
      "command": "dnx",
      "args": ["CliCatalog.Mcp", "--yes"]
    }
  }
}

If you installed it globally (dotnet tool install -g CliCatalog.Mcp), point at the command directly:

{
  "servers": {
    "cli-catalog": {
      "type": "stdio",
      "command": "cli-catalog-mcp"
    }
  }
}

For local development against a source checkout, run it via dotnet run:

{
  "servers": {
    "cli-catalog": {
      "type": "stdio",
      "command": "dotnet",
      "args": ["run", "--project", "src/CliCatalog.Mcp", "-c", "Release"]
    }
  }
}

The get_clis tool

All parameters are optional; the mode is chosen by which you pass:

Param Type Default Purpose
name string | string[] — Check/inspect specific command(s); a miss adds corrections + install options.
query string — Discover tools by capability; returns a ranked shortlist.
depth existence | identity | capability existence How much detail to return.
scope installed | installable | both installed Search installed tools and/or known catalogs.
cursor string — Opaque pagination token from a previous nextCursor.
allowExec bool false Permit --help/--version probing when no non-executing source exists.

Behavior by input:

  • no arguments → list installed commands (paginated).
  • name → resolve the winner + full shadowing chain + details at depth; a miss returns did-you-mean + install options.
  • query → ranked shortlist (semantic when Sampling is available, otherwise lexical full-text).

Example — a miss with correction + install options:

{
  "results": [{
    "name": "ripgrepp", "status": "not-found",
    "didYouMean": [{ "name": "rg", "package": "ripgrep", "distance": 1 }],
    "install": [{ "manager": "winget", "id": "BurntSushi.ripgrep.MSVC", "command": "winget install BurntSushi.ripgrep.MSVC" }]
  }],
  "hints": ["Pass scope=installable to search tools you could install."]
}

Results are structured JSON only, and every capability/identity field is tagged with its source (and confidence where applicable) so agents know how a value was derived.

Configuration (environment variables)

Operator-facing, read at startup:

Variable Meaning
CLICATALOG_INCLUDE_PATHS Explicit PATH-separated dirs to scan (skips the process PATH unless combined with the next).
CLICATALOG_ALSO_SCAN_PROCESS_PATH 1/true to also scan the process PATH alongside includes.
CLICATALOG_EXCLUDE_PATHS PATH-separated dirs to skip.
CLICATALOG_EXECUTION_POLICY never | on-demand (default) | allowlist.
CLICATALOG_EXEC_ALLOWLIST / CLICATALOG_EXEC_DENYLIST Comma-separated command names for allowlist policy.
CLICATALOG_PAGE_SIZE Page size for the no-arg list.
CLICATALOG_CACHE_PATH SQLite cache path, or memory for an in-memory cache. Defaults to a per-user cache dir.

Project layout

src/CliCatalog.Core   # scanning, cache (SQLite + FTS5), change detection, enrichment, sampling — no MCP dep
src/CliCatalog.Mcp    # stdio host: the get_clis tool, resources, list_changed notifier
tests/                # unit, exec-hazard/security, and stdio end-to-end tests
docs/                 # design & implementation plan

See docs/design-and-implementation-plan.md for the full design, rationale, and roadmap.

Adoption Assessment

Assess this package against its supported frameworks, license, maintenance signals and dependency graph before making it a project standard.

No SPDX license expression is published. Review the license text and your organisation's policy before redistribution.No target framework metadata is available. Confirm compatibility in a representative project before standardising on this package.

Related Guides & Workflows

Learn how to evaluate, integrate, or audit this package in your .NET project.