Skip to main content
Installing @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:
Two global flags apply to every command. --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.
Reach for --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.
A named export can also be a factory — a function, sync or async, that takes no arguments and returns a 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:
An export name that doesn’t exist, or that resolves to something other than a 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:
For nested or complex inputs, pass --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.
A --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.
The Inspector speaks the legacy (2025) protocol era only. A fastmcp server pins its era per connection. It still serves the Inspector correctly. The Inspector cannot exercise 2026-07-28 (modern) era behavior. To check the modern era, run 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.
Pass --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 into jq and the formatting never contaminates it.
The exit code reports the outcome for scripts: 0 on success, 1 for a user error, 2 for a connection failure, 3 for a server error.