diff --git a/docs/deployment/fastmcp-cloud.mdx b/docs/deployment/fastmcp-cloud.mdx index 02ad5bae8..f806e1386 100644 --- a/docs/deployment/fastmcp-cloud.mdx +++ b/docs/deployment/fastmcp-cloud.mdx @@ -10,20 +10,51 @@ tag: NEW FastMCP Cloud is a young product and we welcome your feedback. Please join our [Discord](https://discord.com/invite/aGsSC3yDF4) to share your thoughts and ideas, and you can expect to see new features and improvements every week. + + +FastMCP Cloud supports both **FastMCP 2.0** servers and also **FastMCP 1.0** servers that were created with the official MCP Python SDK. + + FastMCP Cloud is completely free while in beta! +## Prerequisites + +To use FastMCP Cloud, you'll need a [GitHub](https://github.com) account. In addition, you'll need a GitHub repo that contains a FastMCP server instance. If you don't want to create one yet, you can proceed to [step 1](#step-1-create-a-project) and use the FastMCP Cloud quickstart repo. + +Your repo can be public or private, but must include at least a Python file that contains a FastMCP server instance. + +To ensure your file is compatible with FastMCP Cloud, you can run `fastmcp inspect ` to see what FastMCP Cloud will see when it runs your server. + + +If you have a `requirements.txt` or `pyproject.toml` in the repo, FastMCP Cloud will automatically detect your server's dependencies and install them for you. Note that your file *can* have an `if __name__ == "__main__"` block, but it will be ignored by FastMCP Cloud. + +For example, a minimal server file might look like: + +```python +from fastmcp import FastMCP + +mcp = FastMCP("MyServer") + +@mcp.tool +def hello(name: str) -> str: + return f"Hello, {name}!" +``` + ## Getting Started -Deploying to FastMCP Cloud takes just three simple steps. +There are just three steps to deploying a server to FastMCP Cloud: ### Step 1: Create a Project -Visit [fastmcp.cloud](https://fastmcp.cloud) and sign in with your GitHub account. Create a project either by selecting an existing repository or using the FastMCP Cloud quickstart repo. +Visit [fastmcp.cloud](https://fastmcp.cloud) and sign in with your GitHub account. Then, create a project. Each project corresponds to a GitHub repo, and you can create one from either your own repo or using the FastMCP Cloud quickstart repo. + FastMCP Cloud Quickstart Screen -### Step 2: Configure Your Server +Next, you'll be prompted to configure your project. + +FastMCP Cloud Configuration Screen The configuration screen lets you specify: - **Name**: The name of your project. This will be used to generate a unique URL for your server. @@ -32,31 +63,27 @@ The configuration screen lets you specify: Note that FastMCP Cloud will automatically detect yours server's Python dependencies from either a `requirements.txt` or `pyproject.toml` file. -FastMCP Cloud Configuration Screen +### Step 2: Deploy Your Server -### Step 3: Deploy - -Once you create your project, FastMCP Cloud will: -1. Create the repository (if using quickstart) +Once you configure your project, FastMCP Cloud will: +1. Clone the repository 2. Build your FastMCP server 3. Deploy it to a unique URL 4. Make it immediately available for connections FastMCP Cloud Deployment Screen +FastMCP Cloud will monitor your repo and redeploy your server whenever you push a change to the `main` branch. In addition, FastMCP Cloud will build and deploy servers for every PR your open, hosting them on unique URLs, so you can test changes before updating your production server. -## Connect to Your Server +### Step 3: Connect to Your Server -Your deployed server will be accessible at a URL like: +Once your server is deployed, it will be accessible at a URL like: ``` https://your-project-name.fastmcp.app/mcp ``` -You should be able to connect to it as soon as you see the deployment succeed! In addition, you can instantly connect your server to a variety of popular LLM clients: +You should be able to connect to it as soon as you see the deployment succeed! FastMCP Cloud provides instant connection options for popular LLM clients: FastMCP Cloud Connection Screen -## Testing Changes - -Any time you open a PR to your connected repo, FastMCP Cloud will create a new server for that branch and deploy it on a unique URL. This allows you to test your changes before merging to production. Each merge to main will trigger a new deployment of the "production" version of your server. \ No newline at end of file diff --git a/docs/docs.json b/docs/docs.json index 6101649c7..22412156b 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -122,7 +122,10 @@ { "group": "Essentials", "icon": "cube", - "pages": ["clients/client", "clients/transports"] + "pages": [ + "clients/client", + "clients/transports" + ] }, { "group": "Core Operations", @@ -148,7 +151,10 @@ { "group": "Authentication", "icon": "user-shield", - "pages": ["clients/auth/oauth", "clients/auth/bearer"] + "pages": [ + "clients/auth/oauth", + "clients/auth/bearer" + ] } ] }, @@ -194,12 +200,17 @@ }, { "anchor": "What's New", - "pages": ["updates", "changelog"] + "pages": [ + "updates", + "changelog" + ] }, { "anchor": "Community", "icon": "users", - "pages": ["community/showcase"] + "pages": [ + "community/showcase" + ] } ] }, diff --git a/docs/python-sdk/fastmcp-client-auth-oauth.mdx b/docs/python-sdk/fastmcp-client-auth-oauth.mdx index a009f9319..30c063b93 100644 --- a/docs/python-sdk/fastmcp-client-auth-oauth.mdx +++ b/docs/python-sdk/fastmcp-client-auth-oauth.mdx @@ -7,13 +7,13 @@ sidebarTitle: oauth ## Functions -### `default_cache_dir` +### `default_cache_dir` ```python default_cache_dir() -> Path ``` -### `check_if_auth_required` +### `check_if_auth_required` ```python check_if_auth_required(mcp_url: str, httpx_kwargs: dict[str, Any] | None = None) -> bool @@ -28,7 +28,7 @@ Check if the MCP endpoint requires authentication by making a test request. ## Classes -### `FileTokenStorage` +### `FileTokenStorage` File-based token storage implementation for OAuth credentials and tokens. @@ -39,7 +39,7 @@ Each instance is tied to a specific server URL for proper token isolation. **Methods:** -#### `get_base_url` +#### `get_base_url` ```python get_base_url(url: str) -> str @@ -48,7 +48,7 @@ get_base_url(url: str) -> str Extract the base URL (scheme + host) from a URL. -#### `get_cache_key` +#### `get_cache_key` ```python get_cache_key(self) -> str @@ -57,7 +57,7 @@ get_cache_key(self) -> str Generate a safe filesystem key from the server's base URL. -#### `get_tokens` +#### `get_tokens` ```python get_tokens(self) -> OAuthToken | None @@ -66,7 +66,7 @@ get_tokens(self) -> OAuthToken | None Load tokens from file storage. -#### `set_tokens` +#### `set_tokens` ```python set_tokens(self, tokens: OAuthToken) -> None @@ -75,7 +75,7 @@ set_tokens(self, tokens: OAuthToken) -> None Save tokens to file storage. -#### `get_client_info` +#### `get_client_info` ```python get_client_info(self) -> OAuthClientInformationFull | None @@ -84,7 +84,7 @@ get_client_info(self) -> OAuthClientInformationFull | None Load client information from file storage. -#### `set_client_info` +#### `set_client_info` ```python set_client_info(self, client_info: OAuthClientInformationFull) -> None @@ -93,7 +93,7 @@ set_client_info(self, client_info: OAuthClientInformationFull) -> None Save client information to file storage. -#### `clear` +#### `clear` ```python clear(self) -> None @@ -102,7 +102,7 @@ clear(self) -> None Clear all cached data for this server. -#### `clear_all` +#### `clear_all` ```python clear_all(cls, cache_dir: Path | None = None) -> None @@ -111,7 +111,7 @@ clear_all(cls, cache_dir: Path | None = None) -> None Clear all cached data for all servers. -### `OAuth` +### `OAuth` OAuth client provider for MCP servers with browser-based authentication. @@ -122,7 +122,7 @@ a browser for user authorization and running a local callback server. **Methods:** -#### `redirect_handler` +#### `redirect_handler` ```python redirect_handler(self, authorization_url: str) -> None @@ -131,7 +131,7 @@ redirect_handler(self, authorization_url: str) -> None Open browser for authorization. -#### `callback_handler` +#### `callback_handler` ```python callback_handler(self) -> tuple[str, str | None] diff --git a/src/fastmcp/client/auth/oauth.py b/src/fastmcp/client/auth/oauth.py index 06f71253e..f2418417a 100644 --- a/src/fastmcp/client/auth/oauth.py +++ b/src/fastmcp/client/auth/oauth.py @@ -3,6 +3,7 @@ from __future__ import annotations import asyncio import json import webbrowser +from asyncio import Future from pathlib import Path from typing import Any, Literal from urllib.parse import urlparse @@ -18,6 +19,7 @@ from mcp.shared.auth import ( OAuthToken as OAuthToken, ) from pydantic import AnyHttpUrl, ValidationError +from uvicorn.server import Server from fastmcp import settings as fastmcp_global_settings from fastmcp.client.oauth_callback import ( @@ -253,10 +255,10 @@ class OAuth(OAuthClientProvider): async def callback_handler(self) -> tuple[str, str | None]: """Handle OAuth callback and return (auth_code, state).""" # Create a future to capture the OAuth response - response_future = asyncio.get_running_loop().create_future() + response_future: Future[Any] = asyncio.get_running_loop().create_future() # Create server with the future - server = create_oauth_callback_server( + server: Server = create_oauth_callback_server( port=self.redirect_port, server_url=self.server_base_url, response_future=response_future, @@ -280,3 +282,5 @@ class OAuth(OAuthClientProvider): server.should_exit = True await asyncio.sleep(0.1) # Allow server to shutdown gracefully tg.cancel_scope.cancel() + + raise RuntimeError("OAuth callback handler could not be started")