cli-mcp examples/dual-mode

NAME

dual-mode - demo CLI that is also an MCP server

SYNOPSIS

dual-mode

DESCRIPTION

dual-mode is cli-mcp's headline shape: one binary that is a normal CLI by default and an MCP server when invoked as dual-mode mcp serve or dual-mode mcp serve-http. The same urfave tree powers all three usage forms:

1. Plain CLI - humans run subcommands directly:
   ./dual-mode hello world
   # hello, world

2. MCP server (stdio) - agents spawn the binary and exchange
   JSON-RPC on its pipes:
   ./dual-mode mcp serve

3. MCP server (Streamable HTTP) - agents POST JSON-RPC:
   ./dual-mode mcp serve-http --addr 127.0.0.1:8080

The mcp subcommand group is auto-excluded from the MCP tool surface. Calling the MCP server does not expose tools named mcp_serve and mcp_serve_http; that would let a tool call recurse into starting another server. mcp only appears in the CLI surface and in this rendered help.

Operating model for an agent integrating with a dual-mode binary:

- Prefer the stdio transport for editor-spawned integrations.
  Lower overhead, no port management, no auth surface.
- Use HTTP when the binary runs as a persistent service that
  multiple agents reach concurrently or across hosts.
- The exit code on Action error propagates through both
  transports. An agent calling the MCP tool sees isError=true
  and the error string; a human running the CLI sees the
  stderr message and a nonzero exit.
- The single binary means CI runs `dual-mode hello world` to
  smoke-test the same code path the agent will hit at runtime.
  One thing to test, two ways to invoke it.

Usage:

dual-mode [GLOBAL OPTIONS] [command [COMMAND OPTIONS]] [ARGUMENTS...]

COMMANDS

hello

print a greeting

--lang="": language: en or es (default: "en")

--loud: shout the greeting

mcp

MCP server transports

serve

run as MCP server over stdio

serve-http

run as MCP server over Streamable HTTP

--addr="": listen address ($ADDR env overrides) (default: "127.0.0.1:8080")

--landing="": text body for GET /

--no-health: disable the /healthz endpoint