@prefecthq/fastmcp-ts gives you the fastmcp CLI as a self-contained binary. Every dependency is bundled, including the MCP SDK, so it runs wherever the package is installed with nothing else to install:
--quiet suppresses the human-readable output — tables, spinners, status lines — leaving only the data. --json switches that data to machine-readable JSON. Together they make the CLI scriptable, a property the rest of this page leans on.
Run a server
fastmcp run starts a server file as a real process, the way it would run in production. TypeScript files run through tsx with no build step, so this is the command for serving a file locally or in a container.
--reload during development: it watches the file and respawns the server on every change, so edits take effect without a manual restart. --transport, --host, --port, and --path set the same MCP_TRANSPORT/MCP_HOST/MCP_PORT/MCP_PATH environment variables server.run() already reads, so they’re interchangeable with exporting those variables directly — useful when a deployment platform wants to pass configuration as flags.
Entrypoint exports
Every example so far runs a file that starts itself —server.ts ends in a top-level await server.run(), the way the running your server guide teaches it. Point the CLI at a file that only exports a server instead, and it starts the server for you: fastmcp run server.ts:app imports server.ts, resolves the export named app, and calls .run() on it. This is the shape a platform wants when it deploys your server — it can bind the transport and port through MCP_TRANSPORT and MCP_PORT without your file needing to know it’s being deployed at all.
Drop the :app and the CLI looks for a default, mcp, server, or app export, in that order, so a plain export const server = new FastMCP(...) is found with no export name given at all. This is the same convention Python FastMCP uses, which keeps a project’s entrypoint recognizable regardless of which language wrote it.
FastMCP server when called. Reach for this when building the server needs work that only makes sense at start time, like reading a config file or opening a database connection before registering tools. Factories are only resolved when you name the export explicitly, since calling an arbitrary exported function as a side effect of guessing a name would be surprising — auto-detection only ever matches an export that’s already a FastMCP instance.
server.ts
run, inspect --file, list --file, call --file, and dev inspector all resolve entrypoints the same way, so file:export works identically everywhere. inspect, list, and call also accept an explicit --export <name> flag, which takes precedence over the colon syntax when both are given:
FastMCP server or a factory returning one, is a hard error naming the file and export so a typo is easy to spot. A file with no default/mcp/server/app export and no --export flag is assumed to be the self-running kind — the CLI imports it, lets its top-level code start the server, and does nothing further.
Inspect a server
fastmcp inspect lists a server’s tools, resources, and prompts and renders them as tables. Point it at a file to start the server in-process and inspect it, or at a running URL to inspect a live server. This is the command for a quick read of what a server exposes — the fastest way to confirm a registration landed or remember a tool’s arguments.
fastmcp list covers the same ground for a server already running, connecting over a URL or a --command. Use inspect --file when you have the source and want it spun up for you; use list when the server is already up and you are talking to it over the wire. When you pass --command, give the binary and its arguments separately rather than one string — --command npx --args tsx,server.ts, not a single "npx tsx server.ts" — so the binary resolves correctly.
Call tools and read resources
fastmcp call invokes a tool by name or reads a resource by URI. Arguments are key=value pairs, and values that parse as JSON are passed as their parsed type rather than strings:
--input-json with a JSON object instead of key=value pairs — it is unambiguous where positional parsing is fragile. When a tool name doesn’t match, the CLI suggests the closest registered name by fuzzy match, so a typo points you at what you meant.
Protocol era
inspect, list, and call connect to a server as a client, so they choose a protocol era the way the library client does. Each picks a default per transport: an HTTP URL negotiates automatically — it uses the modern (2026-07-28) era when the server supports it and falls back to legacy — while a stdio or in-process server the CLI spawns stays legacy. Two flags override the default. --modern opts a stdio or in-process connection into the same automatic negotiation. --pin <revision> requires one exact revision on any transport; it is the stronger request, so it wins even alongside --modern.
--file server is spawned as a subprocess and connected over real stdio, so --modern reaches the modern era through it. This differs from the library’s in-process transport, where an in-memory FastMCP connection stays legacy under 'auto' and needs a pinned era to go modern.
run takes no era flag. It starts a server, and a fastmcp server serves both eras at once with no configuration.
When a --pin revision the server cannot speak reaches the wire, the CLI maps the -32022 UnsupportedProtocolVersion protocol error to a plain-English message: it names the versions the server does support and tells you to change or drop --pin. Two neighboring modern-era protocol errors get the same treatment: -32021 when the server needs a client capability this CLI did not declare, and -32020 when a request’s protocol-version header does not match its body.
Dev inspector
fastmcp dev inspector opens the MCP Inspector — a browser UI for poking at a server interactively — against a server file, with file-watch reload. Use it when you want to explore a server by hand: call tools through a form, read resources, watch notifications. It is the interactive counterpart to inspect, which prints a static snapshot to the terminal.
fastmcp inspect --file server.ts --modern instead.
Install into editors and clients
fastmcp install writes a server into a client’s MCP configuration so that editor or app launches it automatically. This is how you hand a finished server to the tools that consume it — Claude Code, Claude Desktop, Cursor, Gemini, Goose, or a project-local mcp.json.
--args (comma-separated) and --env (comma-separated KEY=VALUE) to configure the entry that gets written. When a target already has an entry for the server, the CLI confirms before overwriting it.
Discover configured servers
fastmcp discover scans every known client configuration on the machine and lists the MCP servers already configured across all of them. Use it to see what a machine is set up to run before installing or to audit existing configuration.
Authentication
Commands that connect to a remote server accept--auth <token>, which is sent as a bearer token on the connection:
Pipelines and exit codes
The CLI keeps stdout reserved for machine-readable data and sends everything human-readable — tables, spinners, status messages — to stderr. That separation is what makes it composable: pipe the data intojq and the formatting never contaminates it.
0 on success, 1 for a user error, 2 for a connection failure, 3 for a server error.