mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-09 15:19:10 +02:00
Align CLI, deployment, and config docs (#4259)
* docs: align CLI and deployment docs Generated with Codex. * docs: restore install config support, fix CIMD placeholder, add missing CLI flags * docs: restore contrib guidance, correct --copy availability * docs: remove dead redirect-shadowed pages * Fix stale --path default in run command help * docs: correct Goose flag support, fix README link to moved testing page --------- Co-authored-by: Jeremiah Lowin <153965+jlowin@users.noreply.github.com>
This commit is contained in:
parent
d3b7922615
commit
149a7aa2ce
18 changed files with 85 additions and 1334 deletions
|
|
@ -1,161 +0,0 @@
|
|||
---
|
||||
title: Client CLI
|
||||
sidebarTitle: CLI
|
||||
description: Query and invoke MCP server tools directly from the terminal with fastmcp list and fastmcp call.
|
||||
icon: terminal
|
||||
---
|
||||
|
||||
import { VersionBadge } from '/snippets/version-badge.mdx'
|
||||
|
||||
<VersionBadge version="3.0.0" />
|
||||
|
||||
MCP servers are designed for programmatic consumption by AI assistants and applications. But during development, you often want to poke at a server directly: check what tools it exposes, call one with test arguments, or verify that a deployment is responding correctly. The FastMCP CLI gives you that direct access with two commands, `fastmcp list` and `fastmcp call`, so you can query and invoke any MCP server without writing a single line of Python.
|
||||
|
||||
These commands are also valuable for LLM-based agents that lack native MCP support. An agent that can execute shell commands can use `fastmcp list --json` to discover available tools and `fastmcp call --json` to invoke them, with structured JSON output designed for programmatic consumption.
|
||||
|
||||
## Server Targets
|
||||
|
||||
Both commands need to know which server to talk to. You provide a "server spec" as the first argument, and FastMCP figures out the transport automatically. You can point at an HTTP URL for a running server, a Python file that defines one, a JSON configuration file that describes one, or a JavaScript file. The CLI resolves the right connection mechanism so you can focus on the query.
|
||||
|
||||
```bash
|
||||
fastmcp list http://localhost:8000/mcp
|
||||
fastmcp list server.py
|
||||
fastmcp list mcp-config.json
|
||||
```
|
||||
|
||||
Python files are handled with particular care. Rather than requiring your script to call `mcp.run()` at the bottom, the CLI routes it through `fastmcp run` internally, which means any Python file that defines a FastMCP server object works as a target with no boilerplate.
|
||||
|
||||
For servers that communicate over stdio (common with Node.js-based MCP servers), use the `--command` flag instead of a positional server spec. The string is shell-split into a command and arguments.
|
||||
|
||||
```bash
|
||||
fastmcp list --command 'npx -y @modelcontextprotocol/server-github'
|
||||
```
|
||||
|
||||
### Name-Based Resolution
|
||||
|
||||
If your MCP servers are already configured in an editor or tool, you can refer to them by name instead of spelling out URLs or file paths. The CLI scans config files from Claude Desktop, Claude Code, Cursor, Gemini CLI, and Goose, and matches the name you provide.
|
||||
|
||||
```bash
|
||||
fastmcp list weather
|
||||
fastmcp call weather get_forecast city=London
|
||||
```
|
||||
|
||||
You can also use the `source:name` form to target a specific source directly, which is useful when the same server name appears in multiple configs or when you want to be explicit about which config you mean.
|
||||
|
||||
```bash
|
||||
fastmcp list claude-code:my-server
|
||||
fastmcp call cursor:weather get_forecast city=London
|
||||
```
|
||||
|
||||
The available source names are `claude-desktop`, `claude-code`, `cursor`, `gemini`, `goose`, and `project` (for `./mcp.json`). Run `fastmcp discover` to see what's available.
|
||||
|
||||
## Discovering Configured Servers
|
||||
|
||||
`fastmcp discover` scans your local editor and project configurations for MCP server definitions. It checks Claude Desktop, Claude Code (`~/.claude.json`), Cursor workspace configs (walking up from the current directory), Gemini CLI (`~/.gemini/settings.json`), Goose (`~/.config/goose/config.yaml`), and `mcp.json` in the current directory.
|
||||
|
||||
```bash
|
||||
fastmcp discover
|
||||
```
|
||||
|
||||
The output groups servers by source, showing each server's name and transport. Use `--source` to filter to specific sources, and `--json` for machine-readable output.
|
||||
|
||||
```bash
|
||||
fastmcp discover --source claude-code
|
||||
fastmcp discover --source cursor --source gemini --json
|
||||
```
|
||||
|
||||
Any server that appears here can be used by name (or `source:name`) with `fastmcp list` and `fastmcp call`, which means you can go from "I have a server configured in Claude Code" to querying it without copying any URLs or paths.
|
||||
|
||||
## Discovering Tools
|
||||
|
||||
`fastmcp list` connects to a server and prints every tool it exposes. The default output is compact: each tool appears as a function signature with its parameter names, types, and a description.
|
||||
|
||||
```bash
|
||||
fastmcp list http://localhost:8000/mcp
|
||||
```
|
||||
|
||||
The output looks like a Python function signature, making it easy to see at a glance what a tool expects and what it returns. Required parameters appear with just their type annotation, while optional ones show their defaults.
|
||||
|
||||
When you need the full JSON Schema for a tool's inputs or outputs -- useful for understanding nested object structures or enum constraints -- opt into them with `--input-schema` or `--output-schema`. These print the raw schema beneath each tool signature.
|
||||
|
||||
### Beyond Tools
|
||||
|
||||
MCP servers can expose resources and prompts alongside tools. By default, `fastmcp list` only shows tools because they are the most common interaction point. Add `--resources` or `--prompts` to include those in the output.
|
||||
|
||||
```bash
|
||||
fastmcp list server.py --resources --prompts
|
||||
```
|
||||
|
||||
Resources appear with their URIs and descriptions. Prompts appear with their argument names so you can see what parameters they accept.
|
||||
|
||||
### Machine-Readable Output
|
||||
|
||||
The `--json` flag switches from human-friendly text to structured JSON. Each tool includes its name, description, and full input schema (and output schema when present). When combined with `--resources` or `--prompts`, those are included as additional top-level keys.
|
||||
|
||||
```bash
|
||||
fastmcp list server.py --json
|
||||
```
|
||||
|
||||
This is the format to use when building automation around MCP servers or feeding tool definitions to an LLM agent that needs to decide which tool to call.
|
||||
|
||||
## Calling Tools
|
||||
|
||||
`fastmcp call` invokes a single tool on a server. You provide the server spec, the tool name, and arguments as `key=value` pairs. The CLI fetches the tool's schema, coerces your string values to the correct types (integers, floats, booleans, arrays, objects), and makes the call.
|
||||
|
||||
```bash
|
||||
fastmcp call http://localhost:8000/mcp search query=hello limit=5
|
||||
```
|
||||
|
||||
Type coercion is driven by the tool's JSON Schema. If a parameter is declared as an integer, the string `"5"` becomes the integer `5`. Booleans accept `true`/`false`, `yes`/`no`, and `1`/`0`. Array and object parameters are parsed as JSON.
|
||||
|
||||
For tools with complex or deeply nested arguments, the `key=value` syntax gets unwieldy. You can pass a single JSON object as the argument instead, and the CLI treats it as the full input dictionary.
|
||||
|
||||
```bash
|
||||
fastmcp call server.py create_item '{"name": "Widget", "tags": ["sale", "new"], "metadata": {"color": "blue"}}'
|
||||
```
|
||||
|
||||
Alternatively, `--input-json` provides the base argument dictionary. Any `key=value` pairs you add alongside it override keys from the JSON, which is useful for templating a complex call and varying one parameter at a time.
|
||||
|
||||
### Error Handling
|
||||
|
||||
The CLI validates your call before sending it. If you misspell a tool name, it uses fuzzy matching to suggest corrections. If you omit a required argument, it tells you which ones are missing and prints the tool's signature as a reminder.
|
||||
|
||||
When a tool call itself returns an error (the server executed the tool but it failed), the error message is printed and the CLI exits with a non-zero status code, making it straightforward to use in scripts.
|
||||
|
||||
### Structured Output
|
||||
|
||||
Like `fastmcp list`, the `--json` flag on `fastmcp call` emits structured JSON instead of formatted text. The output includes the content blocks, error status, and structured content when the server provides it. Use this when you need to parse tool results programmatically.
|
||||
|
||||
```bash
|
||||
fastmcp call server.py get_weather city=London --json
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
When the server target is an HTTP URL, the CLI automatically enables OAuth authentication. If the server requires it, you will be guided through the OAuth flow (typically opening a browser for authorization). If the server has no auth requirements, the OAuth setup is a silent no-op.
|
||||
|
||||
To explicitly disable authentication -- for example, when connecting to a local development server where OAuth setup would just slow you down -- pass `--auth none`.
|
||||
|
||||
```bash
|
||||
fastmcp call http://localhost:8000/mcp my_tool --auth none
|
||||
```
|
||||
|
||||
## Transport Override
|
||||
|
||||
FastMCP defaults to Streamable HTTP for URL targets. If you are connecting to a server that only supports Server-Sent Events (SSE), use `--transport sse` to force the older transport. This appends `/sse` to the URL path automatically so the client picks the correct protocol.
|
||||
|
||||
```bash
|
||||
fastmcp list http://localhost:8000 --transport sse
|
||||
```
|
||||
|
||||
## Interactive Elicitation
|
||||
|
||||
Some MCP tools request additional input from the user during execution through a mechanism called elicitation. When a tool sends an elicitation request, the CLI prints the server's question to the terminal and prompts you to respond. Each field in the elicitation schema is presented with its name and expected type, and required fields are clearly marked.
|
||||
|
||||
You can type `decline` to skip a question or `cancel` to abort the tool call entirely. This interactive behavior means the CLI works naturally with tools that have multi-step or conversational workflows.
|
||||
|
||||
## LLM Agent Integration
|
||||
|
||||
For LLM agents that can execute shell commands but lack built-in MCP support, the CLI provides a clean integration path. The agent calls `fastmcp list --json` to get a structured description of every available tool, including full input schemas, and then calls `fastmcp call --json` with the chosen tool and arguments. Both commands return well-formed JSON that is straightforward to parse.
|
||||
|
||||
Because the CLI handles connection management, transport selection, and type coercion internally, the agent does not need to understand MCP protocol details. It just needs to read JSON and construct shell commands.
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
---
|
||||
title: Generate CLI
|
||||
sidebarTitle: Generate CLI
|
||||
description: Turn any MCP server into a standalone, typed command-line tool.
|
||||
icon: wand-magic-sparkles
|
||||
tag: NEW
|
||||
---
|
||||
|
||||
import { VersionBadge } from '/snippets/version-badge.mdx'
|
||||
|
||||
<VersionBadge version="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](https://cyclopts.readthedocs.io/) 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:
|
||||
|
||||
```bash
|
||||
fastmcp generate-cli weather
|
||||
fastmcp generate-cli http://localhost:8000/mcp
|
||||
fastmcp generate-cli server.py my_weather_cli.py
|
||||
```
|
||||
|
||||
The second positional argument sets the output path. When omitted, it defaults to `cli.py`. If either the CLI file or its companion `SKILL.md` already exists, the command refuses to overwrite unless you pass `-f`:
|
||||
|
||||
```bash
|
||||
fastmcp generate-cli weather -f
|
||||
fastmcp generate-cli weather my_cli.py -f
|
||||
```
|
||||
|
||||
Name-based resolution works here too, so if you have a server configured in Claude Desktop, Cursor, or any other supported editor, you can reference it by name. Run [`fastmcp discover`](/clients/cli#discovering-configured-servers) to see what's available.
|
||||
|
||||
```bash
|
||||
fastmcp generate-cli claude-code:my-server output.py
|
||||
```
|
||||
|
||||
The `--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:
|
||||
|
||||
```
|
||||
$ python cli.py --help
|
||||
Usage: weather-cli COMMAND
|
||||
|
||||
CLI for weather MCP server
|
||||
|
||||
Commands:
|
||||
call-tool Call a tool on the server
|
||||
list-tools List available tools.
|
||||
list-resources List available resources.
|
||||
read-resource Read a resource by URI.
|
||||
list-prompts List available prompts.
|
||||
get-prompt Get a prompt by name. Pass arguments as key=value pairs.
|
||||
```
|
||||
|
||||
The `call-tool` subcommand is where the generated code lives. Each tool on the server becomes its own command:
|
||||
|
||||
```
|
||||
$ python cli.py call-tool --help
|
||||
Usage: weather-cli call-tool COMMAND
|
||||
|
||||
Call a tool on the server
|
||||
|
||||
Commands:
|
||||
get_forecast Get the weather forecast for a city.
|
||||
search_city Search for a city by name.
|
||||
```
|
||||
|
||||
And each tool has typed parameters with help text pulled directly from the server's schema:
|
||||
|
||||
```
|
||||
$ python cli.py call-tool get_forecast --help
|
||||
Usage: weather-cli call-tool get_forecast [OPTIONS]
|
||||
|
||||
Get the weather forecast for a city.
|
||||
|
||||
Options:
|
||||
--city [str] City name (required)
|
||||
--days [int] Number of forecast days (default: 3)
|
||||
```
|
||||
|
||||
Tool names are preserved exactly as the server defines them — underscores stay as underscores, so `call-tool get_forecast` matches what the server expects.
|
||||
|
||||
## Agent Skill
|
||||
|
||||
Alongside the CLI script, `generate-cli` also writes a `SKILL.md` file — a [Claude Code agent skill](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/skills) that documents the generated CLI. The skill includes every tool's exact invocation syntax, parameter flags with types and descriptions, and the utility commands, so an agent can use the CLI immediately without running `--help` or experimenting with flag names.
|
||||
|
||||
The skill is written to the same directory as the CLI script. For a weather server, it looks something like:
|
||||
|
||||
````markdown
|
||||
---
|
||||
name: "weather-cli"
|
||||
description: "CLI for the weather MCP server. Call tools, list resources, and get prompts."
|
||||
---
|
||||
|
||||
# weather CLI
|
||||
|
||||
## Tool Commands
|
||||
|
||||
### get_forecast
|
||||
|
||||
Get the weather forecast for a city.
|
||||
|
||||
```bash
|
||||
uv run --with fastmcp python cli.py call-tool get_forecast --city <value> --days <value>
|
||||
```
|
||||
|
||||
| Flag | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `--city` | string | yes | City name |
|
||||
| `--days` | integer | no | Number of forecast days |
|
||||
````
|
||||
|
||||
To skip skill generation, pass `--no-skill`:
|
||||
|
||||
```bash
|
||||
fastmcp generate-cli weather --no-skill
|
||||
```
|
||||
|
||||
## 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 in `CLIENT_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:
|
||||
```bash
|
||||
python cli.py call-tool get_forecast --city London --days 3
|
||||
```
|
||||
|
||||
**Arrays of simple types** (`array` with `string`/`integer`/`number`/`boolean` items) become `list[T]` parameters that accept multiple flags:
|
||||
```bash
|
||||
python cli.py call-tool tag_items --tags python --tags fastapi --tags mcp
|
||||
```
|
||||
|
||||
**Complex types** (objects, nested arrays, or unions) accept JSON strings. The tool's `--help` displays the full JSON schema so you know exactly what structure to pass:
|
||||
```bash
|
||||
python cli.py call-tool create_user \
|
||||
--name John \
|
||||
--metadata '{"role": "admin", "dept": "engineering"}'
|
||||
```
|
||||
|
||||
Required parameters are mandatory flags; optional ones default to their schema default or `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 changing `CLIENT_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:
|
||||
|
||||
```bash
|
||||
uv run --with fastmcp python cli.py call-tool get_forecast --city London
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue