11"""FastMCP run command implementation with enhanced type hints."""
22
33import json
4- import os
54import re
6- import subprocess
75import sys
86from pathlib import Path
97from typing import Any , Literal
1513from fastmcp .utilities .mcp_server_config import (
1614 MCPServerConfig ,
1715)
18- from fastmcp .utilities .mcp_server_config .v1 .environments .uv import UVEnvironment
1916from fastmcp .utilities .mcp_server_config .v1 .sources .filesystem import FileSystemSource
2017
2118logger = get_logger ("cli.run" )
@@ -31,86 +28,6 @@ def is_url(path: str) -> bool:
3128 return bool (url_pattern .match (path ))
3229
3330
34- def run_with_uv (
35- server_spec : str ,
36- python_version : str | None = None ,
37- with_packages : list [str ] | None = None ,
38- with_requirements : Path | None = None ,
39- project : Path | None = None ,
40- transport : TransportType | None = None ,
41- host : str | None = None ,
42- port : int | None = None ,
43- path : str | None = None ,
44- log_level : LogLevelType | None = None ,
45- show_banner : bool = True ,
46- editable : str | list [str ] | None = None ,
47- ) -> None :
48- """Run a MCP server using uv run subprocess.
49-
50- This function is called when we need to set up a Python environment with specific
51- dependencies before running the server. The config parsing and merging should already
52- be done by the caller.
53-
54- Args:
55- server_spec: Python file, object specification (file:obj), config file, or URL
56- python_version: Python version to use (e.g. "3.10")
57- with_packages: Additional packages to install
58- with_requirements: Requirements file to use
59- project: Run the command within the given project directory
60- transport: Transport protocol to use
61- host: Host to bind to when using http transport
62- port: Port to bind to when using http transport
63- path: Path to bind to when using http transport
64- log_level: Log level
65- show_banner: Whether to show the server banner
66- editable: Editable package paths
67- """
68-
69- env_config = UVEnvironment (
70- python = python_version ,
71- dependencies = with_packages if with_packages else None ,
72- requirements = str (with_requirements .resolve ()) if with_requirements else None ,
73- project = str (project .resolve ()) if project else None ,
74- editable = editable
75- if isinstance (editable , list )
76- else ([editable ] if editable else None ),
77- )
78-
79- # Build the inner fastmcp command (environment variable prevents infinite recursion)
80- inner_cmd = ["fastmcp" , "run" , server_spec ]
81-
82- # Add transport options to the inner command
83- if transport :
84- inner_cmd .extend (["--transport" , transport ])
85- # Only add HTTP-specific options for non-stdio transports
86- if transport != "stdio" :
87- if host :
88- inner_cmd .extend (["--host" , host ])
89- if port :
90- inner_cmd .extend (["--port" , str (port )])
91- if path :
92- inner_cmd .extend (["--path" , path ])
93- if log_level :
94- inner_cmd .extend (["--log-level" , log_level ])
95- if not show_banner :
96- inner_cmd .append ("--no-banner" )
97-
98- # Build the full uv command
99- cmd = env_config .build_command (inner_cmd )
100-
101- # Set marker to prevent infinite loops when subprocess calls FastMCP again
102- env = os .environ | {"FASTMCP_UV_SPAWNED" : "1" }
103-
104- # Run the command
105- logger .debug (f"Running command: { ' ' .join (cmd )} " )
106- try :
107- process = subprocess .run (cmd , check = True , env = env )
108- sys .exit (process .returncode )
109- except subprocess .CalledProcessError as e :
110- logger .error (f"Failed to run server: { e } " )
111- sys .exit (e .returncode )
112-
113-
11431def create_client_server (url : str ) -> Any :
11532 """Create a FastMCP server from a client URL.
11633
0 commit comments