Chapter 1: Your Control Panel - The mcp
Command-Line Interface
Welcome to the MCP Python SDK! This is your starting point for building powerful, interactive AI tools.
Imagine you’ve just built an amazing new tool using the SDK – maybe a helpful assistant that can answer questions about your documents. How do you actually run this tool? How do you test it? How do you connect it to applications like Claude Desktop?
This is where the mcp
command-line interface (CLI) comes in. Think of it as your developer control panel or toolkit for managing your MCP creations right from your terminal (that black window where you type commands). It helps you run, test, and integrate your MCP servers.
In this chapter, we’ll explore the basic commands you’ll use most often. Our main goal is to learn how to take a simple server written in a Python file and get it running.
What is the mcp
Command?
The mcp
command is a tool you run in your terminal. After installing the MCP Python SDK
(specifically with the cli
extras, like pip install mcp[cli]
), you gain access to this command. It provides several sub-commands to help you manage your MCP development workflow.
Let’s look at the most important ones.
Checking Your Setup: mcp version
First things first, let’s make sure everything is installed correctly. You can check the installed version of the MCP SDK using this command:
mcp version
What happens?
This command looks up the installed mcp
package and prints its version number.
Example Output:
MCP version 0.1.0
If you see a version number, you’re good to go! If you get an error, double-check that you’ve installed the SDK correctly (pip install mcp[cli]
).
Running Your Server: mcp run
This is the command you’ll use to execute your MCP server directly. Let’s say you have a Python file named my_first_server.py
that contains your server code.
Minimal Server Example (my_first_server.py
):
# We'll learn about FastMCP in the next chapter!
# For now, just know this creates a basic server.
from mcp.server.fastmcp import FastMCP
# Create an instance of our server
server = FastMCP(name="MyFirstServer")
# This is a standard Python check to make sure
# the script is being run directly
if __name__ == "__main__":
# Tell the server to start running
print("Starting MyFirstServer...")
server.run()
print("MyFirstServer finished.") # You might not see this if the server runs forever
To run this server, you would open your terminal, navigate to the directory containing my_first_server.py
, and type:
mcp run my_first_server.py
What happens?
The mcp run
command will:
- Find your
my_first_server.py
file. - Look inside for a server object (it tries common names like
mcp
,server
, orapp
by default, or you can specify one likemy_first_server.py:server
). - Tell that server object to start running (by calling its
.run()
method).
Your terminal will likely show output like “Starting MyFirstServer…” and then wait for connections or instructions, depending on how the server is configured. To stop it, you usually press Ctrl+C
.
Developing and Inspecting: mcp dev
When you’re building your server, you often want to see what’s happening inside – what messages are being sent and received? The mcp dev
command is perfect for this. It runs your server and launches the MCP Inspector, a web-based tool that lets you monitor and debug your server in real-time.
mcp dev my_first_server.py
What happens?
- Similar to
mcp run
, it finds and prepares to run your server (my_first_server.py
). - It ensures any necessary helper tools (like the Inspector itself, using
npx
) are available. - It starts your server.
- It launches the MCP Inspector, which connects to your running server. You’ll usually see a URL in your terminal that you can open in your web browser, or sometimes the Inspector might open automatically.
This is incredibly useful during development for understanding the flow of information.
(Note: mcp dev
might require Node.js and npx to be installed on your system to run the Inspector tool.)
Integrating with Apps: mcp install
Once your server is working, you might want to use it from another application, like the Claude Desktop app. The mcp install
command helps you register your server with Claude so it appears in the app’s list of available tools.
mcp install my_first_server.py --name "My Awesome Tool"
What happens?
- It finds your
my_first_server.py
file. - It locates the configuration file for the Claude Desktop app on your computer.
- It adds an entry to that configuration file, telling Claude:
- The name you want to use (“My Awesome Tool”).
- How to run your server (using a command like
uv run --with mcp mcp run /path/to/your/my_first_server.py
).uv
is a fast tool used behind the scenes to manage the environment and dependencies needed to run your server. - Optionally, any extra Python packages your server needs (
--with some_package
) or environment variables (--env-var KEY=VALUE
).
Now, when you open Claude Desktop, “My Awesome Tool” should be available for use! This command essentially automates the process of telling Claude how to find and execute your custom server.
How Does mcp run
Work Under the Hood?
Let’s peek behind the curtain when you execute mcp run my_first_server.py
. It might seem like magic, but it’s a well-defined sequence of steps:
- You type the command: You enter
mcp run my_first_server.py
in your terminal. - OS Executes
mcp
: Your operating system finds the installedmcp
script (which is part of theMCP Python SDK
) and runs it using Python. Typer
Parses: Themcp
script uses a library calledTyper
to understand the command-line arguments. It seesrun
as the command andmy_first_server.py
as the argument.run
Function Called:Typer
directs the execution to therun
function defined inside the SDK’scli/cli.py
file.- Path Processing: The
run
function calls internal helpers (like_parse_file_path
) to find the full path tomy_first_server.py
and check if you specified a particular object within the file (e.g.,my_server.py:my_object
). - Server Import: It then uses another helper (
_import_server
) to dynamically load the Python code frommy_first_server.py
and find the actual server object (like theserver
variable we created). - Server Execution: Finally, it calls the
.run()
method on the imported server object. This is the signal for your server code to start doing its job – listening for connections, processing requests, etc. The specifics of.run()
depend on the server type, like the FastMCP Server (FastMCP
) we’ll see next.
Here’s a simplified diagram of that flow:
sequenceDiagram
participant User
participant Terminal
participant OS
participant MCP_CLI as mcp (cli/cli.py)
participant ServerCode as my_first_server.py
User->>Terminal: mcp run my_first_server.py
Terminal->>OS: Execute 'mcp' script
OS->>MCP_CLI: Start script with args ['run', 'my_first_server.py']
MCP_CLI->>MCP_CLI: Parse args (Typer finds 'run' command)
MCP_CLI->>MCP_CLI: _parse_file_path('my_first_server.py')
MCP_CLI->>MCP_CLI: _import_server(filepath, object_name)
MCP_CLI->>ServerCode: Import module & find 'server' object
ServerCode-->>MCP_CLI: Return server object
MCP_CLI->>ServerCode: server.run()
ServerCode->>ServerCode: Start listening/processing...
Diving into the Code (Briefly!)
You don’t need to memorize this, but seeing snippets can help understand the structure.
Inside cli/cli.py
(Simplified):
# Import the Typer library for creating CLIs
import typer
# Import helpers to find/load the server code
from .helpers import _parse_file_path, _import_server # Fictional helper import
# Create the main CLI application object
app = typer.Typer(name="mcp", help="MCP development tools")
# Decorator tells Typer this function handles the 'run' command
@app.command()
def run(
file_spec: str = typer.Argument(...), # Expects the file path argument
# ... other options like --transport ...
) -> None:
"""Run a MCP server."""
# 1. Find the file and specific server object (if any)
file_path, server_object_name = _parse_file_path(file_spec)
# 2. Load the code and get the server instance
server = _import_server(file_path, server_object_name)
# 3. Tell the server instance to start running
server.run() # Additional args like transport might be passed here
# ... other commands like dev, install, version defined similarly ...
# Standard Python entry point
if __name__ == "__main__":
app() # Start the Typer application
This shows how Typer
connects your command (mcp run
) to the run
function, which then orchestrates finding and starting your server code.
Inside cli/claude.py
(Simplified update_claude_config
):
import json
from pathlib import Path
# Helper to find where Claude stores its config
def get_claude_config_path() -> Path | None:
# ... platform specific logic to find the path ...
# Returns Path object like /Users/You/Library/Application Support/Claude
pass # Implementation details skipped
def update_claude_config(file_spec: str, server_name: str, ...) -> bool:
"""Add or update a FastMCP server in Claude's configuration."""
config_dir = get_claude_config_path()
if not config_dir:
print("Error: Claude config not found.")
return False
config_file = config_dir / "claude_desktop_config.json"
try:
# Read existing config or create an empty one
config = json.loads(config_file.read_text()) if config_file.exists() else {}
if "mcpServers" not in config:
config["mcpServers"] = {}
# Define how to run the server using 'uv' (a tool for running Python code)
# This builds the command: uv run --with mcp mcp run /path/to/server.py
run_command = ["uv", "run", "--with", "mcp", "mcp", "run", file_spec]
# ... logic to add --with-editable or --with packages ...
# Add the server entry to the config dictionary
config["mcpServers"][server_name] = {
"command": "uv",
"args": run_command[1:], # Arguments for the uv command
# ... potentially add 'env' dictionary here ...
}
# Write the updated configuration back to the file
config_file.write_text(json.dumps(config, indent=2))
print(f"Successfully installed {server_name} in Claude.")
return True
except Exception as e:
print(f"Error updating Claude config: {e}")
return False
This snippet shows the core logic of mcp install
: find the Claude config file, construct the command needed to run your server using uv
and mcp run
, and save this information into the JSON configuration file.
Conclusion
You’ve learned about the mcp
command-line interface – your essential toolkit for managing MCP servers. You now know how to:
- Check your installation with
mcp version
. - Run a server directly using
mcp run your_server.py
. - Run a server with a debugging inspector using
mcp dev your_server.py
. - Register your server with applications like Claude Desktop using
mcp install your_server.py
.
This command is your bridge between writing server code and actually using it.
In the next chapter, we’ll dive into the heart of many MCP servers: the FastMCP Server (FastMCP
), which is the kind of object the mcp
command typically runs.
Generated by AI Codebase Knowledge Builder