3.0.0
fastmcp list and fastmcp call let you poke at a server interactively, but they’re developer tools — you always have to spell out the server spec, the tool name, and the arguments. fastmcp generate-cli takes the next step: it connects to a server, reads its schemas, and writes a standalone Python script where every tool is a proper subcommand with typed flags, help text, and tab completion. The result is a CLI that feels like it was hand-written for that specific server.
The key insight is that MCP tool schemas already contain everything a CLI framework needs: parameter names, types, descriptions, required/optional status, and defaults. generate-cli maps that schema into cyclopts commands, so JSON Schema types become Python type annotations, descriptions become --help text, and required parameters become mandatory flags.
Generating a Script
Point the command at any server spec — URLs, Python files, discovered server names, MCPConfig JSON — and it writes a CLI script:cli.py. If the file already exists, the command refuses to overwrite unless you pass -f:
fastmcp discover to see what’s available.
--timeout and --auth flags work the same way they do in fastmcp list and fastmcp call.
What You Get
The generated script is a regular Python file — executable, editable, and yours. Here’s what it looks like in practice:call-tool subcommand is where the generated code lives. Each tool on the server becomes its own command:
call-tool get_forecast matches what the server expects.
How It Works
The generated script is a client, not a server. It doesn’t bundle or embed the MCP server — it connects to it on every invocation. For URL-based servers, the server needs to be running. For stdio-based servers, the command specified inCLIENT_SPEC must be available on the system’s PATH.
At the top of the generated file, a CLIENT_SPEC variable holds the resolved transport: either a URL string or a StdioTransport with the command and arguments baked in. Every invocation connects through this spec, so the script works without any external configuration.
Parameter Handling
Parameters are mapped intelligently based on their complexity: Simple types (string, integer, number, boolean) become typed Python parameters with clean flags:
array with string/integer/number/boolean items) become list[T] parameters that accept multiple flags:
--help displays the full JSON schema so you know exactly what structure to pass:
None. Empty values are filtered out before calling the server.
Beyond tool commands, the script includes generic commands that work regardless of what the server exposes: list-tools, list-resources, read-resource, list-prompts, and get-prompt. These connect to the server at runtime, so they always reflect the server’s current state even if the tools have changed since generation.
Editing the Output
The most common edit is changingCLIENT_SPEC. If you generated from a local dev server and want to point at production, just change the string. If you generated from a discovered name and want to pin the transport, replace it with an explicit URL or StdioTransport.
Beyond that, it’s a regular Python file. You can add commands, change the output formatting, integrate it into a larger application, or strip out the parts you don’t need. The helper functions (_call_tool, _print_tool_result) are thin wrappers around fastmcp.Client that are easy to adapt.
The generated script requires fastmcp as a dependency. If the script lives outside a project that already has fastmcp installed, uv run is the easiest way to run it without permanent installation:

