Compare commits

...

1 commit

Author SHA1 Message Date
Jeremiah Lowin
3d4a90538b Internal refactor: fastmcp config to mcp server config
To be clear this is about server deployments
2025-08-29 21:32:45 -04:00
50 changed files with 354 additions and 300 deletions

View file

@ -1,4 +1,4 @@
name: Update FastMCPConfig Schema name: Update MCPServerConfig Schema
# This workflow runs on merges to main to automatically update the config schema # This workflow runs on merges to main to automatically update the config schema
# by creating a PR when changes are needed. # by creating a PR when changes are needed.
@ -7,8 +7,8 @@ on:
push: push:
branches: ["main"] branches: ["main"]
paths: paths:
- "src/fastmcp/utilities/fastmcp_config/**" - "src/fastmcp/utilities/mcp_server_config/**"
- "!src/fastmcp/utilities/fastmcp_config/v1/schema.json" # Exclude the local schema file - "!src/fastmcp/utilities/mcp_server_config/v1/schema.json" # Exclude the local schema file
workflow_dispatch: workflow_dispatch:
permissions: permissions:
@ -45,23 +45,23 @@ jobs:
# Generate schema in docs/public for web access # Generate schema in docs/public for web access
uv run python -c " uv run python -c "
from fastmcp.utilities.fastmcp_config import generate_schema from fastmcp.utilities.mcp_server_config import generate_schema
generate_schema('docs/public/schemas/fastmcp.json/latest.json') generate_schema('docs/public/schemas/fastmcp.json/latest.json')
print('✅ Latest schema generated in docs/public') print('✅ Latest schema generated in docs/public')
" "
# Also update the v1 schema in docs/public # Also update the v1 schema in docs/public
uv run python -c " uv run python -c "
from fastmcp.utilities.fastmcp_config import generate_schema from fastmcp.utilities.mcp_server_config import generate_schema
generate_schema('docs/public/schemas/fastmcp.json/v1.json') generate_schema('docs/public/schemas/fastmcp.json/v1.json')
print('✅ v1 schema generated in docs/public') print('✅ v1 schema generated in docs/public')
" "
# Generate schema in the source directory for local development # Generate schema in the source directory for local development
uv run python -c " uv run python -c "
from fastmcp.utilities.fastmcp_config import generate_schema from fastmcp.utilities.mcp_server_config import generate_schema
generate_schema('src/fastmcp/utilities/fastmcp_config/v1/schema.json') generate_schema('src/fastmcp/utilities/mcp_server_config/v1/schema.json')
print('✅ Schema generated in utilities/fastmcp_config/v1/') print('✅ Schema generated in utilities/mcp_server_config/v1/')
" "
- name: Create Pull Request - name: Create Pull Request
@ -73,7 +73,7 @@ jobs:
body: | body: |
This PR updates the fastmcp.json schema files to match the current source code. This PR updates the fastmcp.json schema files to match the current source code.
The schema is automatically generated from `src/fastmcp/utilities/fastmcp_config/` to ensure consistency. The schema is automatically generated from `src/fastmcp/utilities/mcp_server_config/` to ensure consistency.
**Note:** This PR is fully automated and will update itself with any subsequent changes to the schema, or close automatically if the schema becomes up-to-date through other means. Feel free to leave it open until you're ready to merge. **Note:** This PR is fully automated and will update itself with any subsequent changes to the schema, or close automatically if the schema becomes up-to-date through other means. Feel free to leave it open until you're ready to merge.

View file

@ -380,33 +380,33 @@
"python-sdk/fastmcp-utilities-cli", "python-sdk/fastmcp-utilities-cli",
"python-sdk/fastmcp-utilities-components", "python-sdk/fastmcp-utilities-components",
"python-sdk/fastmcp-utilities-exceptions", "python-sdk/fastmcp-utilities-exceptions",
{
"group": "fastmcp_config",
"pages": [
"python-sdk/fastmcp-utilities-fastmcp_config-__init__",
{
"group": "v1",
"pages": [
"python-sdk/fastmcp-utilities-fastmcp_config-v1-__init__",
"python-sdk/fastmcp-utilities-fastmcp_config-v1-fastmcp_config",
{
"group": "sources",
"pages": [
"python-sdk/fastmcp-utilities-fastmcp_config-v1-sources-__init__",
"python-sdk/fastmcp-utilities-fastmcp_config-v1-sources-base",
"python-sdk/fastmcp-utilities-fastmcp_config-v1-sources-filesystem"
]
}
]
}
]
},
"python-sdk/fastmcp-utilities-http", "python-sdk/fastmcp-utilities-http",
"python-sdk/fastmcp-utilities-inspect", "python-sdk/fastmcp-utilities-inspect",
"python-sdk/fastmcp-utilities-json_schema", "python-sdk/fastmcp-utilities-json_schema",
"python-sdk/fastmcp-utilities-json_schema_type", "python-sdk/fastmcp-utilities-json_schema_type",
"python-sdk/fastmcp-utilities-logging", "python-sdk/fastmcp-utilities-logging",
"python-sdk/fastmcp-utilities-mcp_config", "python-sdk/fastmcp-utilities-mcp_config",
{
"group": "mcp_server_config",
"pages": [
"python-sdk/fastmcp-utilities-mcp_server_config-__init__",
{
"group": "v1",
"pages": [
"python-sdk/fastmcp-utilities-mcp_server_config-v1-__init__",
"python-sdk/fastmcp-utilities-mcp_server_config-v1-mcp_server_config",
{
"group": "sources",
"pages": [
"python-sdk/fastmcp-utilities-mcp_server_config-v1-sources-__init__",
"python-sdk/fastmcp-utilities-mcp_server_config-v1-sources-base",
"python-sdk/fastmcp-utilities-mcp_server_config-v1-sources-filesystem"
]
}
]
}
]
},
"python-sdk/fastmcp-utilities-openapi", "python-sdk/fastmcp-utilities-openapi",
"python-sdk/fastmcp-utilities-tests", "python-sdk/fastmcp-utilities-tests",
"python-sdk/fastmcp-utilities-types" "python-sdk/fastmcp-utilities-types"

View file

@ -10,7 +10,7 @@ FastMCP CLI tools using Cyclopts.
## Functions ## Functions
### `with_argv` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/cli.py#L70" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `with_argv` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/cli.py#L67" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
with_argv(args: list[str] | None) with_argv(args: list[str] | None)
@ -27,7 +27,7 @@ Args are provided without the script name, so we preserve sys.argv[0]
and replace the rest. and replace the rest.
### `version` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/cli.py#L93" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `version` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/cli.py#L90" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
version() version()
@ -37,7 +37,7 @@ version()
Display version information and platform details. Display version information and platform details.
### `dev` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/cli.py#L131" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `dev` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/cli.py#L128" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
dev(server_spec: str | None = None) -> None dev(server_spec: str | None = None) -> None
@ -50,7 +50,7 @@ Run an MCP server with the MCP Inspector for development.
- `server_spec`: Python file to run, optionally with \:object suffix, or None to auto-detect fastmcp.json - `server_spec`: Python file to run, optionally with \:object suffix, or None to auto-detect fastmcp.json
### `run` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/cli.py#L349" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `run` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/cli.py#L309" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
run(server_spec: str | None = None, *server_args: str) -> None run(server_spec: str | None = None, *server_args: str) -> None
@ -74,7 +74,7 @@ fastmcp run server.py -- --config config.json --debug
- `server_spec`: Python file, object specification (file\:obj), config file, URL, or None to auto-detect - `server_spec`: Python file, object specification (file\:obj), config file, URL, or None to auto-detect
### `inspect` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/cli.py#L622" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `inspect` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/cli.py#L521" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
inspect(server_spec: str | None = None) -> None inspect(server_spec: str | None = None) -> None
@ -105,7 +105,7 @@ fastmcp inspect # auto-detect fastmcp.json
- `server_spec`: Python file to inspect, optionally with \:object suffix, or fastmcp.json - `server_spec`: Python file to inspect, optionally with \:object suffix, or fastmcp.json
### `prepare` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/cli.py#L904" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `prepare` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/cli.py#L754" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
prepare(config_path: Annotated[str | None, cyclopts.Parameter(help='Path to fastmcp.json configuration file')] = None, output_dir: Annotated[str | None, cyclopts.Parameter(help='Directory to create the persistent environment in')] = None, skip_source: Annotated[bool, cyclopts.Parameter(help='Skip source preparation (e.g., git clone)')] = False) -> None prepare(config_path: Annotated[str | None, cyclopts.Parameter(help='Path to fastmcp.json configuration file')] = None, output_dir: Annotated[str | None, cyclopts.Parameter(help='Directory to create the persistent environment in')] = None, skip_source: Annotated[bool, cyclopts.Parameter(help='Skip source preparation (e.g., git clone)')] = False) -> None

View file

@ -57,7 +57,7 @@ Install FastMCP server in Claude Code.
- True if installation was successful, False otherwise - True if installation was successful, False otherwise
### `claude_code_command` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/install/claude_code.py#L163" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `claude_code_command` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/install/claude_code.py#L162" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
claude_code_command(server_spec: str) -> None claude_code_command(server_spec: str) -> None

View file

@ -44,7 +44,7 @@ Install FastMCP server in Claude Desktop.
- True if installation was successful, False otherwise - True if installation was successful, False otherwise
### `claude_desktop_command` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/install/claude_desktop.py#L135" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `claude_desktop_command` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/install/claude_desktop.py#L133" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
claude_desktop_command(server_spec: str) -> None claude_desktop_command(server_spec: str) -> None

View file

@ -68,7 +68,7 @@ Install FastMCP server to workspace-specific Cursor configuration.
- True if installation was successful, False otherwise - True if installation was successful, False otherwise
### `install_cursor` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/install/cursor.py#L159" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `install_cursor` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/install/cursor.py#L157" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
install_cursor(file: Path, server_object: str | None, name: str) -> bool install_cursor(file: Path, server_object: str | None, name: str) -> bool
@ -93,7 +93,7 @@ Install FastMCP server in Cursor.
- True if installation was successful, False otherwise - True if installation was successful, False otherwise
### `cursor_command` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/install/cursor.py#L254" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `cursor_command` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/install/cursor.py#L250" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
cursor_command(server_spec: str) -> None cursor_command(server_spec: str) -> None

View file

@ -35,7 +35,7 @@ Generate MCP configuration JSON for manual installation.
- True if generation was successful, False otherwise - True if generation was successful, False otherwise
### `mcp_json_command` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/install/mcp_json.py#L108" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `mcp_json_command` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/install/mcp_json.py#L106" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
mcp_json_command(server_spec: str) -> None mcp_json_command(server_spec: str) -> None

View file

@ -10,7 +10,7 @@ FastMCP run command implementation with enhanced type hints.
## Functions ## Functions
### `is_url` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/run.py#L29" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `is_url` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/run.py#L28" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
is_url(path: str) -> bool is_url(path: str) -> bool
@ -20,7 +20,7 @@ is_url(path: str) -> bool
Check if a string is a URL. Check if a string is a URL.
### `run_with_uv` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/run.py#L35" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `run_with_uv` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/run.py#L34" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
run_with_uv(server_spec: str, python_version: str | None = None, with_packages: list[str] | None = None, with_requirements: Path | None = None, project: Path | None = None, transport: TransportType | None = None, host: str | None = None, port: int | None = None, path: str | None = None, log_level: LogLevelType | None = None, show_banner: bool = True, editable: str | list[str] | None = None) -> None run_with_uv(server_spec: str, python_version: str | None = None, with_packages: list[str] | None = None, with_requirements: Path | None = None, project: Path | None = None, transport: TransportType | None = None, host: str | None = None, port: int | None = None, path: str | None = None, log_level: LogLevelType | None = None, show_banner: bool = True, editable: str | list[str] | None = None) -> None
@ -29,6 +29,10 @@ run_with_uv(server_spec: str, python_version: str | None = None, with_packages:
Run a MCP server using uv run subprocess. Run a MCP server using uv run subprocess.
This function is called when we need to set up a Python environment with specific
dependencies before running the server. The config parsing and merging should already
be done by the caller.
**Args:** **Args:**
- `server_spec`: Python file, object specification (file\:obj), config file, or URL - `server_spec`: Python file, object specification (file\:obj), config file, or URL
- `python_version`: Python version to use (e.g. "3.10") - `python_version`: Python version to use (e.g. "3.10")
@ -41,9 +45,10 @@ Run a MCP server using uv run subprocess.
- `path`: Path to bind to when using http transport - `path`: Path to bind to when using http transport
- `log_level`: Log level - `log_level`: Log level
- `show_banner`: Whether to show the server banner - `show_banner`: Whether to show the server banner
- `editable`: Editable package paths
### `create_client_server` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/run.py#L170" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `create_client_server` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/run.py#L115" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
create_client_server(url: str) -> Any create_client_server(url: str) -> Any
@ -59,7 +64,7 @@ Create a FastMCP server from a client URL.
- A FastMCP server instance - A FastMCP server instance
### `create_mcp_config_server` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/run.py#L190" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `create_mcp_config_server` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/run.py#L135" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
create_mcp_config_server(mcp_config_path: Path) -> FastMCP[None] create_mcp_config_server(mcp_config_path: Path) -> FastMCP[None]
@ -69,10 +74,10 @@ create_mcp_config_server(mcp_config_path: Path) -> FastMCP[None]
Create a FastMCP server from a MCPConfig. Create a FastMCP server from a MCPConfig.
### `load_fastmcp_config` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/run.py#L201" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `load_mcp_server_config` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/run.py#L146" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
load_fastmcp_config(config_path: Path) -> FastMCPConfig load_mcp_server_config(config_path: Path) -> MCPServerConfig
``` ```
@ -82,10 +87,10 @@ Load a FastMCP configuration from a fastmcp.json file.
- `config_path`: Path to fastmcp.json file - `config_path`: Path to fastmcp.json file
**Returns:** **Returns:**
- FastMCPConfig object - MCPServerConfig object
### `run_command` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/run.py#L219" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `run_command` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/run.py#L163" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
run_command(server_spec: str, transport: TransportType | None = None, host: str | None = None, port: int | None = None, path: str | None = None, log_level: LogLevelType | None = None, server_args: list[str] | None = None, show_banner: bool = True, use_direct_import: bool = False, skip_source: bool = False) -> None run_command(server_spec: str, transport: TransportType | None = None, host: str | None = None, port: int | None = None, path: str | None = None, log_level: LogLevelType | None = None, server_args: list[str] | None = None, show_banner: bool = True, use_direct_import: bool = False, skip_source: bool = False) -> None
@ -107,7 +112,7 @@ Run a MCP server or connect to a remote one.
- `skip_source`: Whether to skip source preparation step - `skip_source`: Whether to skip source preparation step
### `run_v1_server` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/run.py#L341" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `run_v1_server` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/cli/run.py#L284" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
run_v1_server(server: FastMCP1x, host: str | None = None, port: int | None = None, transport: TransportType | None = None) -> None run_v1_server(server: FastMCP1x, host: str | None = None, port: int | None = None, transport: TransportType | None = None) -> None

View file

@ -7,13 +7,13 @@ sidebarTitle: oauth
## Functions ## Functions
### `default_cache_dir` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L36" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `default_cache_dir` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L48" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
default_cache_dir() -> Path default_cache_dir() -> Path
``` ```
### `check_if_auth_required` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L154" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `check_if_auth_required` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L192" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
check_if_auth_required(mcp_url: str, httpx_kwargs: dict[str, Any] | None = None) -> bool check_if_auth_required(mcp_url: str, httpx_kwargs: dict[str, Any] | None = None) -> bool
@ -28,7 +28,13 @@ Check if the MCP endpoint requires authentication by making a test request.
## Classes ## Classes
### `FileTokenStorage` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L40" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `StoredToken` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L37" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
Token storage format with absolute expiry time.
### `FileTokenStorage` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L52" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
File-based token storage implementation for OAuth credentials and tokens. File-based token storage implementation for OAuth credentials and tokens.
@ -39,7 +45,7 @@ Each instance is tied to a specific server URL for proper token isolation.
**Methods:** **Methods:**
#### `get_base_url` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L55" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `get_base_url` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L67" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
get_base_url(url: str) -> str get_base_url(url: str) -> str
@ -48,7 +54,7 @@ get_base_url(url: str) -> str
Extract the base URL (scheme + host) from a URL. Extract the base URL (scheme + host) from a URL.
#### `get_cache_key` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L60" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `get_cache_key` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L72" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
get_cache_key(self) -> str get_cache_key(self) -> str
@ -57,7 +63,7 @@ get_cache_key(self) -> str
Generate a safe filesystem key from the server's base URL. Generate a safe filesystem key from the server's base URL.
#### `get_tokens` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L75" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `get_tokens` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L87" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
get_tokens(self) -> OAuthToken | None get_tokens(self) -> OAuthToken | None
@ -66,7 +72,7 @@ get_tokens(self) -> OAuthToken | None
Load tokens from file storage. Load tokens from file storage.
#### `set_tokens` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L92" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `set_tokens` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L119" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
set_tokens(self, tokens: OAuthToken) -> None set_tokens(self, tokens: OAuthToken) -> None
@ -75,7 +81,7 @@ set_tokens(self, tokens: OAuthToken) -> None
Save tokens to file storage. Save tokens to file storage.
#### `get_client_info` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L98" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `get_client_info` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L136" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
get_client_info(self) -> OAuthClientInformationFull | None get_client_info(self) -> OAuthClientInformationFull | None
@ -84,7 +90,7 @@ get_client_info(self) -> OAuthClientInformationFull | None
Load client information from file storage. Load client information from file storage.
#### `set_client_info` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L126" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `set_client_info` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L164" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
set_client_info(self, client_info: OAuthClientInformationFull) -> None set_client_info(self, client_info: OAuthClientInformationFull) -> None
@ -93,7 +99,7 @@ set_client_info(self, client_info: OAuthClientInformationFull) -> None
Save client information to file storage. Save client information to file storage.
#### `clear` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L132" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `clear` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L170" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
clear(self) -> None clear(self) -> None
@ -102,7 +108,7 @@ clear(self) -> None
Clear all cached data for this server. Clear all cached data for this server.
#### `clear_all` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L141" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `clear_all` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L179" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
clear_all(cls, cache_dir: Path | None = None) -> None clear_all(cls, cache_dir: Path | None = None) -> None
@ -111,7 +117,7 @@ clear_all(cls, cache_dir: Path | None = None) -> None
Clear all cached data for all servers. Clear all cached data for all servers.
### `OAuth` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L184" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `OAuth` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L222" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
OAuth client provider for MCP servers with browser-based authentication. OAuth client provider for MCP servers with browser-based authentication.
@ -122,7 +128,7 @@ a browser for user authorization and running a local callback server.
**Methods:** **Methods:**
#### `redirect_handler` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L255" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `redirect_handler` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L302" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
redirect_handler(self, authorization_url: str) -> None redirect_handler(self, authorization_url: str) -> None
@ -131,7 +137,7 @@ redirect_handler(self, authorization_url: str) -> None
Open browser for authorization. Open browser for authorization.
#### `callback_handler` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L260" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `callback_handler` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/auth/oauth.py#L307" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
callback_handler(self) -> tuple[str, str | None] callback_handler(self) -> tuple[str, str | None]

View file

@ -7,7 +7,7 @@ sidebarTitle: client
## Classes ## Classes
### `ClientSessionState` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L80" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `ClientSessionState` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L81" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
Holds all session-related state for a Client instance. Holds all session-related state for a Client instance.
@ -16,7 +16,7 @@ This allows clean separation of configuration (which is copied) from
session state (which should be fresh for each new client instance). session state (which should be fresh for each new client instance).
### `Client` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L96" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `Client` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L97" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
MCP client that delegates connection management to a Transport instance. MCP client that delegates connection management to a Transport instance.
@ -79,7 +79,7 @@ async with client:
**Methods:** **Methods:**
#### `session` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L282" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `session` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L283" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
session(self) -> ClientSession session(self) -> ClientSession
@ -88,7 +88,7 @@ session(self) -> ClientSession
Get the current active session. Raises RuntimeError if not connected. Get the current active session. Raises RuntimeError if not connected.
#### `initialize_result` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L292" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `initialize_result` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L293" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
initialize_result(self) -> mcp.types.InitializeResult initialize_result(self) -> mcp.types.InitializeResult
@ -97,7 +97,7 @@ initialize_result(self) -> mcp.types.InitializeResult
Get the result of the initialization request. Get the result of the initialization request.
#### `set_roots` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L300" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `set_roots` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L301" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
set_roots(self, roots: RootsList | RootsHandler) -> None set_roots(self, roots: RootsList | RootsHandler) -> None
@ -106,7 +106,7 @@ set_roots(self, roots: RootsList | RootsHandler) -> None
Set the roots for the client. This does not automatically call `send_roots_list_changed`. Set the roots for the client. This does not automatically call `send_roots_list_changed`.
#### `set_sampling_callback` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L304" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `set_sampling_callback` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L305" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
set_sampling_callback(self, sampling_callback: ClientSamplingHandler) -> None set_sampling_callback(self, sampling_callback: ClientSamplingHandler) -> None
@ -115,7 +115,7 @@ set_sampling_callback(self, sampling_callback: ClientSamplingHandler) -> None
Set the sampling callback for the client. Set the sampling callback for the client.
#### `set_elicitation_callback` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L310" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `set_elicitation_callback` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L311" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None
@ -124,7 +124,7 @@ set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None
Set the elicitation callback for the client. Set the elicitation callback for the client.
#### `is_connected` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L318" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `is_connected` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L319" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
is_connected(self) -> bool is_connected(self) -> bool
@ -133,7 +133,7 @@ is_connected(self) -> bool
Check if the client is currently connected. Check if the client is currently connected.
#### `new` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L322" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `new` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L323" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
new(self) -> Client[ClientTransportT] new(self) -> Client[ClientTransportT]
@ -149,13 +149,13 @@ share state with the original client.
- A new Client instance with the same configuration but disconnected state. - A new Client instance with the same configuration but disconnected state.
#### `close` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L487" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `close` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L490" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
close(self) close(self)
``` ```
#### `ping` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L493" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `ping` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L496" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
ping(self) -> bool ping(self) -> bool
@ -164,7 +164,7 @@ ping(self) -> bool
Send a ping request. Send a ping request.
#### `cancel` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L498" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `cancel` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L501" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
cancel(self, request_id: str | int, reason: str | None = None) -> None cancel(self, request_id: str | int, reason: str | None = None) -> None
@ -173,7 +173,7 @@ cancel(self, request_id: str | int, reason: str | None = None) -> None
Send a cancellation notification for an in-progress request. Send a cancellation notification for an in-progress request.
#### `progress` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L515" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `progress` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L518" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
progress(self, progress_token: str | int, progress: float, total: float | None = None, message: str | None = None) -> None progress(self, progress_token: str | int, progress: float, total: float | None = None, message: str | None = None) -> None
@ -182,7 +182,7 @@ progress(self, progress_token: str | int, progress: float, total: float | None =
Send a progress notification. Send a progress notification.
#### `set_logging_level` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L527" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `set_logging_level` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L530" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
set_logging_level(self, level: mcp.types.LoggingLevel) -> None set_logging_level(self, level: mcp.types.LoggingLevel) -> None
@ -191,7 +191,7 @@ set_logging_level(self, level: mcp.types.LoggingLevel) -> None
Send a logging/setLevel request. Send a logging/setLevel request.
#### `send_roots_list_changed` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L531" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `send_roots_list_changed` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L534" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
send_roots_list_changed(self) -> None send_roots_list_changed(self) -> None
@ -200,7 +200,7 @@ send_roots_list_changed(self) -> None
Send a roots/list_changed notification. Send a roots/list_changed notification.
#### `list_resources_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L537" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `list_resources_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L540" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
list_resources_mcp(self) -> mcp.types.ListResourcesResult list_resources_mcp(self) -> mcp.types.ListResourcesResult
@ -216,7 +216,7 @@ containing the list of resources and any additional metadata.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `list_resources` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L552" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `list_resources` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L555" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
list_resources(self) -> list[mcp.types.Resource] list_resources(self) -> list[mcp.types.Resource]
@ -231,7 +231,7 @@ Retrieve a list of resources available on the server.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `list_resource_templates_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L564" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `list_resource_templates_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L567" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
list_resource_templates_mcp(self) -> mcp.types.ListResourceTemplatesResult list_resource_templates_mcp(self) -> mcp.types.ListResourceTemplatesResult
@ -247,7 +247,7 @@ containing the list of resource templates and any additional metadata.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `list_resource_templates` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L581" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `list_resource_templates` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L584" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
list_resource_templates(self) -> list[mcp.types.ResourceTemplate] list_resource_templates(self) -> list[mcp.types.ResourceTemplate]
@ -262,7 +262,7 @@ Retrieve a list of resource templates available on the server.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `read_resource_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L595" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `read_resource_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L598" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
read_resource_mcp(self, uri: AnyUrl | str) -> mcp.types.ReadResourceResult read_resource_mcp(self, uri: AnyUrl | str) -> mcp.types.ReadResourceResult
@ -281,7 +281,7 @@ containing the resource contents and any additional metadata.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `read_resource` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L617" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `read_resource` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L620" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
read_resource(self, uri: AnyUrl | str) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents] read_resource(self, uri: AnyUrl | str) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents]
@ -300,7 +300,7 @@ objects, typically containing either text or binary data.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `list_prompts_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L656" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `list_prompts_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L659" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
list_prompts_mcp(self) -> mcp.types.ListPromptsResult list_prompts_mcp(self) -> mcp.types.ListPromptsResult
@ -316,7 +316,7 @@ containing the list of prompts and any additional metadata.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `list_prompts` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L671" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `list_prompts` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L674" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
list_prompts(self) -> list[mcp.types.Prompt] list_prompts(self) -> list[mcp.types.Prompt]
@ -331,7 +331,7 @@ Retrieve a list of prompts available on the server.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `get_prompt_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L684" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `get_prompt_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L687" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
get_prompt_mcp(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult get_prompt_mcp(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult
@ -351,7 +351,7 @@ containing the prompt messages and any additional metadata.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `get_prompt` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L720" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `get_prompt` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L723" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult
@ -371,7 +371,7 @@ containing the prompt messages and any additional metadata.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `complete_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L741" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `complete_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L744" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
complete_mcp(self, ref: mcp.types.ResourceReference | mcp.types.PromptReference, argument: dict[str, str]) -> mcp.types.CompleteResult complete_mcp(self, ref: mcp.types.ResourceReference | mcp.types.PromptReference, argument: dict[str, str]) -> mcp.types.CompleteResult
@ -391,7 +391,7 @@ containing the completion and any additional metadata.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `complete` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L764" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `complete` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L767" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
complete(self, ref: mcp.types.ResourceReference | mcp.types.PromptReference, argument: dict[str, str]) -> mcp.types.Completion complete(self, ref: mcp.types.ResourceReference | mcp.types.PromptReference, argument: dict[str, str]) -> mcp.types.Completion
@ -410,7 +410,7 @@ Send a completion request to the server.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `list_tools_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L786" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `list_tools_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L789" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
list_tools_mcp(self) -> mcp.types.ListToolsResult list_tools_mcp(self) -> mcp.types.ListToolsResult
@ -426,7 +426,7 @@ containing the list of tools and any additional metadata.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `list_tools` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L801" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `list_tools` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L804" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
list_tools(self) -> list[mcp.types.Tool] list_tools(self) -> list[mcp.types.Tool]
@ -441,7 +441,7 @@ Retrieve a list of tools available on the server.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `call_tool_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L815" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `call_tool_mcp` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L818" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
call_tool_mcp(self, name: str, arguments: dict[str, Any], progress_handler: ProgressHandler | None = None, timeout: datetime.timedelta | float | int | None = None) -> mcp.types.CallToolResult call_tool_mcp(self, name: str, arguments: dict[str, Any], progress_handler: ProgressHandler | None = None, timeout: datetime.timedelta | float | int | None = None) -> mcp.types.CallToolResult
@ -466,7 +466,7 @@ containing the tool result and any additional metadata.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `call_tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L852" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `call_tool` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L855" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
call_tool(self, name: str, arguments: dict[str, Any] | None = None, timeout: datetime.timedelta | float | int | None = None, progress_handler: ProgressHandler | None = None, raise_on_error: bool = True) -> CallToolResult call_tool(self, name: str, arguments: dict[str, Any] | None = None, timeout: datetime.timedelta | float | int | None = None, progress_handler: ProgressHandler | None = None, raise_on_error: bool = True) -> CallToolResult
@ -496,10 +496,10 @@ raw result object.
- `RuntimeError`: If called while the client is not connected. - `RuntimeError`: If called while the client is not connected.
#### `generate_name` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L923" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `generate_name` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L926" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
generate_name(cls, name: str | None = None) -> str generate_name(cls, name: str | None = None) -> str
``` ```
### `CallToolResult` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L932" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `CallToolResult` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/client.py#L935" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

View file

@ -182,7 +182,7 @@ Handles provider-specific requirements:
**Methods:** **Methods:**
#### `get_client` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L354" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `get_client` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L355" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
get_client(self, client_id: str) -> OAuthClientInformationFull | None get_client(self, client_id: str) -> OAuthClientInformationFull | None
@ -199,7 +199,7 @@ handles the case where a client with cached tokens reconnects
on a different port. on a different port.
#### `register_client` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L386" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `register_client` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L388" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
register_client(self, client_info: OAuthClientInformationFull) -> None register_client(self, client_info: OAuthClientInformationFull) -> None
@ -226,7 +226,7 @@ The flow:
4. When client reconnects with a different port, ProxyDCRClient accepts it 4. When client reconnects with a different port, ProxyDCRClient accepts it
#### `authorize` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L435" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `authorize` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L447" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
authorize(self, client: OAuthClientInformationFull, params: AuthorizationParams) -> str authorize(self, client: OAuthClientInformationFull, params: AuthorizationParams) -> str
@ -240,7 +240,7 @@ This implements the DCR-compliant proxy pattern:
3. Redirect to IdP with our fixed callback URL 3. Redirect to IdP with our fixed callback URL
#### `load_authorization_code` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L491" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `load_authorization_code` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L503" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
load_authorization_code(self, client: OAuthClientInformationFull, authorization_code: str) -> AuthorizationCode | None load_authorization_code(self, client: OAuthClientInformationFull, authorization_code: str) -> AuthorizationCode | None
@ -252,7 +252,7 @@ Look up our client code and return authorization code object
with PKCE challenge for validation. with PKCE challenge for validation.
#### `exchange_authorization_code` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L533" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `exchange_authorization_code` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L545" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
exchange_authorization_code(self, client: OAuthClientInformationFull, authorization_code: AuthorizationCode) -> OAuthToken exchange_authorization_code(self, client: OAuthClientInformationFull, authorization_code: AuthorizationCode) -> OAuthToken
@ -264,7 +264,7 @@ For the DCR-compliant proxy flow, we return the IdP tokens that were obtained
during the IdP callback exchange. PKCE validation is handled by the MCP framework. during the IdP callback exchange. PKCE validation is handled by the MCP framework.
#### `load_refresh_token` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L600" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `load_refresh_token` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L612" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
load_refresh_token(self, client: OAuthClientInformationFull, refresh_token: str) -> RefreshToken | None load_refresh_token(self, client: OAuthClientInformationFull, refresh_token: str) -> RefreshToken | None
@ -273,7 +273,7 @@ load_refresh_token(self, client: OAuthClientInformationFull, refresh_token: str)
Load refresh token from local storage. Load refresh token from local storage.
#### `exchange_refresh_token` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L608" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `exchange_refresh_token` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L620" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
exchange_refresh_token(self, client: OAuthClientInformationFull, refresh_token: RefreshToken, scopes: list[str]) -> OAuthToken exchange_refresh_token(self, client: OAuthClientInformationFull, refresh_token: RefreshToken, scopes: list[str]) -> OAuthToken
@ -282,7 +282,7 @@ exchange_refresh_token(self, client: OAuthClientInformationFull, refresh_token:
Exchange refresh token for new access token using authlib. Exchange refresh token for new access token using authlib.
#### `load_access_token` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L683" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `load_access_token` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L695" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
load_access_token(self, token: str) -> AccessToken | None load_access_token(self, token: str) -> AccessToken | None
@ -294,7 +294,7 @@ Delegates to the JWT verifier which handles signature validation,
expiration checking, and claims validation using the upstream JWKS. expiration checking, and claims validation using the upstream JWKS.
#### `revoke_token` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L700" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `revoke_token` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L712" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
revoke_token(self, token: AccessToken | RefreshToken) -> None revoke_token(self, token: AccessToken | RefreshToken) -> None
@ -306,7 +306,7 @@ Removes tokens from local storage and attempts to revoke them with
the upstream server if a revocation endpoint is configured. the upstream server if a revocation endpoint is configured.
#### `get_routes` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L893" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `get_routes` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/oauth_proxy.py#L905" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
get_routes(self) -> list[Route] get_routes(self) -> list[Route]

View file

@ -65,9 +65,9 @@ Setup Requirements:
4. Note your Client ID and Client Secret 4. Note your Client ID and Client Secret
### `AuthKitProviderSettings` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/providers/workos.py#L253" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `AuthKitProviderSettings` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/providers/workos.py#L257" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `AuthKitProvider` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/providers/workos.py#L271" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `AuthKitProvider` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/providers/workos.py#L275" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
AuthKit metadata provider for DCR (Dynamic Client Registration). AuthKit metadata provider for DCR (Dynamic Client Registration).
@ -93,7 +93,7 @@ https://workos.com/docs/authkit/mcp/integrating/token-verification
**Methods:** **Methods:**
#### `get_routes` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/providers/workos.py#L354" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `get_routes` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/providers/workos.py#L358" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
get_routes(self) -> list[Route] get_routes(self) -> list[Route]

View file

@ -44,8 +44,9 @@ Validate a redirect URI against allowed patterns.
**Args:** **Args:**
- `redirect_uri`: The redirect URI to validate - `redirect_uri`: The redirect URI to validate
- `allowed_patterns`: List of allowed patterns. If None, defaults to localhost. - `allowed_patterns`: List of allowed patterns. If None, all URIs are allowed (for DCR compatibility).
If empty list, all URIs are allowed. If empty list, no URIs are allowed.
To restrict to localhost only, explicitly pass DEFAULT_LOCALHOST_PATTERNS.
**Returns:** **Returns:**
- True if the redirect URI is allowed - True if the redirect URI is allowed

View file

@ -8,9 +8,21 @@ sidebarTitle: logging
Comprehensive logging middleware for FastMCP servers. Comprehensive logging middleware for FastMCP servers.
## Functions
### `default_serializer` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/middleware/logging.py#L14" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
default_serializer(data: Any) -> str
```
The default serializer for Payloads in the logging middleware.
## Classes ## Classes
### `LoggingMiddleware` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/middleware/logging.py#L10" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `LoggingMiddleware` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/middleware/logging.py#L19" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
Middleware that provides comprehensive request and response logging. Middleware that provides comprehensive request and response logging.
@ -21,16 +33,16 @@ monitoring, and understanding server usage patterns.
**Methods:** **Methods:**
#### `on_message` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/middleware/logging.py#L71" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `on_message` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/middleware/logging.py#L91" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
on_message(self, context: MiddlewareContext, call_next: CallNext) -> Any on_message(self, context: MiddlewareContext[Any], call_next: CallNext[Any, Any]) -> Any
``` ```
Log all messages. Log all messages.
### `StructuredLoggingMiddleware` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/middleware/logging.py#L92" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `StructuredLoggingMiddleware` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/middleware/logging.py#L114" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
Middleware that provides structured JSON logging for better log analysis. Middleware that provides structured JSON logging for better log analysis.
@ -41,10 +53,10 @@ aggregation tools like ELK stack, Splunk, or cloud logging services.
**Methods:** **Methods:**
#### `on_message` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/middleware/logging.py#L149" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `on_message` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/middleware/logging.py#L185" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
on_message(self, context: MiddlewareContext, call_next: CallNext) -> Any on_message(self, context: MiddlewareContext[Any], call_next: CallNext[Any, Any]) -> Any
``` ```
Log structured message information. Log structured message information.

View file

@ -7,7 +7,37 @@ sidebarTitle: cli
## Functions ## Functions
### `log_server_banner` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/cli.py#L27" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `is_already_in_uv_subprocess` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/cli.py#L28" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
is_already_in_uv_subprocess() -> bool
```
Check if we're already running in a FastMCP uv subprocess.
### `load_and_merge_config` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/cli.py#L33" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
load_and_merge_config(server_spec: str | None, **cli_overrides) -> tuple[MCPServerConfig, str]
```
Load config from server_spec and apply CLI overrides.
This consolidates the config parsing logic that was duplicated across
run, inspect, and dev commands.
**Args:**
- `server_spec`: Python file, config file, URL, or None to auto-detect
- `cli_overrides`: CLI arguments that override config values
**Returns:**
- Tuple of (MCPServerConfig, resolved_server_spec)
### `log_server_banner` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/cli.py#L151" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
log_server_banner(server: FastMCP[Any], transport: Literal['stdio', 'http', 'sse', 'streamable-http']) -> None log_server_banner(server: FastMCP[Any], transport: Literal['stdio', 'http', 'sse', 'streamable-http']) -> None

View file

@ -3,7 +3,7 @@ title: __init__
sidebarTitle: __init__ sidebarTitle: __init__
--- ---
# `fastmcp.utilities.fastmcp_config` # `fastmcp.utilities.mcp_server_config`
FastMCP Configuration module. FastMCP Configuration module.

View file

@ -3,6 +3,6 @@ title: __init__
sidebarTitle: __init__ sidebarTitle: __init__
--- ---
# `fastmcp.utilities.fastmcp_config.v1` # `fastmcp.utilities.mcp_server_config.v1`
*This module is empty or contains only private/internal implementations.* *This module is empty or contains only private/internal implementations.*

View file

@ -1,9 +1,9 @@
--- ---
title: fastmcp_config title: mcp_server_config
sidebarTitle: fastmcp_config sidebarTitle: mcp_server_config
--- ---
# `fastmcp.utilities.fastmcp_config.v1.fastmcp_config` # `fastmcp.utilities.mcp_server_config.v1.mcp_server_config`
FastMCP Configuration File Support. FastMCP Configuration File Support.
@ -15,7 +15,7 @@ command-line arguments.
## Functions ## Functions
### `generate_schema` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L707" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `generate_schema` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L705" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
generate_schema(output_path: Path | str | None = None) -> dict[str, Any] | None generate_schema(output_path: Path | str | None = None) -> dict[str, Any] | None
@ -38,7 +38,7 @@ validation and auto-completion.
## Classes ## Classes
### `Environment` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L33" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `Environment` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L33" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
Configuration for Python environment setup. Configuration for Python environment setup.
@ -46,22 +46,22 @@ Configuration for Python environment setup.
**Methods:** **Methods:**
#### `build_uv_args` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L66" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `build_uv_run_command` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L66" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
build_uv_args(self, command: str | list[str] | None = None) -> list[str] build_uv_run_command(self, command: list[str]) -> list[str]
``` ```
Build uv run arguments from this environment configuration. Build complete uv run command with environment args and command to execute.
**Args:** **Args:**
- `command`: Optional command to append (string or list of args) - `command`: Command to execute (e.g., ["fastmcp", "run", "server.py"])
**Returns:** **Returns:**
- List of arguments for uv run command - Complete command ready for subprocess.run, including "uv" prefix
#### `run_with_uv` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L109" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `run_with_uv` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L105" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
run_with_uv(self, command: list[str]) -> None run_with_uv(self, command: list[str]) -> None
@ -73,7 +73,7 @@ Execute a command using uv run with this environment configuration.
- `command`: Command and arguments to execute (e.g., ["fastmcp", "run", "server.py"]) - `command`: Command and arguments to execute (e.g., ["fastmcp", "run", "server.py"])
#### `needs_uv` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L132" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `needs_uv` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L130" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
needs_uv(self) -> bool needs_uv(self) -> bool
@ -85,7 +85,7 @@ Check if this environment config requires uv to set up.
- True if any environment settings require uv run - True if any environment settings require uv run
#### `prepare` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L148" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `prepare` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L146" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
prepare(self, output_dir: Path | None = None) -> None prepare(self, output_dir: Path | None = None) -> None
@ -98,7 +98,7 @@ Prepare the Python environment using uv.
If None, creates a temporary directory for ephemeral use. If None, creates a temporary directory for ephemeral use.
### `Deployment` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L313" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `Deployment` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L311" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
Configuration for server deployment and runtime settings. Configuration for server deployment and runtime settings.
@ -106,7 +106,7 @@ Configuration for server deployment and runtime settings.
**Methods:** **Methods:**
#### `apply_runtime_settings` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L362" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `apply_runtime_settings` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L360" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
apply_runtime_settings(self, config_path: Path | None = None) -> None apply_runtime_settings(self, config_path: Path | None = None) -> None
@ -122,7 +122,7 @@ For example: "API_URL": "https://api.${ENVIRONMENT}.example.com"
will substitute the value of the ENVIRONMENT variable at runtime. will substitute the value of the ENVIRONMENT variable at runtime.
### `FastMCPConfig` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L411" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `MCPServerConfig` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L409" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
Configuration for a FastMCP server. Configuration for a FastMCP server.
@ -133,7 +133,7 @@ a FastMCP server in a declarative format.
**Methods:** **Methods:**
#### `validate_source` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L460" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `validate_source` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L458" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
validate_source(cls, v: dict | FileSystemSource) -> FileSystemSource validate_source(cls, v: dict | FileSystemSource) -> FileSystemSource
@ -146,10 +146,10 @@ Supports:
- FileSystemSource instance (passed through) - FileSystemSource instance (passed through)
No string parsing happens here - that's only at CLI boundaries. No string parsing happens here - that's only at CLI boundaries.
FastMCPConfig works only with properly typed objects. MCPServerConfig works only with properly typed objects.
#### `validate_environment` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L483" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `validate_environment` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L481" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
validate_environment(cls, v: dict | Environment) -> Environment validate_environment(cls, v: dict | Environment) -> Environment
@ -162,7 +162,7 @@ Accepts:
- dict that can be converted to Environment - dict that can be converted to Environment
#### `validate_deployment` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L499" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `validate_deployment` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L497" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
validate_deployment(cls, v: dict | Deployment) -> Deployment validate_deployment(cls, v: dict | Deployment) -> Deployment
@ -175,10 +175,10 @@ Accepts:
- dict that can be converted to Deployment - dict that can be converted to Deployment
#### `from_file` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L515" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `from_file` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L513" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
from_file(cls, file_path: Path) -> FastMCPConfig from_file(cls, file_path: Path) -> MCPServerConfig
``` ```
Load configuration from a JSON file. Load configuration from a JSON file.
@ -187,7 +187,7 @@ Load configuration from a JSON file.
- `file_path`: Path to the configuration file - `file_path`: Path to the configuration file
**Returns:** **Returns:**
- FastMCPConfig instance - MCPServerConfig instance
**Raises:** **Raises:**
- `FileNotFoundError`: If the file doesn't exist - `FileNotFoundError`: If the file doesn't exist
@ -195,10 +195,10 @@ Load configuration from a JSON file.
- `pydantic.ValidationError`: If the configuration is invalid - `pydantic.ValidationError`: If the configuration is invalid
#### `from_cli_args` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L538" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `from_cli_args` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L536" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
from_cli_args(cls, source: FileSystemSource, transport: Literal['stdio', 'http', 'sse', 'streamable-http'] | None = None, host: str | None = None, port: int | None = None, path: str | None = None, log_level: Literal['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'] | None = None, python: str | None = None, dependencies: list[str] | None = None, requirements: str | None = None, project: str | None = None, editable: str | None = None, env: dict[str, str] | None = None, cwd: str | None = None, args: list[str] | None = None) -> FastMCPConfig from_cli_args(cls, source: FileSystemSource, transport: Literal['stdio', 'http', 'sse', 'streamable-http'] | None = None, host: str | None = None, port: int | None = None, path: str | None = None, log_level: Literal['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'] | None = None, python: str | None = None, dependencies: list[str] | None = None, requirements: str | None = None, project: str | None = None, editable: str | None = None, env: dict[str, str] | None = None, cwd: str | None = None, args: list[str] | None = None) -> MCPServerConfig
``` ```
Create a config from CLI arguments. Create a config from CLI arguments.
@ -223,10 +223,10 @@ goes through a config object.
- `args`: Server arguments - `args`: Server arguments
**Returns:** **Returns:**
- FastMCPConfig instance - MCPServerConfig instance
#### `find_config` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L615" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `find_config` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L613" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
find_config(cls, start_path: Path | None = None) -> Path | None find_config(cls, start_path: Path | None = None) -> Path | None
@ -241,7 +241,7 @@ Find a fastmcp.json file in the specified directory.
- Path to the configuration file, or None if not found - Path to the configuration file, or None if not found
#### `prepare` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L634" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `prepare` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L632" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
prepare(self, skip_source: bool = False, output_dir: Path | None = None) -> None prepare(self, skip_source: bool = False, output_dir: Path | None = None) -> None
@ -257,7 +257,7 @@ When output_dir is None, does ephemeral caching (for backwards compatibility).
- `output_dir`: Directory to create the persistent uv project in (optional) - `output_dir`: Directory to create the persistent uv project in (optional)
#### `prepare_environment` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L655" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `prepare_environment` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L653" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
prepare_environment(self, output_dir: Path | None = None) -> None prepare_environment(self, output_dir: Path | None = None) -> None
@ -272,7 +272,7 @@ Prepare the Python environment.
Delegates to the environment's prepare() method Delegates to the environment's prepare() method
#### `prepare_source` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L666" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `prepare_source` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L664" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
prepare_source(self) -> None prepare_source(self) -> None
@ -283,7 +283,7 @@ Prepare the source for loading.
Delegates to the source's prepare() method. Delegates to the source's prepare() method.
#### `run_server` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/fastmcp_config.py#L673" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `run_server` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/mcp_server_config.py#L671" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
run_server(self, **kwargs: Any) -> None run_server(self, **kwargs: Any) -> None

View file

@ -3,6 +3,6 @@ title: __init__
sidebarTitle: __init__ sidebarTitle: __init__
--- ---
# `fastmcp.utilities.fastmcp_config.v1.sources` # `fastmcp.utilities.mcp_server_config.v1.sources`
*This module is empty or contains only private/internal implementations.* *This module is empty or contains only private/internal implementations.*

View file

@ -3,11 +3,11 @@ title: base
sidebarTitle: base sidebarTitle: base
--- ---
# `fastmcp.utilities.fastmcp_config.v1.sources.base` # `fastmcp.utilities.mcp_server_config.v1.sources.base`
## Classes ## Classes
### `BaseSource` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/sources/base.py#L7" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `BaseSource` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/sources/base.py#L7" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
Abstract base class for all source types. Abstract base class for all source types.
@ -15,7 +15,7 @@ Abstract base class for all source types.
**Methods:** **Methods:**
#### `prepare` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/sources/base.py#L12" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `prepare` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/sources/base.py#L12" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
prepare(self) -> None prepare(self) -> None
@ -28,7 +28,7 @@ this method performs that preparation. For sources that don't
need preparation (e.g., local files), this is a no-op. need preparation (e.g., local files), this is a no-op.
#### `load_server` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/sources/base.py#L23" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `load_server` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/sources/base.py#L23" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
load_server(self) -> Any load_server(self) -> Any

View file

@ -3,11 +3,11 @@ title: filesystem
sidebarTitle: filesystem sidebarTitle: filesystem
--- ---
# `fastmcp.utilities.fastmcp_config.v1.sources.filesystem` # `fastmcp.utilities.mcp_server_config.v1.sources.filesystem`
## Classes ## Classes
### `FileSystemSource` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/sources/filesystem.py#L15" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> ### `FileSystemSource` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/sources/filesystem.py#L15" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
Source for local Python files. Source for local Python files.
@ -15,7 +15,7 @@ Source for local Python files.
**Methods:** **Methods:**
#### `parse_path_with_object` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/sources/filesystem.py#L27" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `parse_path_with_object` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/sources/filesystem.py#L27" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
parse_path_with_object(cls, v: str) -> str parse_path_with_object(cls, v: str) -> str
@ -27,7 +27,7 @@ This validator runs before the model is created, allowing us to
handle the "file.py:object" syntax at the model boundary. handle the "file.py:object" syntax at the model boundary.
#### `load_server` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/fastmcp_config/v1/sources/filesystem.py#L62" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup> #### `load_server` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/utilities/mcp_server_config/v1/sources/filesystem.py#L62" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python ```python
load_server(self) -> Any load_server(self) -> Any

View file

@ -26,14 +26,14 @@ With the configuration file in place, you can run the server in several ways:
```bash ```bash
# Auto-detect fastmcp.json in current directory # Auto-detect fastmcp.json in current directory
cd examples/fastmcp_config_demo cd examples/mcp_server_config_demo
fastmcp run fastmcp run
# Or specify the config file explicitly # Or specify the config file explicitly
fastmcp run examples/fastmcp_config_demo/fastmcp.json fastmcp run examples/mcp_server_config_demo/fastmcp.json
# Or use development mode with the Inspector UI # Or use development mode with the Inspector UI
fastmcp dev examples/fastmcp_config_demo/fastmcp.json fastmcp dev examples/mcp_server_config_demo/fastmcp.json
``` ```
## Benefits ## Benefits

View file

@ -6,8 +6,8 @@ import sys
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
from fastmcp.utilities.fastmcp_config import Environment
from fastmcp.utilities.logging import get_logger from fastmcp.utilities.logging import get_logger
from fastmcp.utilities.mcp_server_config import Environment
logger = get_logger(__name__) logger = get_logger(__name__)

View file

@ -20,13 +20,13 @@ import fastmcp
from fastmcp.cli import run as run_module from fastmcp.cli import run as run_module
from fastmcp.cli.install import install_app from fastmcp.cli.install import install_app
from fastmcp.server.server import FastMCP from fastmcp.server.server import FastMCP
from fastmcp.utilities.fastmcp_config import Environment, FastMCPConfig
from fastmcp.utilities.inspect import ( from fastmcp.utilities.inspect import (
InspectFormat, InspectFormat,
format_info, format_info,
inspect_fastmcp, inspect_fastmcp,
) )
from fastmcp.utilities.logging import get_logger from fastmcp.utilities.logging import get_logger
from fastmcp.utilities.mcp_server_config import Environment, MCPServerConfig
logger = get_logger("cli") logger = get_logger("cli")
console = Console() console = Console()
@ -796,7 +796,7 @@ async def prepare(
# Auto-detect fastmcp.json if not provided # Auto-detect fastmcp.json if not provided
if config_path is None: if config_path is None:
found_config = FastMCPConfig.find_config() found_config = MCPServerConfig.find_config()
if found_config: if found_config:
config_path = str(found_config) config_path = str(found_config)
logger.info(f"Using configuration from {config_path}") logger.info(f"Using configuration from {config_path}")
@ -816,7 +816,7 @@ async def prepare(
try: try:
# Load the configuration # Load the configuration
config = FastMCPConfig.from_file(config_file) config = MCPServerConfig.from_file(config_file)
# Prepare environment and source # Prepare environment and source
await config.prepare( await config.prepare(

View file

@ -9,8 +9,8 @@ from typing import Annotated
import cyclopts import cyclopts
from rich import print from rich import print
from fastmcp.utilities.fastmcp_config import Environment
from fastmcp.utilities.logging import get_logger from fastmcp.utilities.logging import get_logger
from fastmcp.utilities.mcp_server_config import Environment
from .shared import process_common_args from .shared import process_common_args

View file

@ -9,8 +9,8 @@ import cyclopts
from rich import print from rich import print
from fastmcp.mcp_config import StdioMCPServer, update_config_file from fastmcp.mcp_config import StdioMCPServer, update_config_file
from fastmcp.utilities.fastmcp_config import Environment
from fastmcp.utilities.logging import get_logger from fastmcp.utilities.logging import get_logger
from fastmcp.utilities.mcp_server_config import Environment
from .shared import process_common_args from .shared import process_common_args

View file

@ -10,8 +10,8 @@ import cyclopts
from rich import print from rich import print
from fastmcp.mcp_config import StdioMCPServer, update_config_file from fastmcp.mcp_config import StdioMCPServer, update_config_file
from fastmcp.utilities.fastmcp_config import Environment
from fastmcp.utilities.logging import get_logger from fastmcp.utilities.logging import get_logger
from fastmcp.utilities.mcp_server_config import Environment
from .shared import process_common_args from .shared import process_common_args

View file

@ -9,8 +9,8 @@ import cyclopts
import pyperclip import pyperclip
from rich import print from rich import print
from fastmcp.utilities.fastmcp_config import Environment
from fastmcp.utilities.logging import get_logger from fastmcp.utilities.logging import get_logger
from fastmcp.utilities.mcp_server_config import Environment
from .shared import process_common_args from .shared import process_common_args

View file

@ -8,9 +8,9 @@ from dotenv import dotenv_values
from pydantic import ValidationError from pydantic import ValidationError
from rich import print from rich import print
from fastmcp.utilities.fastmcp_config import FastMCPConfig
from fastmcp.utilities.fastmcp_config.v1.sources.filesystem import FileSystemSource
from fastmcp.utilities.logging import get_logger from fastmcp.utilities.logging import get_logger
from fastmcp.utilities.mcp_server_config import MCPServerConfig
from fastmcp.utilities.mcp_server_config.v1.sources.filesystem import FileSystemSource
logger = get_logger(__name__) logger = get_logger(__name__)
@ -40,7 +40,7 @@ async def process_common_args(
# Convert None to empty lists for list parameters # Convert None to empty lists for list parameters
with_packages = with_packages or [] with_packages = with_packages or []
env_vars = env_vars or [] env_vars = env_vars or []
# Create FastMCPConfig from server_spec # Create MCPServerConfig from server_spec
config = None config = None
if server_spec.endswith(".json"): if server_spec.endswith(".json"):
config_path = Path(server_spec).resolve() config_path = Path(server_spec).resolve()
@ -58,8 +58,8 @@ async def process_common_args(
print("[red]MCPConfig files are not supported for installation[/red]") print("[red]MCPConfig files are not supported for installation[/red]")
sys.exit(1) sys.exit(1)
else: else:
# It's a FastMCPConfig # It's a MCPServerConfig
config = FastMCPConfig.from_file(config_path) config = MCPServerConfig.from_file(config_path)
# Merge packages from config if not overridden # Merge packages from config if not overridden
if config.environment.dependencies: if config.environment.dependencies:
@ -72,7 +72,7 @@ async def process_common_args(
else: else:
# Create config from file path # Create config from file path
source = FileSystemSource(path=server_spec) source = FileSystemSource(path=server_spec)
config = FastMCPConfig(source=source) config = MCPServerConfig(source=source)
# Extract file and server_object from the source # Extract file and server_object from the source
# The FileSystemSource handles parsing path:object syntax # The FileSystemSource handles parsing path:object syntax

View file

@ -11,12 +11,12 @@ from typing import Any, Literal
from mcp.server.fastmcp import FastMCP as FastMCP1x from mcp.server.fastmcp import FastMCP as FastMCP1x
from fastmcp.server.server import FastMCP from fastmcp.server.server import FastMCP
from fastmcp.utilities.fastmcp_config import (
Environment,
FastMCPConfig,
)
from fastmcp.utilities.fastmcp_config.v1.sources.filesystem import FileSystemSource
from fastmcp.utilities.logging import get_logger from fastmcp.utilities.logging import get_logger
from fastmcp.utilities.mcp_server_config import (
Environment,
MCPServerConfig,
)
from fastmcp.utilities.mcp_server_config.v1.sources.filesystem import FileSystemSource
logger = get_logger("cli.run") logger = get_logger("cli.run")
@ -143,16 +143,16 @@ def create_mcp_config_server(mcp_config_path: Path) -> FastMCP[None]:
return server return server
def load_fastmcp_config(config_path: Path) -> FastMCPConfig: def load_mcp_server_config(config_path: Path) -> MCPServerConfig:
"""Load a FastMCP configuration from a fastmcp.json file. """Load a FastMCP configuration from a fastmcp.json file.
Args: Args:
config_path: Path to fastmcp.json file config_path: Path to fastmcp.json file
Returns: Returns:
FastMCPConfig object MCPServerConfig object
""" """
config = FastMCPConfig.from_file(config_path) config = MCPServerConfig.from_file(config_path)
# Apply runtime settings from deployment config # Apply runtime settings from deployment config
config.deployment.apply_runtime_settings(config_path) config.deployment.apply_runtime_settings(config_path)
@ -204,7 +204,7 @@ async def run_command(
server = create_mcp_config_server(config_path) server = create_mcp_config_server(config_path)
else: else:
# It's a FastMCP config - load it properly # It's a FastMCP config - load it properly
config = load_fastmcp_config(config_path) config = load_mcp_server_config(config_path)
# Merge deployment config with CLI arguments (CLI takes precedence) # Merge deployment config with CLI arguments (CLI takes precedence)
transport = transport or config.deployment.transport transport = transport or config.deployment.transport
@ -232,9 +232,9 @@ async def run_command(
logger.debug(f'Found server "{server.name}" from config {config_path}') logger.debug(f'Found server "{server.name}" from config {config_path}')
else: else:
# Regular file case - create a FastMCPConfig with FileSystemSource # Regular file case - create a MCPServerConfig with FileSystemSource
source = FileSystemSource(path=server_spec) source = FileSystemSource(path=server_spec)
config = FastMCPConfig(source=source) config = MCPServerConfig(source=source)
# Prepare source only (environment is handled by uv run) # Prepare source only (environment is handled by uv run)
await config.prepare_source() if not skip_source else None await config.prepare_source() if not skip_source else None

View file

@ -36,8 +36,8 @@ from fastmcp.client.auth.oauth import OAuth
from fastmcp.mcp_config import MCPConfig, infer_transport_type_from_url from fastmcp.mcp_config import MCPConfig, infer_transport_type_from_url
from fastmcp.server.dependencies import get_http_headers from fastmcp.server.dependencies import get_http_headers
from fastmcp.server.server import FastMCP from fastmcp.server.server import FastMCP
from fastmcp.utilities.fastmcp_config.v1.fastmcp_config import Environment
from fastmcp.utilities.logging import get_logger from fastmcp.utilities.logging import get_logger
from fastmcp.utilities.mcp_server_config.v1.mcp_server_config import Environment
logger = get_logger(__name__) logger = get_logger(__name__)

View file

@ -14,9 +14,9 @@ from rich.table import Table
from rich.text import Text from rich.text import Text
import fastmcp import fastmcp
from fastmcp.utilities.fastmcp_config import FastMCPConfig
from fastmcp.utilities.fastmcp_config.v1.sources.filesystem import FileSystemSource
from fastmcp.utilities.logging import get_logger from fastmcp.utilities.logging import get_logger
from fastmcp.utilities.mcp_server_config import MCPServerConfig
from fastmcp.utilities.mcp_server_config.v1.sources.filesystem import FileSystemSource
from fastmcp.utilities.types import get_cached_typeadapter from fastmcp.utilities.types import get_cached_typeadapter
if TYPE_CHECKING: if TYPE_CHECKING:
@ -33,7 +33,7 @@ def is_already_in_uv_subprocess() -> bool:
def load_and_merge_config( def load_and_merge_config(
server_spec: str | None, server_spec: str | None,
**cli_overrides, **cli_overrides,
) -> tuple[FastMCPConfig, str]: ) -> tuple[MCPServerConfig, str]:
"""Load config from server_spec and apply CLI overrides. """Load config from server_spec and apply CLI overrides.
This consolidates the config parsing logic that was duplicated across This consolidates the config parsing logic that was duplicated across
@ -44,7 +44,7 @@ def load_and_merge_config(
cli_overrides: CLI arguments that override config values cli_overrides: CLI arguments that override config values
Returns: Returns:
Tuple of (FastMCPConfig, resolved_server_spec) Tuple of (MCPServerConfig, resolved_server_spec)
""" """
config = None config = None
config_path = None config_path = None
@ -53,7 +53,7 @@ def load_and_merge_config(
if server_spec is None: if server_spec is None:
config_path = Path("fastmcp.json") config_path = Path("fastmcp.json")
if not config_path.exists(): if not config_path.exists():
found_config = FastMCPConfig.find_config() found_config = MCPServerConfig.find_config()
if found_config: if found_config:
config_path = found_config config_path = found_config
else: else:
@ -81,9 +81,9 @@ def load_and_merge_config(
# MCPConfig - we don't process these here, just pass through # MCPConfig - we don't process these here, just pass through
pass pass
else: else:
# Try to parse as FastMCPConfig # Try to parse as MCPServerConfig
try: try:
adapter = get_cached_typeadapter(FastMCPConfig) adapter = get_cached_typeadapter(MCPServerConfig)
config = adapter.validate_python(data) config = adapter.validate_python(data)
# Apply deployment settings # Apply deployment settings
@ -91,7 +91,7 @@ def load_and_merge_config(
config.deployment.apply_runtime_settings(config_path) config.deployment.apply_runtime_settings(config_path)
except ValidationError: except ValidationError:
# Not a valid FastMCPConfig, just pass through # Not a valid MCPServerConfig, just pass through
pass pass
except (json.JSONDecodeError, FileNotFoundError): except (json.JSONDecodeError, FileNotFoundError):
# Not a valid JSON file, just pass through # Not a valid JSON file, just pass through
@ -100,7 +100,7 @@ def load_and_merge_config(
# If we don't have a config object yet, create one from filesystem source # If we don't have a config object yet, create one from filesystem source
if config is None: if config is None:
source = FileSystemSource(path=resolved_spec) source = FileSystemSource(path=resolved_spec)
config = FastMCPConfig(source=source) config = MCPServerConfig(source=source)
# Convert to dict for immutable transformation # Convert to dict for immutable transformation
config_dict = config.model_dump() config_dict = config.model_dump()
@ -134,7 +134,7 @@ def load_and_merge_config(
config_dict["deployment"]["args"] = server_args_override config_dict["deployment"]["args"] = server_args_override
# Create new config from modified dict # Create new config from modified dict
new_config = FastMCPConfig(**config_dict) new_config = MCPServerConfig(**config_dict)
return new_config, resolved_spec return new_config, resolved_spec

View file

@ -4,20 +4,20 @@ This module provides versioned configuration support for FastMCP servers.
The current version is v1, which is re-exported here for convenience. The current version is v1, which is re-exported here for convenience.
""" """
from fastmcp.utilities.fastmcp_config.v1.fastmcp_config import ( from fastmcp.utilities.mcp_server_config.v1.mcp_server_config import (
Deployment, Deployment,
Environment, Environment,
FastMCPConfig, MCPServerConfig,
generate_schema, generate_schema,
) )
from fastmcp.utilities.fastmcp_config.v1.sources.base import BaseSource from fastmcp.utilities.mcp_server_config.v1.sources.base import BaseSource
from fastmcp.utilities.fastmcp_config.v1.sources.filesystem import FileSystemSource from fastmcp.utilities.mcp_server_config.v1.sources.filesystem import FileSystemSource
__all__ = [ __all__ = [
"BaseSource", "BaseSource",
"Deployment", "Deployment",
"Environment", "Environment",
"FastMCPConfig", "MCPServerConfig",
"FileSystemSource", "FileSystemSource",
"generate_schema", "generate_schema",
] ]

View file

@ -17,8 +17,8 @@ from typing import TYPE_CHECKING, Any, Literal, overload
from pydantic import BaseModel, Field, field_validator from pydantic import BaseModel, Field, field_validator
from fastmcp.utilities.fastmcp_config.v1.sources.filesystem import FileSystemSource
from fastmcp.utilities.logging import get_logger from fastmcp.utilities.logging import get_logger
from fastmcp.utilities.mcp_server_config.v1.sources.filesystem import FileSystemSource
logger = get_logger("cli.config") logger = get_logger("cli.config")
@ -406,7 +406,7 @@ class Deployment(BaseModel):
return re.sub(r"\$\{([^}]+)\}", replace_var, value) return re.sub(r"\$\{([^}]+)\}", replace_var, value)
class FastMCPConfig(BaseModel): class MCPServerConfig(BaseModel):
"""Configuration for a FastMCP server. """Configuration for a FastMCP server.
This configuration file allows you to specify all settings needed to run This configuration file allows you to specify all settings needed to run
@ -463,7 +463,7 @@ class FastMCPConfig(BaseModel):
- FileSystemSource instance (passed through) - FileSystemSource instance (passed through)
No string parsing happens here - that's only at CLI boundaries. No string parsing happens here - that's only at CLI boundaries.
FastMCPConfig works only with properly typed objects. MCPServerConfig works only with properly typed objects.
""" """
if isinstance(v, FileSystemSource): if isinstance(v, FileSystemSource):
# Already a FileSystemSource instance, return as-is # Already a FileSystemSource instance, return as-is
@ -510,14 +510,14 @@ class FastMCPConfig(BaseModel):
raise ValueError("deployment must be a dict, Deployment instance") raise ValueError("deployment must be a dict, Deployment instance")
@classmethod @classmethod
def from_file(cls, file_path: Path) -> FastMCPConfig: def from_file(cls, file_path: Path) -> MCPServerConfig:
"""Load configuration from a JSON file. """Load configuration from a JSON file.
Args: Args:
file_path: Path to the configuration file file_path: Path to the configuration file
Returns: Returns:
FastMCPConfig instance MCPServerConfig instance
Raises: Raises:
FileNotFoundError: If the file doesn't exist FileNotFoundError: If the file doesn't exist
@ -550,7 +550,7 @@ class FastMCPConfig(BaseModel):
env: dict[str, str] | None = None, env: dict[str, str] | None = None,
cwd: str | None = None, cwd: str | None = None,
args: list[str] | None = None, args: list[str] | None = None,
) -> FastMCPConfig: ) -> MCPServerConfig:
"""Create a config from CLI arguments. """Create a config from CLI arguments.
This allows us to have a single code path where everything This allows us to have a single code path where everything
@ -573,7 +573,7 @@ class FastMCPConfig(BaseModel):
args: Server arguments args: Server arguments
Returns: Returns:
FastMCPConfig instance MCPServerConfig instance
""" """
# Build environment config if any env args provided # Build environment config if any env args provided
environment = None environment = None
@ -716,7 +716,7 @@ def generate_schema(output_path: Path | str | None = None) -> dict[str, Any] | N
Returns: Returns:
JSON schema as a dictionary if output_path is None, otherwise None JSON schema as a dictionary if output_path is None, otherwise None
""" """
schema = FastMCPConfig.model_json_schema() schema = MCPServerConfig.model_json_schema()
# Add some metadata # Add some metadata
schema["$id"] = FASTMCP_JSON_SCHEMA schema["$id"] = FASTMCP_JSON_SCHEMA

View file

@ -6,8 +6,8 @@ from typing import Any, Literal
from pydantic import Field, field_validator from pydantic import Field, field_validator
from fastmcp.utilities.fastmcp_config.v1.sources.base import BaseSource
from fastmcp.utilities.logging import get_logger from fastmcp.utilities.logging import get_logger
from fastmcp.utilities.mcp_server_config.v1.sources.base import BaseSource
logger = get_logger(__name__) logger = get_logger(__name__)

View file

@ -458,7 +458,7 @@ class TestWindowsSpecific:
"""Test parsing Windows paths with drive letters and colons.""" """Test parsing Windows paths with drive letters and colons."""
from pathlib import Path from pathlib import Path
from fastmcp.utilities.fastmcp_config.v1.sources.filesystem import ( from fastmcp.utilities.mcp_server_config.v1.sources.filesystem import (
FileSystemSource, FileSystemSource,
) )

View file

@ -7,12 +7,12 @@ from pathlib import Path
import pytest import pytest
from pydantic import ValidationError from pydantic import ValidationError
from fastmcp.utilities.fastmcp_config import ( from fastmcp.utilities.mcp_server_config import (
Deployment, Deployment,
Environment, Environment,
FastMCPConfig, MCPServerConfig,
) )
from fastmcp.utilities.fastmcp_config.v1.sources.filesystem import FileSystemSource from fastmcp.utilities.mcp_server_config.v1.sources.filesystem import FileSystemSource
class TestFileSystemSource: class TestFileSystemSource:
@ -20,7 +20,7 @@ class TestFileSystemSource:
def test_dict_source_minimal(self): def test_dict_source_minimal(self):
"""Test that dict source is converted to FileSystemSource.""" """Test that dict source is converted to FileSystemSource."""
config = FastMCPConfig(source={"path": "server.py"}) config = MCPServerConfig(source={"path": "server.py"})
# Dict is converted to FileSystemSource # Dict is converted to FileSystemSource
assert isinstance(config.source, FileSystemSource) assert isinstance(config.source, FileSystemSource)
assert config.source.path == "server.py" assert config.source.path == "server.py"
@ -29,7 +29,7 @@ class TestFileSystemSource:
def test_dict_source_with_entrypoint(self): def test_dict_source_with_entrypoint(self):
"""Test dict source with entrypoint field.""" """Test dict source with entrypoint field."""
config = FastMCPConfig(source={"path": "server.py", "entrypoint": "app"}) config = MCPServerConfig(source={"path": "server.py", "entrypoint": "app"})
# Dict with entrypoint is converted to FileSystemSource # Dict with entrypoint is converted to FileSystemSource
assert isinstance(config.source, FileSystemSource) assert isinstance(config.source, FileSystemSource)
assert config.source.path == "server.py" assert config.source.path == "server.py"
@ -38,7 +38,7 @@ class TestFileSystemSource:
def test_filesystem_source_entrypoint(self): def test_filesystem_source_entrypoint(self):
"""Test FileSystemSource entrypoint format.""" """Test FileSystemSource entrypoint format."""
config = FastMCPConfig( config = MCPServerConfig(
source=FileSystemSource(path="src/server.py", entrypoint="mcp") source=FileSystemSource(path="src/server.py", entrypoint="mcp")
) )
assert isinstance(config.source, FileSystemSource) assert isinstance(config.source, FileSystemSource)
@ -52,7 +52,7 @@ class TestEnvironment:
def test_environment_config_fields(self): def test_environment_config_fields(self):
"""Test all Environment fields.""" """Test all Environment fields."""
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
environment={ environment={
"python": "3.12", "python": "3.12",
@ -73,28 +73,28 @@ class TestEnvironment:
def test_needs_uv(self): def test_needs_uv(self):
"""Test needs_uv() method.""" """Test needs_uv() method."""
# No environment config - doesn't need UV # No environment config - doesn't need UV
config = FastMCPConfig(source={"path": "server.py"}) config = MCPServerConfig(source={"path": "server.py"})
assert not config.environment.needs_uv() assert not config.environment.needs_uv()
# Empty environment - doesn't need UV # Empty environment - doesn't need UV
config = FastMCPConfig(source={"path": "server.py"}, environment={}) config = MCPServerConfig(source={"path": "server.py"}, environment={})
assert not config.environment.needs_uv() assert not config.environment.needs_uv()
# With dependencies - needs UV # With dependencies - needs UV
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, environment={"dependencies": ["requests"]} source={"path": "server.py"}, environment={"dependencies": ["requests"]}
) )
assert config.environment.needs_uv() assert config.environment.needs_uv()
# With Python version - needs UV # With Python version - needs UV
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, environment={"python": "3.12"} source={"path": "server.py"}, environment={"python": "3.12"}
) )
assert config.environment.needs_uv() assert config.environment.needs_uv()
def test_build_uv_run_command(self): def test_build_uv_run_command(self):
"""Test build_uv_run_command() method.""" """Test build_uv_run_command() method."""
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
environment={ environment={
"python": "3.12", "python": "3.12",
@ -125,7 +125,7 @@ class TestEnvironment:
def test_run_with_uv(self): def test_run_with_uv(self):
"""Test run_with_uv() subprocess execution.""" """Test run_with_uv() subprocess execution."""
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, environment={"dependencies": ["requests"]} source={"path": "server.py"}, environment={"dependencies": ["requests"]}
) )
@ -144,7 +144,7 @@ class TestDeployment:
def test_deployment_config_fields(self): def test_deployment_config_fields(self):
"""Test all Deployment fields.""" """Test all Deployment fields."""
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
deployment={ deployment={
"transport": "http", "transport": "http",
@ -176,7 +176,7 @@ class TestDeployment:
work_dir = tmp_path / "work" work_dir = tmp_path / "work"
work_dir.mkdir() work_dir.mkdir()
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
deployment={ deployment={
"env": {"TEST_VAR": "test_value"}, "env": {"TEST_VAR": "test_value"},
@ -212,7 +212,7 @@ class TestDeployment:
os.environ["BASE_URL"] = "example.com" os.environ["BASE_URL"] = "example.com"
os.environ["ENV_NAME"] = "production" os.environ["ENV_NAME"] = "production"
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
deployment={ deployment={
"env": { "env": {
@ -253,12 +253,12 @@ class TestDeployment:
os.environ[key] = value os.environ[key] = value
class TestFastMCPConfig: class TestMCPServerConfig:
"""Test FastMCPConfig root configuration.""" """Test MCPServerConfig root configuration."""
def test_minimal_config(self): def test_minimal_config(self):
"""Test creating a config with only required fields.""" """Test creating a config with only required fields."""
config = FastMCPConfig(source={"path": "server.py"}) config = MCPServerConfig(source={"path": "server.py"})
assert isinstance(config.source, FileSystemSource) assert isinstance(config.source, FileSystemSource)
assert config.source.path == "server.py" assert config.source.path == "server.py"
assert config.source.entrypoint is None assert config.source.entrypoint is None
@ -274,7 +274,7 @@ class TestFastMCPConfig:
def test_nested_structure(self): def test_nested_structure(self):
"""Test the nested configuration structure.""" """Test the nested configuration structure."""
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
environment={ environment={
"python": "3.12", "python": "3.12",
@ -304,7 +304,7 @@ class TestFastMCPConfig:
config_file = tmp_path / "fastmcp.json" config_file = tmp_path / "fastmcp.json"
config_file.write_text(json.dumps(config_data)) config_file.write_text(json.dumps(config_data))
config = FastMCPConfig.from_file(config_file) config = MCPServerConfig.from_file(config_file)
# When loaded from JSON with entrypoint format, it becomes EntrypointConfig # When loaded from JSON with entrypoint format, it becomes EntrypointConfig
assert isinstance(config.source, FileSystemSource) assert isinstance(config.source, FileSystemSource)
@ -325,7 +325,7 @@ class TestFastMCPConfig:
config_file = tmp_path / "fastmcp.json" config_file = tmp_path / "fastmcp.json"
config_file.write_text(json.dumps(config_data)) config_file.write_text(json.dumps(config_data))
config = FastMCPConfig.from_file(config_file) config = MCPServerConfig.from_file(config_file)
# String entrypoint with : should be converted to EntrypointConfig # String entrypoint with : should be converted to EntrypointConfig
assert isinstance(config.source, FileSystemSource) assert isinstance(config.source, FileSystemSource)
assert config.source.path == "server.py" assert config.source.path == "server.py"
@ -342,7 +342,7 @@ class TestFastMCPConfig:
config_file = tmp_path / "fastmcp.json" config_file = tmp_path / "fastmcp.json"
config_file.write_text(json.dumps(config_data)) config_file.write_text(json.dumps(config_data))
config = FastMCPConfig.from_file(config_file) config = MCPServerConfig.from_file(config_file)
# Should be parsed into EntrypointConfig # Should be parsed into EntrypointConfig
assert isinstance(config.source, FileSystemSource) assert isinstance(config.source, FileSystemSource)
@ -365,7 +365,7 @@ class TestFastMCPConfig:
original_cwd = os.getcwd() original_cwd = os.getcwd()
try: try:
os.chdir(tmp_path) os.chdir(tmp_path)
found = FastMCPConfig.find_config() found = MCPServerConfig.find_config()
assert found == config_file assert found == config_file
finally: finally:
os.chdir(original_cwd) os.chdir(original_cwd)
@ -379,7 +379,7 @@ class TestFastMCPConfig:
subdir.mkdir() subdir.mkdir()
# Should NOT find config in parent directory # Should NOT find config in parent directory
found = FastMCPConfig.find_config(subdir) found = MCPServerConfig.find_config(subdir)
assert found is None assert found is None
def test_find_config_in_specified_dir(self, tmp_path): def test_find_config_in_specified_dir(self, tmp_path):
@ -388,12 +388,12 @@ class TestFastMCPConfig:
config_file.write_text(json.dumps({"source": {"path": "server.py"}})) config_file.write_text(json.dumps({"source": {"path": "server.py"}}))
# Should find config when looking in the directory that contains it # Should find config when looking in the directory that contains it
found = FastMCPConfig.find_config(tmp_path) found = MCPServerConfig.find_config(tmp_path)
assert found == config_file assert found == config_file
def test_find_config_not_found(self, tmp_path): def test_find_config_not_found(self, tmp_path):
"""Test when config is not found.""" """Test when config is not found."""
found = FastMCPConfig.find_config(tmp_path) found = MCPServerConfig.find_config(tmp_path)
assert found is None assert found is None
def test_invalid_transport(self, tmp_path): def test_invalid_transport(self, tmp_path):
@ -407,12 +407,12 @@ class TestFastMCPConfig:
config_file.write_text(json.dumps(config_data)) config_file.write_text(json.dumps(config_data))
with pytest.raises(ValidationError): with pytest.raises(ValidationError):
FastMCPConfig.from_file(config_file) MCPServerConfig.from_file(config_file)
def test_optional_sections(self): def test_optional_sections(self):
"""Test that all config sections are optional except source.""" """Test that all config sections are optional except source."""
# Only source is required # Only source is required
config = FastMCPConfig(source={"path": "server.py"}) config = MCPServerConfig(source={"path": "server.py"})
assert isinstance(config.source, FileSystemSource) assert isinstance(config.source, FileSystemSource)
assert config.source.path == "server.py" assert config.source.path == "server.py"
# Environment and deployment are now always present but may be empty # Environment and deployment are now always present but may be empty
@ -420,7 +420,7 @@ class TestFastMCPConfig:
assert isinstance(config.deployment, Deployment) assert isinstance(config.deployment, Deployment)
# Only environment with values # Only environment with values
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, environment={"python": "3.12"} source={"path": "server.py"}, environment={"python": "3.12"}
) )
assert config.environment.python == "3.12" assert config.environment.python == "3.12"
@ -431,7 +431,7 @@ class TestFastMCPConfig:
) )
# Only deployment with values # Only deployment with values
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, deployment={"transport": "http"} source={"path": "server.py"}, deployment={"transport": "http"}
) )
assert isinstance(config.environment, Environment) assert isinstance(config.environment, Environment)

View file

@ -7,7 +7,7 @@ from pathlib import Path
import pytest import pytest
from fastmcp.client import Client from fastmcp.client import Client
from fastmcp.utilities.fastmcp_config import FastMCPConfig from fastmcp.utilities.mcp_server_config import MCPServerConfig
@pytest.fixture @pytest.fixture
@ -89,7 +89,7 @@ class TestConfigWithClient:
"""Test that a server loaded from config works with a client.""" """Test that a server loaded from config works with a client."""
# Load the config # Load the config
config_file = server_with_config / "fastmcp.json" config_file = server_with_config / "fastmcp.json"
config = FastMCPConfig.from_file(config_file) config = MCPServerConfig.from_file(config_file)
# Import the server using the source # Import the server using the source
import importlib.util import importlib.util
@ -132,7 +132,7 @@ class TestEnvironmentExecution:
def test_needs_uv_with_dependencies(self): def test_needs_uv_with_dependencies(self):
"""Test that environment with dependencies needs UV.""" """Test that environment with dependencies needs UV."""
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
environment={"dependencies": ["requests", "numpy"]}, # type: ignore[arg-type] environment={"dependencies": ["requests", "numpy"]}, # type: ignore[arg-type]
) )
@ -142,7 +142,7 @@ class TestEnvironmentExecution:
def test_needs_uv_with_python_version(self): def test_needs_uv_with_python_version(self):
"""Test that environment with Python version needs UV.""" """Test that environment with Python version needs UV."""
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
environment={"python": "3.12"}, # type: ignore[arg-type] environment={"python": "3.12"}, # type: ignore[arg-type]
) )
@ -152,7 +152,7 @@ class TestEnvironmentExecution:
def test_no_uv_needed_without_environment(self): def test_no_uv_needed_without_environment(self):
"""Test that no UV is needed without environment config.""" """Test that no UV is needed without environment config."""
config = FastMCPConfig(source={"path": "server.py"}) config = MCPServerConfig(source={"path": "server.py"})
# Environment is now always present but may be empty # Environment is now always present but may be empty
assert config.environment is not None assert config.environment is not None
@ -160,7 +160,7 @@ class TestEnvironmentExecution:
def test_no_uv_needed_with_empty_environment(self): def test_no_uv_needed_with_empty_environment(self):
"""Test that no UV is needed with empty environment config.""" """Test that no UV is needed with empty environment config."""
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
environment={}, # type: ignore[arg-type] environment={}, # type: ignore[arg-type]
) )
@ -184,7 +184,7 @@ class TestPathResolution:
server_file = src_dir / "server.py" server_file = src_dir / "server.py"
server_file.write_text("# Server") server_file.write_text("# Server")
config = FastMCPConfig(source={"path": "../src/server.py"}) config = MCPServerConfig(source={"path": "../src/server.py"})
# The source path is resolved during load_server # The source path is resolved during load_server
# For now, just check that the source is created correctly # For now, just check that the source is created correctly
@ -198,7 +198,7 @@ class TestPathResolution:
work_dir = tmp_path / "work" work_dir = tmp_path / "work"
work_dir.mkdir() work_dir.mkdir()
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
deployment={"cwd": "work"}, # type: ignore[arg-type] deployment={"cwd": "work"}, # type: ignore[arg-type]
) )
@ -222,7 +222,7 @@ class TestPathResolution:
reqs_file = tmp_path / "requirements.txt" reqs_file = tmp_path / "requirements.txt"
reqs_file.write_text("fastmcp>=2.0") reqs_file.write_text("fastmcp>=2.0")
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
environment={"requirements": "requirements.txt"}, # type: ignore[arg-type] environment={"requirements": "requirements.txt"}, # type: ignore[arg-type]
) )
@ -243,7 +243,7 @@ class TestConfigValidation:
def test_invalid_transport_rejected(self): def test_invalid_transport_rejected(self):
"""Test that invalid transport values are rejected.""" """Test that invalid transport values are rejected."""
with pytest.raises(ValueError): with pytest.raises(ValueError):
FastMCPConfig( MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
deployment={"transport": "invalid_transport"}, # type: ignore[arg-type] deployment={"transport": "invalid_transport"}, # type: ignore[arg-type]
) )
@ -251,7 +251,7 @@ class TestConfigValidation:
def test_streamable_http_transport_rejected(self): def test_streamable_http_transport_rejected(self):
"""Test that streamable-http transport is rejected in fastmcp.json config.""" """Test that streamable-http transport is rejected in fastmcp.json config."""
with pytest.raises(ValueError): with pytest.raises(ValueError):
FastMCPConfig( MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
deployment={"transport": "streamable-http"}, # type: ignore[arg-type] deployment={"transport": "streamable-http"}, # type: ignore[arg-type]
) )
@ -259,7 +259,7 @@ class TestConfigValidation:
def test_invalid_log_level_rejected(self): def test_invalid_log_level_rejected(self):
"""Test that invalid log level values are rejected.""" """Test that invalid log level values are rejected."""
with pytest.raises(ValueError): with pytest.raises(ValueError):
FastMCPConfig( MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
deployment={"log_level": "INVALID"}, # type: ignore[arg-type] deployment={"log_level": "INVALID"}, # type: ignore[arg-type]
) )
@ -267,12 +267,12 @@ class TestConfigValidation:
def test_missing_source_rejected(self): def test_missing_source_rejected(self):
"""Test that config without source is rejected.""" """Test that config without source is rejected."""
with pytest.raises(ValueError): with pytest.raises(ValueError):
FastMCPConfig() # type: ignore[call-arg] MCPServerConfig() # type: ignore[call-arg]
def test_valid_transport_values(self): def test_valid_transport_values(self):
"""Test that all valid transport values are accepted.""" """Test that all valid transport values are accepted."""
for transport in ["stdio", "http", "sse"]: for transport in ["stdio", "http", "sse"]:
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
deployment={"transport": transport}, # type: ignore[arg-type] deployment={"transport": transport}, # type: ignore[arg-type]
) )
@ -282,7 +282,7 @@ class TestConfigValidation:
def test_valid_log_levels(self): def test_valid_log_levels(self):
"""Test that all valid log levels are accepted.""" """Test that all valid log levels are accepted."""
for level in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]: for level in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]:
config = FastMCPConfig( config = MCPServerConfig(
source={"path": "server.py"}, source={"path": "server.py"},
deployment={"log_level": level}, # type: ignore[arg-type] deployment={"log_level": level}, # type: ignore[arg-type]
) )

View file

@ -3,7 +3,7 @@
import json import json
from pathlib import Path from pathlib import Path
from fastmcp.utilities.fastmcp_config.v1.fastmcp_config import generate_schema from fastmcp.utilities.mcp_server_config.v1.mcp_server_config import generate_schema
def test_schema_file_matches_pydantic_model(): def test_schema_file_matches_pydantic_model():
@ -14,7 +14,7 @@ def test_schema_file_matches_pydantic_model():
/ "src" / "src"
/ "fastmcp" / "fastmcp"
/ "utilities" / "utilities"
/ "fastmcp_config" / "mcp_server_config"
/ "v1" / "v1"
/ "schema.json" / "schema.json"
) )
@ -30,7 +30,7 @@ def test_schema_file_matches_pydantic_model():
assert file_schema == generated_schema, ( assert file_schema == generated_schema, (
"The schema.json file does not match the Pydantic model schema. " "The schema.json file does not match the Pydantic model schema. "
"Please regenerate the schema file by running:\n" "Please regenerate the schema file by running:\n"
'uv run python -c "from fastmcp.utilities.fastmcp_config.v1.fastmcp_config import generate_schema; ' 'uv run python -c "from fastmcp.utilities.mcp_server_config.v1.mcp_server_config import generate_schema; '
'import json; print(json.dumps(generate_schema(), indent=2))" > ' 'import json; print(json.dumps(generate_schema(), indent=2))" > '
f"{schema_file}" f"{schema_file}"
) )

View file

@ -6,24 +6,24 @@ from unittest.mock import AsyncMock, MagicMock, patch
import pytest import pytest
from fastmcp.utilities.fastmcp_config import Environment, FastMCPConfig from fastmcp.utilities.mcp_server_config import Environment, MCPServerConfig
from fastmcp.utilities.fastmcp_config.v1.sources.filesystem import FileSystemSource from fastmcp.utilities.mcp_server_config.v1.sources.filesystem import FileSystemSource
class TestFastMCPConfigPrepare: class TestMCPServerConfigPrepare:
"""Test the FastMCPConfig.prepare() method.""" """Test the MCPServerConfig.prepare() method."""
@patch( @patch(
"fastmcp.utilities.fastmcp_config.v1.fastmcp_config.FastMCPConfig.prepare_source", "fastmcp.utilities.mcp_server_config.v1.mcp_server_config.MCPServerConfig.prepare_source",
new_callable=AsyncMock, new_callable=AsyncMock,
) )
@patch( @patch(
"fastmcp.utilities.fastmcp_config.v1.fastmcp_config.FastMCPConfig.prepare_environment", "fastmcp.utilities.mcp_server_config.v1.mcp_server_config.MCPServerConfig.prepare_environment",
new_callable=AsyncMock, new_callable=AsyncMock,
) )
async def test_prepare_calls_both_methods(self, mock_env, mock_src): async def test_prepare_calls_both_methods(self, mock_env, mock_src):
"""Test that prepare() calls both prepare_environment and prepare_source.""" """Test that prepare() calls both prepare_environment and prepare_source."""
config = FastMCPConfig( config = MCPServerConfig(
source=FileSystemSource(path="server.py"), source=FileSystemSource(path="server.py"),
environment=Environment(python="3.10"), environment=Environment(python="3.10"),
) )
@ -34,16 +34,16 @@ class TestFastMCPConfigPrepare:
mock_src.assert_called_once() mock_src.assert_called_once()
@patch( @patch(
"fastmcp.utilities.fastmcp_config.v1.fastmcp_config.FastMCPConfig.prepare_source", "fastmcp.utilities.mcp_server_config.v1.mcp_server_config.MCPServerConfig.prepare_source",
new_callable=AsyncMock, new_callable=AsyncMock,
) )
@patch( @patch(
"fastmcp.utilities.fastmcp_config.v1.fastmcp_config.FastMCPConfig.prepare_environment", "fastmcp.utilities.mcp_server_config.v1.mcp_server_config.MCPServerConfig.prepare_environment",
new_callable=AsyncMock, new_callable=AsyncMock,
) )
async def test_prepare_with_output_dir(self, mock_env, mock_src): async def test_prepare_with_output_dir(self, mock_env, mock_src):
"""Test that prepare() with output_dir calls prepare_environment with it.""" """Test that prepare() with output_dir calls prepare_environment with it."""
config = FastMCPConfig( config = MCPServerConfig(
source=FileSystemSource(path="server.py"), source=FileSystemSource(path="server.py"),
environment=Environment(python="3.10"), environment=Environment(python="3.10"),
) )
@ -55,16 +55,16 @@ class TestFastMCPConfigPrepare:
mock_src.assert_called_once() mock_src.assert_called_once()
@patch( @patch(
"fastmcp.utilities.fastmcp_config.v1.fastmcp_config.FastMCPConfig.prepare_source", "fastmcp.utilities.mcp_server_config.v1.mcp_server_config.MCPServerConfig.prepare_source",
new_callable=AsyncMock, new_callable=AsyncMock,
) )
@patch( @patch(
"fastmcp.utilities.fastmcp_config.v1.fastmcp_config.FastMCPConfig.prepare_environment", "fastmcp.utilities.mcp_server_config.v1.mcp_server_config.MCPServerConfig.prepare_environment",
new_callable=AsyncMock, new_callable=AsyncMock,
) )
async def test_prepare_skip_source(self, mock_env, mock_src): async def test_prepare_skip_source(self, mock_env, mock_src):
"""Test that prepare() skips source when skip_source=True.""" """Test that prepare() skips source when skip_source=True."""
config = FastMCPConfig( config = MCPServerConfig(
source=FileSystemSource(path="server.py"), source=FileSystemSource(path="server.py"),
environment=Environment(python="3.10"), environment=Environment(python="3.10"),
) )
@ -75,16 +75,16 @@ class TestFastMCPConfigPrepare:
mock_src.assert_not_called() mock_src.assert_not_called()
@patch( @patch(
"fastmcp.utilities.fastmcp_config.v1.fastmcp_config.FastMCPConfig.prepare_source", "fastmcp.utilities.mcp_server_config.v1.mcp_server_config.MCPServerConfig.prepare_source",
new_callable=AsyncMock, new_callable=AsyncMock,
) )
@patch( @patch(
"fastmcp.utilities.fastmcp_config.v1.fastmcp_config.Environment.prepare", "fastmcp.utilities.mcp_server_config.v1.mcp_server_config.Environment.prepare",
new_callable=AsyncMock, new_callable=AsyncMock,
) )
async def test_prepare_no_environment_settings(self, mock_env_prepare, mock_src): async def test_prepare_no_environment_settings(self, mock_env_prepare, mock_src):
"""Test that prepare() works with default empty environment config.""" """Test that prepare() works with default empty environment config."""
config = FastMCPConfig( config = MCPServerConfig(
source=FileSystemSource(path="server.py"), source=FileSystemSource(path="server.py"),
# environment defaults to empty Environment() # environment defaults to empty Environment()
) )
@ -188,8 +188,8 @@ class TestEnvironmentPrepare:
class TestProjectPrepareCommand: class TestProjectPrepareCommand:
"""Test the CLI project prepare command.""" """Test the CLI project prepare command."""
@patch("fastmcp.utilities.fastmcp_config.FastMCPConfig.from_file") @patch("fastmcp.utilities.mcp_server_config.MCPServerConfig.from_file")
@patch("fastmcp.utilities.fastmcp_config.FastMCPConfig.find_config") @patch("fastmcp.utilities.mcp_server_config.MCPServerConfig.find_config")
async def test_project_prepare_auto_detect(self, mock_find, mock_from_file): async def test_project_prepare_auto_detect(self, mock_find, mock_from_file):
"""Test project prepare with auto-detected config.""" """Test project prepare with auto-detected config."""
from fastmcp.cli.cli import prepare from fastmcp.cli.cli import prepare
@ -220,7 +220,7 @@ class TestProjectPrepareCommand:
assert "Project prepared successfully" in success_call assert "Project prepared successfully" in success_call
@patch("pathlib.Path.exists") @patch("pathlib.Path.exists")
@patch("fastmcp.utilities.fastmcp_config.FastMCPConfig.from_file") @patch("fastmcp.utilities.mcp_server_config.MCPServerConfig.from_file")
async def test_project_prepare_explicit_path(self, mock_from_file, mock_exists): async def test_project_prepare_explicit_path(self, mock_from_file, mock_exists):
"""Test project prepare with explicit config path.""" """Test project prepare with explicit config path."""
from fastmcp.cli.cli import prepare from fastmcp.cli.cli import prepare
@ -243,7 +243,7 @@ class TestProjectPrepareCommand:
output_dir=Path("./test-env"), output_dir=Path("./test-env"),
) )
@patch("fastmcp.utilities.fastmcp_config.FastMCPConfig.find_config") @patch("fastmcp.utilities.mcp_server_config.MCPServerConfig.find_config")
async def test_project_prepare_no_config_found(self, mock_find): async def test_project_prepare_no_config_found(self, mock_find):
"""Test project prepare when no config is found.""" """Test project prepare when no config is found."""
from fastmcp.cli.cli import prepare from fastmcp.cli.cli import prepare
@ -280,7 +280,7 @@ class TestProjectPrepareCommand:
assert "--output-dir parameter is required" in error_msg assert "--output-dir parameter is required" in error_msg
@patch("pathlib.Path.exists") @patch("pathlib.Path.exists")
@patch("fastmcp.utilities.fastmcp_config.FastMCPConfig.from_file") @patch("fastmcp.utilities.mcp_server_config.MCPServerConfig.from_file")
async def test_project_prepare_failure(self, mock_from_file, mock_exists): async def test_project_prepare_failure(self, mock_from_file, mock_exists):
"""Test project prepare when prepare() fails.""" """Test project prepare when prepare() fails."""
from fastmcp.cli.cli import prepare from fastmcp.cli.cli import prepare

View file

@ -13,7 +13,7 @@ from fastmcp.client.client import Client
from fastmcp.client.transports import FastMCPTransport from fastmcp.client.transports import FastMCPTransport
from fastmcp.mcp_config import MCPConfig, StdioMCPServer from fastmcp.mcp_config import MCPConfig, StdioMCPServer
from fastmcp.server.server import FastMCP from fastmcp.server.server import FastMCP
from fastmcp.utilities.fastmcp_config.v1.sources.filesystem import FileSystemSource from fastmcp.utilities.mcp_server_config.v1.sources.filesystem import FileSystemSource
class TestUrlDetection: class TestUrlDetection:
@ -339,7 +339,7 @@ mcp = fastmcp.FastMCP("TestServer")
from unittest.mock import AsyncMock, patch from unittest.mock import AsyncMock, patch
from fastmcp.cli.run import run_command from fastmcp.cli.run import run_command
from fastmcp.utilities.fastmcp_config.v1.sources.filesystem import ( from fastmcp.utilities.mcp_server_config.v1.sources.filesystem import (
FileSystemSource, FileSystemSource,
) )
@ -368,7 +368,7 @@ mcp = fastmcp.FastMCP("TestServer")
from unittest.mock import AsyncMock, patch from unittest.mock import AsyncMock, patch
from fastmcp.cli.run import run_command from fastmcp.cli.run import run_command
from fastmcp.utilities.fastmcp_config.v1.sources.filesystem import ( from fastmcp.utilities.mcp_server_config.v1.sources.filesystem import (
FileSystemSource, FileSystemSource,
) )

View file

@ -6,13 +6,13 @@ from pathlib import Path
import pytest import pytest
from fastmcp.cli.run import load_fastmcp_config from fastmcp.cli.run import load_mcp_server_config
from fastmcp.utilities.fastmcp_config import ( from fastmcp.utilities.mcp_server_config import (
Deployment, Deployment,
Environment, Environment,
FastMCPConfig, MCPServerConfig,
) )
from fastmcp.utilities.fastmcp_config.v1.sources.filesystem import FileSystemSource from fastmcp.utilities.mcp_server_config.v1.sources.filesystem import FileSystemSource
@pytest.fixture @pytest.fixture
@ -43,17 +43,17 @@ def test_tool(message: str) -> str:
return config_file return config_file
def test_load_fastmcp_config(sample_config, monkeypatch): def test_load_mcp_server_config(sample_config, monkeypatch):
"""Test loading configuration and returning config subsets.""" """Test loading configuration and returning config subsets."""
# Capture environment changes # Capture environment changes
original_env = dict(os.environ) original_env = dict(os.environ)
try: try:
config = load_fastmcp_config(sample_config) config = load_mcp_server_config(sample_config)
# Check that we got the right types # Check that we got the right types
assert isinstance(config, FastMCPConfig) assert isinstance(config, MCPServerConfig)
assert isinstance(config.source, FileSystemSource) assert isinstance(config.source, FileSystemSource)
assert isinstance(config.deployment, Deployment) assert isinstance(config.deployment, Deployment)
assert isinstance(config.environment, Environment) assert isinstance(config.environment, Environment)
@ -95,7 +95,7 @@ def test_load_config_with_entrypoint_source(tmp_path):
server_file = src_dir / "server.py" server_file = src_dir / "server.py"
server_file.write_text("# Server") server_file.write_text("# Server")
config = load_fastmcp_config(config_file) config = load_mcp_server_config(config_file)
# Check source - path is not resolved yet, only during load_server # Check source - path is not resolved yet, only during load_server
assert config.source.path == "src/server.py" assert config.source.path == "src/server.py"
@ -125,7 +125,7 @@ def test_load_config_with_cwd(tmp_path):
original_cwd = os.getcwd() original_cwd = os.getcwd()
try: try:
config = load_fastmcp_config(config_file) # noqa: F841 config = load_mcp_server_config(config_file) # noqa: F841
# Check that working directory was changed # Check that working directory was changed
assert Path.cwd() == subdir.resolve() assert Path.cwd() == subdir.resolve()
@ -160,7 +160,7 @@ def test_load_config_with_relative_cwd(tmp_path):
original_cwd = os.getcwd() original_cwd = os.getcwd()
try: try:
config = load_fastmcp_config(config_file) # noqa: F841 config = load_mcp_server_config(config_file) # noqa: F841
# Should change to parent directory of config file # Should change to parent directory of config file
assert Path.cwd() == subdir1.resolve() assert Path.cwd() == subdir1.resolve()
@ -180,7 +180,7 @@ def test_load_minimal_config(tmp_path):
server_file = tmp_path / "server.py" server_file = tmp_path / "server.py"
server_file.write_text("# Server") server_file.write_text("# Server")
config = load_fastmcp_config(config_file) config = load_mcp_server_config(config_file)
# Check we got source - path is not resolved yet, only during load_server # Check we got source - path is not resolved yet, only during load_server
assert isinstance(config.source, FileSystemSource) assert isinstance(config.source, FileSystemSource)
@ -201,7 +201,7 @@ def test_load_config_with_server_args(tmp_path):
server_file = tmp_path / "server.py" server_file = tmp_path / "server.py"
server_file.write_text("# Server") server_file.write_text("# Server")
config = load_fastmcp_config(config_file) config = load_mcp_server_config(config_file)
assert config.deployment.args == ["--debug", "--config", "custom.json"] assert config.deployment.args == ["--debug", "--config", "custom.json"]
@ -221,7 +221,7 @@ def test_config_subset_independence(tmp_path):
server_file = tmp_path / "server.py" server_file = tmp_path / "server.py"
server_file.write_text("# Server") server_file.write_text("# Server")
config = load_fastmcp_config(config_file) config = load_mcp_server_config(config_file)
# Each subset should be independently usable # Each subset should be independently usable
# Path is not resolved yet, only during load_server # Path is not resolved yet, only during load_server
@ -259,7 +259,7 @@ def test_environment_config_path_resolution(tmp_path):
server_file = tmp_path / "server.py" server_file = tmp_path / "server.py"
server_file.write_text("# Server") server_file.write_text("# Server")
config = load_fastmcp_config(config_file) config = load_mcp_server_config(config_file)
# Check that UV command is built with resolved paths # Check that UV command is built with resolved paths
uv_cmd = config.environment.build_uv_run_command(["fastmcp", "run", "server.py"]) uv_cmd = config.environment.build_uv_run_command(["fastmcp", "run", "server.py"])

View file

@ -4,8 +4,8 @@ from pathlib import Path
import pytest import pytest
from fastmcp.utilities.fastmcp_config import FastMCPConfig from fastmcp.utilities.mcp_server_config import MCPServerConfig
from fastmcp.utilities.fastmcp_config.v1.sources.filesystem import FileSystemSource from fastmcp.utilities.mcp_server_config.v1.sources.filesystem import FileSystemSource
class TestServerArguments: class TestServerArguments:
@ -39,7 +39,7 @@ def get_config() -> dict:
# Test with arguments # Test with arguments
source = FileSystemSource(path=str(server_file)) source = FileSystemSource(path=str(server_file))
config = FastMCPConfig(source=source) config = MCPServerConfig(source=source)
from fastmcp.cli.cli import with_argv from fastmcp.cli.cli import with_argv
@ -69,7 +69,7 @@ mcp = FastMCP(args.name)
""") """)
source = FileSystemSource(path=str(server_file)) source = FileSystemSource(path=str(server_file))
config = FastMCPConfig(source=source) config = MCPServerConfig(source=source)
from fastmcp.cli.cli import with_argv from fastmcp.cli.cli import with_argv
@ -96,7 +96,7 @@ mcp = FastMCP(name)
""") """)
source = FileSystemSource(path=str(server_file)) source = FileSystemSource(path=str(server_file))
config = FastMCPConfig(source=source) config = MCPServerConfig(source=source)
from fastmcp.cli.cli import with_argv from fastmcp.cli.cli import with_argv
@ -123,7 +123,7 @@ mcp = FastMCP(name)
pytest.skip("config_server.py example not found") pytest.skip("config_server.py example not found")
source = FileSystemSource(path=str(config_server)) source = FileSystemSource(path=str(config_server))
config = FastMCPConfig(source=source) config = MCPServerConfig(source=source)
from fastmcp.cli.cli import with_argv from fastmcp.cli.cli import with_argv

View file

@ -1,6 +1,6 @@
"""Tests for CLI utility functions.""" """Tests for CLI utility functions."""
from fastmcp.utilities.fastmcp_config.v1.fastmcp_config import Environment from fastmcp.utilities.mcp_server_config.v1.mcp_server_config import Environment
class TestEnvironmentBuildUVRunCommand: class TestEnvironmentBuildUVRunCommand: