Jeremiah Lowin commited on
Commit
cc899d9
·
unverified ·
1 Parent(s): abc4a6d

Update deployment docs (#1486)

Browse files
docs/assets/images/fastmcp_cloud/create_project.png ADDED

Git LFS Details

  • SHA256: 5a301fd3313fdf51257d1fc361502082776030aa8855f0e3189f8f53bd784502
  • Pointer size: 131 Bytes
  • Size of remote file: 636 kB
docs/assets/images/fastmcp_cloud/deployment.png ADDED

Git LFS Details

  • SHA256: 42babadcbcf60d81674833235ba69b2a151e37a3a3aeff0ed8b42ced5c7c8b90
  • Pointer size: 131 Bytes
  • Size of remote file: 692 kB
docs/assets/images/fastmcp_cloud/quickstart.png ADDED

Git LFS Details

  • SHA256: 7b9f272d32595572d94b6c8b0c2b862975867c3c4bc6f7e3e5f9c1da7334c84b
  • Pointer size: 131 Bytes
  • Size of remote file: 619 kB
docs/deployment/fastmcp-cloud.mdx ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: FastMCP Cloud
3
+ sidebarTitle: FastMCP Cloud
4
+ description: The fastest way to deploy your MCP server
5
+ icon: cloud
6
+ tag: NEW
7
+ ---
8
+
9
+ [FastMCP Cloud](https://fastmcp.cloud) is a managed platform for hosting MCP servers, built by the FastMCP team. While the FastMCP framework will always be fully open-source, we created FastMCP Cloud to solve the deployment challenges we've seen developers face. Our goal is to provide the absolute fastest way to make your MCP server available to LLM clients like Claude and Cursor.
10
+
11
+ 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.
12
+
13
+ <Tip>
14
+ FastMCP Cloud is completely free while in beta!
15
+ </Tip>
16
+
17
+ ## Getting Started
18
+
19
+ Deploying to FastMCP Cloud takes just three simple steps.
20
+
21
+ ### Step 1: Create a Project
22
+
23
+ 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.
24
+ <img src="/assets/images/fastmcp_cloud/quickstart.png" alt="FastMCP Cloud Quickstart Screen" />
25
+
26
+ ### Step 2: Configure your Server
27
+
28
+ The configuration screen lets you specify:
29
+ - **Name**: The name of your project. This will be used to generate a unique URL for your server.
30
+ - **Entrypoint**: The Python file containing your FastMCP server (e.g., `echo.py`). This field has the same syntax as the `fastmcp run` command, for example `echo.py:my_server` to specify a specific object in the file.
31
+ - **Authentication**: Whether to require OAuth for client connections.
32
+
33
+ <img src="/assets/images/fastmcp_cloud/create_project.png" alt="FastMCP Cloud Configuration Screen" />
34
+
35
+ ### Step 3: Deploy
36
+
37
+ Once you create your project, FastMCP Cloud will:
38
+ 1. Create the repository (if using quickstart)
39
+ 2. Build your FastMCP server
40
+ 3. Deploy it to a unique URL
41
+ 4. Make it immediately available for connections
42
+
43
+ <img src="/assets/images/fastmcp_cloud/deployment.png" alt="FastMCP Cloud Deployment Screen" />
44
+
45
+
46
+ The deployed server is live and accessible at a URL like:
47
+
48
+ ```
49
+ https://your-project-name.fastmcp.app/mcp
50
+ ```
51
+
52
+ You should be able to connect to it as soon as you see the deployment succeed!
53
+
54
+ Any time you open a PR to your repo, FastMCP Cloud will create a new, unique URL for that branch. This allows you to test your changes before merging to production. Each merge to main will trigger a new deployment of the latest version of your server.
docs/deployment/running-server.mdx CHANGED
@@ -1,17 +1,15 @@
1
  ---
2
- title: Running Your FastMCP Server
3
- sidebarTitle: Running the Server
4
- description: Learn how to run and deploy your FastMCP server using various transport protocols like STDIO, Streamable HTTP, and SSE.
5
  icon: circle-play
6
  ---
7
- import { VersionBadge } from '/snippets/version-badge.mdx'
8
 
9
-
10
- FastMCP servers can be run in different ways depending on your application's needs, from local command-line tools to persistent web services. This guide covers the primary methods for running your server, focusing on the available transport protocols: STDIO, Streamable HTTP, and SSE.
11
 
12
  ## The `run()` Method
13
 
14
- FastMCP servers can be run directly from Python by calling the `run()` method on a `FastMCP` instance.
15
 
16
  <Tip>
17
  For maximum compatibility, it's best practice to place the `run()` call within an `if __name__ == "__main__":` block. This ensures the server starts only when the script is executed directly, not when imported as a module.
@@ -29,253 +27,141 @@ def hello(name: str) -> str:
29
  if __name__ == "__main__":
30
  mcp.run()
31
  ```
32
- You can now run this MCP server by executing `python my_server.py`.
33
-
34
- MCP servers can be run with a variety of different transport options, depending on your application's requirements. The `run()` method can take a `transport` argument and other transport-specific keyword arguments to configure how the server operates.
35
-
36
- ## The FastMCP CLI
37
-
38
- FastMCP also provides a command-line interface for running servers without modifying the source code. After installing FastMCP, you can run your server directly from the command line:
39
-
40
- ```bash
41
- fastmcp run server.py
42
- ```
43
-
44
- <Tip>
45
- **Important**: When using `fastmcp run`, it **ignores** the `if __name__ == "__main__"` block entirely. Instead, it looks for a FastMCP object named `mcp`, `server`, or `app` and calls its `run()` method directly with the transport options you specify.
46
-
47
- This means you can use `fastmcp run` to override the transport specified in your code, which is particularly useful for testing or changing deployment methods without modifying the code.
48
- </Tip>
49
-
50
- You can specify transport options and other configuration:
51
-
52
- ```bash
53
- fastmcp run server.py --transport sse --port 9000
54
- ```
55
-
56
- ### Dependency Management with CLI
57
 
58
- When using the FastMCP CLI, you can pass additional options to configure how `uv` runs your server:
59
-
60
- ```bash
61
- # Run with a specific Python version
62
- fastmcp run server.py --python 3.11
63
-
64
- # Run with additional packages
65
- fastmcp run server.py --with pandas --with numpy
66
-
67
- # Run with dependencies from a requirements file
68
- fastmcp run server.py --with-requirements requirements.txt
69
-
70
- # Combine multiple options
71
- fastmcp run server.py --python 3.10 --with httpx --transport http
72
-
73
- # Run within a specific project directory
74
- fastmcp run server.py --project /path/to/project
75
- ```
76
 
77
- <Note>
78
- When using `--python`, `--with`, `--project`, or `--with-requirements`, the server runs via `uv run` subprocess instead of using your local environment. The `uv` command will manage dependencies based on your project configuration.
79
- </Note>
80
 
81
- <Tip>
82
- The `--python` option is particularly useful when you need to run a server with a specific Python version that differs from your system's default. This addresses common compatibility issues where servers require a particular Python version to function correctly.
83
- </Tip>
84
 
85
- For development and testing, you can use the `dev` command to run your server with the MCP Inspector:
86
 
87
- ```bash
88
- fastmcp dev server.py
89
- ```
90
 
91
- The `dev` command also supports the same dependency management options:
92
 
93
- ```bash
94
- # Dev server with specific Python version and packages
95
- fastmcp dev server.py --python 3.11 --with pandas
96
- ```
97
 
98
- See the [CLI documentation](/patterns/cli) for detailed information about all available commands and options.
 
99
 
100
- ### Passing Arguments to Servers
101
 
102
- When servers accept command line arguments (using argparse, click, or other libraries), you can pass them after `--`:
 
 
103
 
104
- ```bash
105
- fastmcp run config_server.py -- --config config.json
106
- fastmcp run database_server.py -- --database-path /tmp/db.sqlite --debug
107
  ```
108
 
109
- This is useful for servers that need configuration files, database paths, API keys, or other runtime options.
110
-
111
- ## Transport Options
 
 
112
 
113
- Below is a comparison of available transport options to help you choose the right one for your needs:
114
 
115
- | Transport | Use Cases | Recommendation |
116
- | --------- | --------- | -------------- |
117
- | **STDIO** | Local tools, command-line scripts, and integrations with clients like Claude Desktop | Best for local tools and when clients manage server processes |
118
- | **Streamable HTTP** | Web-based deployments, microservices, exposing MCP over a network | Recommended choice for web-based deployments |
119
- | **SSE** | Existing web-based deployments that rely on SSE | Deprecated - prefer Streamable HTTP for new projects |
120
 
121
- ### STDIO
122
 
123
- The STDIO transport is the default and most widely compatible option for local MCP server execution. It is ideal for local tools, command-line integrations, and clients like Claude Desktop. However, it has the disadvantage of having to run the MCP code locally, which can introduce security concerns with third-party servers.
124
 
125
- STDIO is the default transport, so you don't need to specify it when calling `run()`. However, you can specify it explicitly to make your intent clear:
126
-
127
- ```python {6}
128
  from fastmcp import FastMCP
129
 
130
- mcp = FastMCP()
 
 
 
 
131
 
132
  if __name__ == "__main__":
133
- mcp.run(transport="stdio")
 
134
  ```
135
 
136
- When using Stdio transport, you will typically *not* run the server yourself as a separate process. Rather, your *clients* will spin up a new server process for each session. As such, no additional configuration is required.
137
-
138
- ### Streamable HTTP
139
-
140
- <VersionBadge version="2.3.0" />
141
 
142
- Streamable HTTP is a modern, efficient transport for exposing your MCP server via HTTP. It is the recommended transport for web-based deployments.
143
-
144
- To run a server using Streamable HTTP, you can use the `run()` method with the `transport` argument set to `"http"`. This will start a Uvicorn server on the default host (`127.0.0.1`), port (`8000`), and path (`/mcp/`).
145
- <CodeGroup>
146
- ```python {6} server.py
147
- from fastmcp import FastMCP
148
 
149
- mcp = FastMCP()
150
-
151
- if __name__ == "__main__":
152
- mcp.run(transport="http")
153
- ```
154
- ```python {5} client.py
155
- import asyncio
156
- from fastmcp import Client
157
 
158
- async def example():
159
- async with Client("http://127.0.0.1:8000/mcp/") as client:
160
- await client.ping()
161
 
 
162
  if __name__ == "__main__":
163
- asyncio.run(example())
 
164
  ```
165
- </CodeGroup>
166
 
167
- <Tip>
168
- For backward compatibility, wherever `"http"` is accepted as a transport name, you can also pass `"streamable-http"` as a fully supported alias. This is particularly useful when upgrading from FastMCP 1.x in the official Python SDK and FastMCP \<= 2.9, where `"streamable-http"` was the standard name.
169
- </Tip>
170
 
171
- To customize the host, port, path, or log level, provide appropriate keyword arguments to the `run()` method.
172
 
173
- <CodeGroup>
174
- ```python {8-11} server.py
175
- from fastmcp import FastMCP
176
 
177
- mcp = FastMCP()
178
 
179
- if __name__ == "__main__":
180
- mcp.run(
181
- transport="http",
182
- host="127.0.0.1",
183
- port=4200,
184
- path="/my-custom-path",
185
- log_level="debug",
186
- )
187
- ```
188
- ```python {5} client.py
189
- import asyncio
190
- from fastmcp import Client
191
 
192
- async def example():
193
- async with Client("http://127.0.0.1:4200/my-custom-path") as client:
194
- await client.ping()
195
 
196
- if __name__ == "__main__":
197
- asyncio.run(example())
198
  ```
199
- </CodeGroup>
200
 
201
- ### SSE
202
 
203
- <Warning>
204
- The SSE transport is deprecated and may be removed in a future version.
205
- New applications should use Streamable HTTP transport instead.
206
- </Warning>
207
 
208
- Server-Sent Events (SSE) is an HTTP-based protocol for server-to-client streaming. While FastMCP still supports SSE, it is deprecated and Streamable HTTP is preferred for new projects.
209
 
210
- To run a server using SSE, you can use the `run()` method with the `transport` argument set to `"sse"`. This will start a Uvicorn server on the default host (`127.0.0.1`), port (`8000`), and with default SSE path (`/sse/`) and message path (`/messages/`).
211
-
212
- <CodeGroup>
213
- ```python {6} server.py
214
- from fastmcp import FastMCP
215
 
216
- mcp = FastMCP()
 
217
 
218
- if __name__ == "__main__":
219
- mcp.run(transport="sse")
220
- ```
221
- ```python {3,7} client.py
222
- import asyncio
223
- from fastmcp import Client
224
- from fastmcp.client.transports import SSETransport
225
 
226
- async def example():
227
- async with Client(
228
- transport=SSETransport("http://127.0.0.1:8000/sse/")
229
- ) as client:
230
- await client.ping()
231
 
232
- if __name__ == "__main__":
233
- asyncio.run(example())
234
  ```
235
- </CodeGroup>
236
-
237
- <Tip>
238
- Notice that the client in the above example uses an explicit `SSETransport` to connect to the server. FastMCP will attempt to infer the appropriate transport from the provided configuration, but HTTP URLs are assumed to be Streamable HTTP (as of FastMCP 2.3.0).
239
- </Tip>
240
 
241
- To customize the host, port, or log level, provide appropriate keyword arguments to the `run()` method. You can also adjust the SSE path (which clients should connect to) and the message POST endpoint (which clients use to send subsequent messages).
 
 
242
 
243
- <CodeGroup>
244
- ```python {8-12} server.py
245
- from fastmcp import FastMCP
246
 
247
- mcp = FastMCP()
248
 
249
- if __name__ == "__main__":
250
- mcp.run(
251
- transport="sse",
252
- host="127.0.0.1",
253
- port=4200,
254
- log_level="debug",
255
- path="/my-custom-sse-path",
256
- )
257
  ```
258
- ```python {7} client.py
259
- import asyncio
260
- from fastmcp import Client
261
- from fastmcp.client.transports import SSETransport
262
-
263
- async def example():
264
- async with Client(
265
- transport=SSETransport("http://127.0.0.1:4200/my-custom-sse-path")
266
- ) as client:
267
- await client.ping()
268
 
269
- if __name__ == "__main__":
270
- asyncio.run(example())
271
- ```
272
- </CodeGroup>
273
 
 
274
 
 
275
 
276
- ## Async Usage
277
 
278
- FastMCP provides both synchronous and asynchronous APIs for running your server. The `run()` method seen in previous examples is a synchronous method that internally uses `anyio.run()` to run the asynchronous server. For applications that are already running in an async context, FastMCP provides the `run_async()` method.
279
 
280
  ```python {10-12}
281
  from fastmcp import FastMCP
@@ -289,14 +175,14 @@ def hello(name: str) -> str:
289
 
290
  async def main():
291
  # Use run_async() in async contexts
292
- await mcp.run_async(transport="http")
293
 
294
  if __name__ == "__main__":
295
  asyncio.run(main())
296
  ```
297
 
298
  <Warning>
299
- The `run()` method cannot be called from inside an async function because it already creates its own async event loop internally. If you attempt to call `run()` from inside an async function, you'll get an error about the event loop already running.
300
 
301
  Always use `run_async()` inside async functions and `run()` in synchronous contexts.
302
  </Warning>
@@ -305,7 +191,7 @@ Both `run()` and `run_async()` accept the same transport arguments, so all the e
305
 
306
  ## Custom Routes
307
 
308
- You can also add custom web routes to your FastMCP server, which will be exposed alongside the MCP endpoint. To do so, use the `@custom_route` decorator. Note that this is less flexible than using a full ASGI framework, but can be useful for adding simple endpoints like health checks to your standalone server.
309
 
310
  ```python
311
  from fastmcp import FastMCP
@@ -318,6 +204,55 @@ mcp = FastMCP("MyServer")
318
  async def health_check(request: Request) -> PlainTextResponse:
319
  return PlainTextResponse("OK")
320
 
 
 
 
 
321
  if __name__ == "__main__":
322
- mcp.run()
323
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Running Your Server
3
+ sidebarTitle: Running
4
+ description: Learn how to run your FastMCP server locally for development and testing
5
  icon: circle-play
6
  ---
 
7
 
8
+ FastMCP servers can be run in different ways depending on your needs. This guide focuses on running servers locally for development and testing. For production deployment to a URL, see the [Self-Hosted Deployment](/deployment/self-hosted) guide.
 
9
 
10
  ## The `run()` Method
11
 
12
+ Every FastMCP server needs to be started to accept connections. The simplest way to run a server is by calling the `run()` method on your FastMCP instance. This method starts the server and blocks until it's stopped, handling all the connection management for you.
13
 
14
  <Tip>
15
  For maximum compatibility, it's best practice to place the `run()` call within an `if __name__ == "__main__":` block. This ensures the server starts only when the script is executed directly, not when imported as a module.
 
27
  if __name__ == "__main__":
28
  mcp.run()
29
  ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
+ You can now run this MCP server by executing `python my_server.py`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
+ ## Transport Protocols
 
 
34
 
35
+ MCP servers communicate with clients through different transport protocols. Think of transports as the "language" your server speaks to communicate with clients. FastMCP supports three main transport protocols, each designed for specific use cases and deployment scenarios.
 
 
36
 
37
+ The choice of transport determines how clients connect to your server, what network capabilities are available, and how many clients can connect simultaneously. Understanding these transports helps you choose the right approach for your application.
38
 
39
+ ### STDIO Transport (Default)
 
 
40
 
41
+ STDIO (Standard Input/Output) is the default transport for FastMCP servers. When you call `run()` without arguments, your server uses STDIO transport. This transport communicates through standard input and output streams, making it perfect for command-line tools and desktop applications like Claude Desktop.
42
 
43
+ With STDIO transport, the client spawns a new server process for each session and manages its lifecycle. The server reads MCP messages from stdin and writes responses to stdout. This is why STDIO servers don't stay running - they're started on-demand by the client.
 
 
 
44
 
45
+ ```python
46
+ from fastmcp import FastMCP
47
 
48
+ mcp = FastMCP("MyServer")
49
 
50
+ @mcp.tool
51
+ def hello(name: str) -> str:
52
+ return f"Hello, {name}!"
53
 
54
+ if __name__ == "__main__":
55
+ mcp.run() # Uses STDIO transport by default
 
56
  ```
57
 
58
+ STDIO is ideal for:
59
+ - Local development and testing
60
+ - Claude Desktop integration
61
+ - Command-line tools
62
+ - Single-user applications
63
 
64
+ ### HTTP Transport (Streamable)
65
 
66
+ HTTP transport turns your MCP server into a web service accessible via a URL. This transport uses the Streamable HTTP protocol, which allows clients to connect over the network. Unlike STDIO where each client gets its own process, an HTTP server can handle multiple clients simultaneously.
 
 
 
 
67
 
68
+ The Streamable HTTP protocol provides full bidirectional communication between client and server, supporting all MCP operations including streaming responses. This makes it the recommended choice for network-based deployments.
69
 
70
+ To use HTTP transport, specify it in the `run()` method along with networking options:
71
 
72
+ ```python
 
 
73
  from fastmcp import FastMCP
74
 
75
+ mcp = FastMCP("MyServer")
76
+
77
+ @mcp.tool
78
+ def hello(name: str) -> str:
79
+ return f"Hello, {name}!"
80
 
81
  if __name__ == "__main__":
82
+ # Start an HTTP server on port 8000
83
+ mcp.run(transport="http", host="127.0.0.1", port=8000)
84
  ```
85
 
86
+ Your server is now accessible at `http://localhost:8000/mcp/`. This URL is the MCP endpoint that clients will connect to. HTTP transport enables:
87
+ - Network accessibility
88
+ - Multiple concurrent clients
89
+ - Integration with web infrastructure
90
+ - Remote deployment capabilities
91
 
92
+ For production HTTP deployment with authentication and advanced configuration, see the [Self-Hosted Deployment](/deployment/self-hosted) guide.
 
 
 
 
 
93
 
94
+ ### SSE Transport (Legacy)
 
 
 
 
 
 
 
95
 
96
+ Server-Sent Events (SSE) transport was the original HTTP-based transport for MCP. While still supported for backward compatibility, it has limitations compared to the newer Streamable HTTP transport. SSE only supports server-to-client streaming, making it less efficient for bidirectional communication.
 
 
97
 
98
+ ```python
99
  if __name__ == "__main__":
100
+ # SSE transport - use HTTP instead for new projects
101
+ mcp.run(transport="sse", host="127.0.0.1", port=8000)
102
  ```
 
103
 
104
+ We recommend using HTTP transport instead of SSE for all new projects. SSE remains available only for compatibility with older clients that haven't upgraded to Streamable HTTP.
 
 
105
 
106
+ ### Choosing the Right Transport
107
 
108
+ Each transport serves different needs. STDIO is perfect when you need simple, local execution - it's what Claude Desktop and most command-line tools expect. HTTP transport is essential when you need network access, want to serve multiple clients, or plan to deploy your server remotely. SSE exists only for backward compatibility and shouldn't be used in new projects.
 
 
109
 
110
+ Consider your deployment scenario: Are you building a tool for local use? STDIO is your best choice. Need a centralized service that multiple clients can access? HTTP transport is the way to go.
111
 
112
+ ## The FastMCP CLI
 
 
 
 
 
 
 
 
 
 
 
113
 
114
+ FastMCP provides a powerful command-line interface for running servers without modifying the source code. The CLI can automatically find and run your server with different transports, manage dependencies, and handle development workflows:
 
 
115
 
116
+ ```bash
117
+ fastmcp run server.py
118
  ```
 
119
 
120
+ The CLI automatically finds a FastMCP instance in your file (named `mcp`, `server`, or `app`) and runs it with the specified options. This is particularly useful for testing different transports or configurations without changing your code.
121
 
122
+ ### Dependency Management
 
 
 
123
 
124
+ The CLI integrates with `uv` to manage Python environments and dependencies:
125
 
126
+ ```bash
127
+ # Run with a specific Python version
128
+ fastmcp run server.py --python 3.11
 
 
129
 
130
+ # Run with additional packages
131
+ fastmcp run server.py --with pandas --with numpy
132
 
133
+ # Run with dependencies from a requirements file
134
+ fastmcp run server.py --with-requirements requirements.txt
 
 
 
 
 
135
 
136
+ # Combine multiple options
137
+ fastmcp run server.py --python 3.10 --with httpx --transport http
 
 
 
138
 
139
+ # Run within a specific project directory
140
+ fastmcp run server.py --project /path/to/project
141
  ```
 
 
 
 
 
142
 
143
+ <Note>
144
+ When using `--python`, `--with`, `--project`, or `--with-requirements`, the server runs via `uv run` subprocess instead of using your local environment.
145
+ </Note>
146
 
147
+ ### Passing Arguments to Servers
 
 
148
 
149
+ When servers accept command line arguments (using argparse, click, or other libraries), you can pass them after `--`:
150
 
151
+ ```bash
152
+ fastmcp run config_server.py -- --config config.json
153
+ fastmcp run database_server.py -- --database-path /tmp/db.sqlite --debug
 
 
 
 
 
154
  ```
 
 
 
 
 
 
 
 
 
 
155
 
156
+ This is useful for servers that need configuration files, database paths, API keys, or other runtime options.
 
 
 
157
 
158
+ For more CLI features including development mode with the MCP Inspector, see the [CLI documentation](/patterns/cli).
159
 
160
+ ### Async Usage
161
 
162
+ FastMCP servers are built on async Python, but the framework provides both synchronous and asynchronous APIs to fit your application's needs. The `run()` method we've been using is actually a synchronous wrapper around the async server implementation.
163
 
164
+ For applications that are already running in an async context, FastMCP provides the `run_async()` method:
165
 
166
  ```python {10-12}
167
  from fastmcp import FastMCP
 
175
 
176
  async def main():
177
  # Use run_async() in async contexts
178
+ await mcp.run_async(transport="http", port=8000)
179
 
180
  if __name__ == "__main__":
181
  asyncio.run(main())
182
  ```
183
 
184
  <Warning>
185
+ The `run()` method cannot be called from inside an async function because it creates its own async event loop internally. If you attempt to call `run()` from inside an async function, you'll get an error about the event loop already running.
186
 
187
  Always use `run_async()` inside async functions and `run()` in synchronous contexts.
188
  </Warning>
 
191
 
192
  ## Custom Routes
193
 
194
+ When using HTTP transport, you might want to add custom web endpoints alongside your MCP server. This is useful for health checks, status pages, or simple APIs. FastMCP lets you add custom routes using the `@custom_route` decorator:
195
 
196
  ```python
197
  from fastmcp import FastMCP
 
204
  async def health_check(request: Request) -> PlainTextResponse:
205
  return PlainTextResponse("OK")
206
 
207
+ @mcp.tool
208
+ def process(data: str) -> str:
209
+ return f"Processed: {data}"
210
+
211
  if __name__ == "__main__":
212
+ mcp.run(transport="http") # Health check at http://localhost:8000/health
213
+ ```
214
+
215
+ Custom routes are served by the same web server as your MCP endpoint. They're available at the root of your domain while the MCP endpoint is at `/mcp/`. For more complex web applications, consider [mounting your MCP server into a FastAPI or Starlette app](/deployment/self-hosted#integration-with-web-frameworks).
216
+
217
+ ## Alternative Initialization Patterns
218
+
219
+ The `if __name__ == "__main__"` pattern works well for standalone scripts, but some deployment scenarios require different approaches. FastMCP handles these cases automatically.
220
+
221
+ ### CLI-Only Servers
222
+
223
+ When using the FastMCP CLI, you don't need the `if __name__` block at all. The CLI will find your FastMCP instance and run it:
224
+
225
+ ```python
226
+ # server.py
227
+ from fastmcp import FastMCP
228
+
229
+ mcp = FastMCP("MyServer") # CLI looks for 'mcp', 'server', or 'app'
230
+
231
+ @mcp.tool
232
+ def process(data: str) -> str:
233
+ return f"Processed: {data}"
234
+
235
+ # No if __name__ block needed - CLI will find and run 'mcp'
236
+ ```
237
+
238
+ ### ASGI Applications
239
+
240
+ For ASGI deployment (running with Uvicorn or similar), you'll want to create an ASGI application object. This approach is common in production deployments where you need more control over the server configuration:
241
+
242
+ ```python
243
+ # app.py
244
+ from fastmcp import FastMCP
245
+
246
+ def create_app():
247
+ mcp = FastMCP("MyServer")
248
+
249
+ @mcp.tool
250
+ def process(data: str) -> str:
251
+ return f"Processed: {data}"
252
+
253
+ return mcp.http_app()
254
+
255
+ app = create_app() # Uvicorn will use this
256
+ ```
257
+
258
+ See the [Self-Hosted Deployment](/deployment/self-hosted) guide for more ASGI deployment patterns.
docs/deployment/self-hosted.mdx ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Self-Hosted Remote MCP
3
+ sidebarTitle: Self-Hosted
4
+ description: Deploy your FastMCP server as a remote MCP service accessible via URL
5
+ icon: server
6
+ ---
7
+
8
+ <Tip>
9
+ STDIO transport is perfect for local development and desktop applications. But to unlock the full potential of MCP—centralized services, multi-client access, and network availability—you need remote HTTP deployment.
10
+ </Tip>
11
+
12
+ This guide walks you through deploying your FastMCP server as a remote MCP service that's accessible via a URL. Once deployed, your MCP server will be available over the network, allowing multiple clients to connect simultaneously and enabling integration with cloud-based LLM applications. This guide focuses specifically on remote MCP deployment, not local STDIO servers.
13
+
14
+ ## Choosing Your Approach
15
+
16
+ FastMCP provides two ways to deploy your server as an HTTP service. Understanding the trade-offs helps you choose the right approach for your needs.
17
+
18
+ The **direct HTTP server** approach is simpler and perfect for getting started quickly. You modify your server's `run()` method to use HTTP transport, and FastMCP handles all the web server configuration. This approach works well for standalone deployments where you want your MCP server to be the only service running on a port.
19
+
20
+ The **ASGI application** approach gives you more control and flexibility. Instead of running the server directly, you create an ASGI application that can be served by production-grade servers like Uvicorn or Gunicorn. This approach is better when you need advanced server features like multiple workers, custom middleware, or when you're integrating with existing web applications.
21
+
22
+ ### Direct HTTP Server
23
+
24
+ The simplest way to get your MCP server online is to use the built-in `run()` method with HTTP transport. This approach handles all the server configuration for you and is ideal when you want a standalone MCP server without additional complexity.
25
+
26
+ ```python server.py
27
+ from fastmcp import FastMCP
28
+
29
+ mcp = FastMCP("My Server")
30
+
31
+ @mcp.tool
32
+ def process_data(input: str) -> str:
33
+ """Process data on the server"""
34
+ return f"Processed: {input}"
35
+
36
+ if __name__ == "__main__":
37
+ mcp.run(transport="http", host="0.0.0.0", port=8000)
38
+ ```
39
+
40
+ Run your server with a simple Python command:
41
+ ```bash
42
+ python server.py
43
+ ```
44
+
45
+ Your server is now accessible at `http://localhost:8000/mcp/` (or use your server's actual IP address for remote access).
46
+
47
+ This approach is ideal when you want to get online quickly with minimal configuration. It's perfect for internal tools, development environments, or simple deployments where you don't need advanced server features. The built-in server handles all the HTTP details, letting you focus on your MCP implementation.
48
+
49
+ ### ASGI Application
50
+
51
+ For production deployments, you'll often want more control over how your server runs. FastMCP can create a standard ASGI application that works with any ASGI server like Uvicorn, Gunicorn, or Hypercorn. This approach is particularly useful when you need to configure advanced server options, run multiple workers, or integrate with existing infrastructure.
52
+
53
+ ```python app.py
54
+ from fastmcp import FastMCP
55
+
56
+ mcp = FastMCP("My Server")
57
+
58
+ @mcp.tool
59
+ def process_data(input: str) -> str:
60
+ """Process data on the server"""
61
+ return f"Processed: {input}"
62
+
63
+ # Create ASGI application
64
+ app = mcp.http_app()
65
+ ```
66
+
67
+ Run with any ASGI server - here's an example with Uvicorn:
68
+ ```bash
69
+ uvicorn app:app --host 0.0.0.0 --port 8000
70
+ ```
71
+
72
+ Your server is accessible at the same URL: `http://localhost:8000/mcp/` (or use your server's actual IP address for remote access).
73
+
74
+ The ASGI approach shines in production environments where you need reliability and performance. You can run multiple worker processes to handle concurrent requests, add custom middleware for logging or monitoring, integrate with existing deployment pipelines, or mount your MCP server as part of a larger application. This flexibility makes it the preferred choice for serious deployments.
75
+
76
+ ## Configuring Your Server
77
+
78
+ ### Custom Path
79
+
80
+ By default, your MCP server is accessible at `/mcp/` on your domain. You can customize this path to fit your URL structure or avoid conflicts with existing endpoints. This is particularly useful when integrating MCP into an existing application or following specific API conventions.
81
+
82
+ ```python
83
+ # Option 1: With mcp.run()
84
+ mcp.run(transport="http", host="0.0.0.0", port=8000, path="/api/mcp/")
85
+
86
+ # Option 2: With ASGI app
87
+ app = mcp.http_app(path="/api/mcp/")
88
+ ```
89
+
90
+ Now your server is accessible at `http://localhost:8000/api/mcp/`.
91
+
92
+ ### Authentication
93
+
94
+ <Warning>
95
+ Authentication is **highly recommended** for remote MCP servers. Some LLM clients require authentication for remote servers and will refuse to connect without it.
96
+ </Warning>
97
+
98
+ FastMCP supports multiple authentication methods to secure your remote server. See the [Authentication Overview](/servers/auth/authentication) for complete configuration options including Bearer tokens, JWT, and OAuth.
99
+
100
+ ### Health Checks
101
+
102
+ Health check endpoints are essential for monitoring your deployed server and ensuring it's responding correctly. FastMCP allows you to add custom routes alongside your MCP endpoints, making it easy to implement health checks that work with both deployment approaches.
103
+
104
+ ```python
105
+ from starlette.responses import JSONResponse
106
+
107
+ @mcp.custom_route("/health", methods=["GET"])
108
+ async def health_check(request):
109
+ return JSONResponse({"status": "healthy", "service": "mcp-server"})
110
+ ```
111
+
112
+ This health endpoint will be available at `http://localhost:8000/health` and can be used by load balancers, monitoring systems, or deployment platforms to verify your server is running.
113
+
114
+ ## Integration with Web Frameworks
115
+
116
+ If you already have a web application running, you can add MCP capabilities by mounting a FastMCP server as a sub-application. This allows you to expose MCP tools alongside your existing API endpoints, sharing the same domain and infrastructure. The MCP server becomes just another route in your application, making it easy to manage and deploy.
117
+
118
+ For detailed integration guides, see:
119
+ - [FastAPI Integration](/integrations/fastapi)
120
+ - [Starlette Integration](/integrations/starlette)
121
+
122
+ Here's a quick example showing how to add MCP to an existing FastAPI application:
123
+
124
+ ```python
125
+ from fastapi import FastAPI
126
+ from fastmcp import FastMCP
127
+
128
+ # Your existing API
129
+ api = FastAPI()
130
+
131
+ @api.get("/api/status")
132
+ def status():
133
+ return {"status": "ok"}
134
+
135
+ # Create your MCP server
136
+ mcp = FastMCP("API Tools")
137
+
138
+ @mcp.tool
139
+ def query_database(query: str) -> dict:
140
+ """Run a database query"""
141
+ return {"result": "data"}
142
+
143
+ # Mount MCP at /mcp
144
+ api.mount("/mcp", mcp.http_app())
145
+
146
+ # Run with: uvicorn app:api --host 0.0.0.0 --port 8000
147
+ ```
148
+
149
+ Your existing API remains at `http://localhost:8000/api/` while MCP is available at `http://localhost:8000/mcp/`.
150
+
151
+ ## Production Deployment
152
+
153
+ ### Running with Uvicorn
154
+
155
+ When deploying to production, you'll want to optimize your server for performance and reliability. Uvicorn provides several options to improve your server's capabilities, including running multiple worker processes to handle concurrent requests and enabling enhanced logging for monitoring.
156
+
157
+ ```bash
158
+ # Install uvicorn with standard extras for better performance
159
+ pip install 'uvicorn[standard]'
160
+
161
+ # Run with multiple workers for better concurrency
162
+ uvicorn app:app --host 0.0.0.0 --port 8000 --workers 4
163
+
164
+ # Enable detailed logging for monitoring
165
+ uvicorn app:app --host 0.0.0.0 --port 8000 --log-level info
166
+ ```
167
+
168
+ ### Environment Variables
169
+
170
+ Production deployments should never hardcode sensitive information like API keys or authentication tokens. Instead, use environment variables to configure your server at runtime. This keeps your code secure and makes it easy to deploy the same code to different environments with different configurations.
171
+
172
+ Here's an example using bearer token authentication (though OAuth is recommended for production):
173
+
174
+ ```python
175
+ import os
176
+ from fastmcp import FastMCP
177
+ from fastmcp.server.auth import BearerTokenAuth
178
+
179
+ # Read configuration from environment
180
+ auth_token = os.environ.get("MCP_AUTH_TOKEN")
181
+ if auth_token:
182
+ auth = BearerTokenAuth(token=auth_token)
183
+ mcp = FastMCP("Production Server", auth=auth)
184
+ else:
185
+ mcp = FastMCP("Production Server")
186
+
187
+ app = mcp.http_app()
188
+ ```
189
+
190
+ Deploy with your secrets safely stored in environment variables:
191
+ ```bash
192
+ MCP_AUTH_TOKEN=secret uvicorn app:app --host 0.0.0.0 --port 8000
193
+ ```
194
+
195
+ ## Testing Your Deployment
196
+
197
+ Once your server is deployed, you'll need to verify it's accessible and functioning correctly. For comprehensive testing strategies including connectivity tests, client testing, and authentication testing, see the [Testing Your Server](/deployment/testing) guide.
198
+
199
+ ## Hosting Your Server
200
+
201
+ This guide has shown you how to create an HTTP-accessible MCP server, but you'll still need a hosting provider to make it available on the internet. Your FastMCP server can run anywhere that supports Python web applications:
202
+
203
+ - **Cloud VMs** (AWS EC2, Google Compute Engine, Azure VMs)
204
+ - **Container platforms** (Cloud Run, Container Instances, ECS)
205
+ - **Platform-as-a-Service** (Railway, Render, Vercel)
206
+ - **Edge platforms** (Cloudflare Workers)
207
+ - **Kubernetes clusters** (self-managed or managed)
208
+
209
+ The key requirements are Python 3.10+ support and the ability to expose an HTTP port. Most providers will require you to package your server (requirements.txt, Dockerfile, etc.) according to their deployment format. For managed, zero-configuration deployment, see [FastMCP Cloud](/deployment/fastmcp-cloud).
docs/deployment/testing.mdx ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Testing Your Server
3
+ sidebarTitle: Testing
4
+ description: Unit test your MCP servers with the FastMCP Client's deterministic testing capabilities
5
+ icon: vial
6
+ ---
7
+
8
+ The [FastMCP Client](/clients/client) is a deterministic testing tool that gives you complete programmatic control over MCP server interactions. You call specific tools with exact arguments, verify responses, and test edge cases - making it ideal for unit testing your MCP servers.
9
+
10
+ ## In-Memory Testing
11
+
12
+ The FastMCP Client's standout feature is in-memory testing. Instead of deploying your server or managing network connections, you pass your server instance directly to the client. This creates a zero-overhead connection that runs entirely in memory.
13
+
14
+ What makes this approach so powerful is that everything runs in the same Python process. You can set breakpoints anywhere - in your test code or inside your server handlers - and step through with your debugger. There's no server startup scripts, no port management, no cleanup between tests. Tests execute instantly without network overhead.
15
+
16
+ ```python
17
+ from fastmcp import FastMCP, Client
18
+
19
+ # Create your server
20
+ server = FastMCP("WeatherServer")
21
+
22
+ @server.tool
23
+ def get_temperature(city: str) -> dict:
24
+ """Get current temperature for a city"""
25
+ temps = {"NYC": 72, "LA": 85, "Chicago": 68}
26
+ return {"city": city, "temp": temps.get(city, 70)}
27
+
28
+ @server.resource("weather://forecast")
29
+ def get_forecast() -> dict:
30
+ """Get 5-day forecast"""
31
+ return {"days": 5, "conditions": "sunny"}
32
+
33
+ async def test_weather_operations():
34
+ # Pass server directly - no deployment needed
35
+ async with Client(server) as client:
36
+ # Test tool execution
37
+ result = await client.call_tool("get_temperature", {"city": "NYC"})
38
+ assert result.data == {"city": "NYC", "temp": 72}
39
+
40
+ # Test resource retrieval
41
+ forecast = await client.read_resource("weather://forecast")
42
+ assert forecast.contents[0].data == {"days": 5, "conditions": "sunny"}
43
+ ```
44
+
45
+ The in-memory approach transforms MCP testing from a deployment challenge into standard unit testing. You focus on testing your server's behavior, not wrestling with infrastructure.
46
+
47
+ ## Testing with Frameworks
48
+
49
+ The FastMCP Client works seamlessly with any Python testing framework. Whether you prefer pytest, unittest, or another framework, the pattern remains consistent: create a server, pass it to the client, and verify behavior.
50
+
51
+ ```python
52
+ import pytest
53
+ from fastmcp import FastMCP, Client
54
+
55
+ @pytest.fixture
56
+ def weather_server():
57
+ server = FastMCP("WeatherServer")
58
+
59
+ @server.tool
60
+ def get_temperature(city: str) -> dict:
61
+ temps = {"NYC": 72, "LA": 85, "Chicago": 68}
62
+ return {"city": city, "temp": temps.get(city, 70)}
63
+
64
+ return server
65
+
66
+ @pytest.mark.asyncio
67
+ async def test_temperature_tool(weather_server):
68
+ async with Client(weather_server) as client:
69
+ result = await client.call_tool("get_temperature", {"city": "LA"})
70
+ assert result.data == {"city": "LA", "temp": 85}
71
+
72
+ @pytest.mark.asyncio
73
+ async def test_unknown_city(weather_server):
74
+ async with Client(weather_server) as client:
75
+ result = await client.call_tool("get_temperature", {"city": "Paris"})
76
+ assert result.data["temp"] == 70 # Default temperature
77
+ ```
78
+
79
+ ## Mocking External Dependencies
80
+
81
+ FastMCP servers are standard Python objects, so you can mock external dependencies using your preferred mocking approach. Replace databases, APIs, or any external service with test doubles to keep your tests fast and deterministic.
82
+
83
+ ```python
84
+ from unittest.mock import AsyncMock
85
+
86
+ async def test_database_tool():
87
+ server = FastMCP("DataServer")
88
+
89
+ # Mock the database
90
+ mock_db = AsyncMock()
91
+ mock_db.fetch_users.return_value = [
92
+ {"id": 1, "name": "Alice"},
93
+ {"id": 2, "name": "Bob"}
94
+ ]
95
+
96
+ @server.tool
97
+ async def list_users() -> list:
98
+ return await mock_db.fetch_users()
99
+
100
+ async with Client(server) as client:
101
+ result = await client.call_tool("list_users", {})
102
+ assert len(result.data) == 2
103
+ assert result.data[0]["name"] == "Alice"
104
+ mock_db.fetch_users.assert_called_once()
105
+ ```
106
+
107
+ ## Testing Deployed Servers
108
+
109
+ While in-memory testing covers most unit testing needs, you'll occasionally need to test against a deployed server - to verify authentication, test network behavior, or validate deployments.
110
+
111
+ ### HTTP Transport Testing
112
+
113
+ When you need to test actual network behavior or verify a deployment, connect to your running server using its URL:
114
+
115
+ ```python
116
+ from fastmcp import Client
117
+
118
+ async def test_deployed_server():
119
+ # Connect to a running server
120
+ async with Client("http://localhost:8000/mcp/") as client:
121
+ await client.ping()
122
+
123
+ # Test with real network transport
124
+ tools = await client.list_tools()
125
+ assert len(tools) > 0
126
+
127
+ result = await client.call_tool("greet", {"name": "World"})
128
+ assert "Hello" in result.data
129
+ ```
130
+
131
+ ### Testing Authentication
132
+
133
+ The FastMCP Client handles authentication transparently, making it easy to test secured servers:
134
+
135
+ ```python
136
+ async def test_authenticated_server():
137
+ # Bearer token authentication
138
+ async with Client(
139
+ "https://api.example.com/mcp",
140
+ headers={"Authorization": "Bearer test-token"}
141
+ ) as client:
142
+ await client.ping()
143
+ tools = await client.list_tools()
144
+
145
+ # OAuth flow (opens browser for authorization)
146
+ async with Client("https://api.example.com/mcp", auth="oauth") as client:
147
+ result = await client.call_tool("protected_tool", {})
148
+ assert result.data is not None
149
+ ```
150
+
151
+ ## Best Practices
152
+
153
+ 1. **Default to in-memory testing** - It's faster, more reliable, and easier to debug
154
+ 2. **Test behavior, not implementation** - Call tools and verify responses rather than testing internals
155
+ 3. **Use framework fixtures** - Create reusable server configurations for your test suite
156
+ 4. **Mock external dependencies** - Keep tests fast and deterministic by mocking databases, APIs, etc.
157
+ 5. **Test error cases** - Verify your server handles invalid inputs and edge cases properly
158
+
159
+ The FastMCP Client transforms MCP server testing from a deployment challenge into a straightforward unit testing task. With in-memory connections and deterministic control, you can build comprehensive test suites that run in milliseconds.
docs/docs.json CHANGED
@@ -20,7 +20,7 @@
20
  "background": "/assets/brand/card-background.png"
21
  },
22
  "banner": {
23
- "content": "Remote MCP that just works. &nbsp; [Try FastMCP Cloud ->](https://fastmcp.link/IhmBxWn)"
24
  },
25
  "colors": {
26
  "dark": "#f72585",
@@ -70,14 +70,7 @@
70
  {
71
  "group": "Servers",
72
  "pages": [
73
- {
74
- "group": "Essentials",
75
- "icon": "cube",
76
- "pages": [
77
- "servers/server",
78
- "deployment/running-server"
79
- ]
80
- },
81
  {
82
  "group": "Core Components",
83
  "icon": "toolbox",
@@ -110,6 +103,16 @@
110
  "servers/auth/token-verification",
111
  "servers/auth/full-oauth-server"
112
  ]
 
 
 
 
 
 
 
 
 
 
113
  }
114
  ]
115
  },
@@ -119,10 +122,7 @@
119
  {
120
  "group": "Essentials",
121
  "icon": "cube",
122
- "pages": [
123
- "clients/client",
124
- "clients/transports"
125
- ]
126
  },
127
  {
128
  "group": "Core Operations",
@@ -148,10 +148,7 @@
148
  {
149
  "group": "Authentication",
150
  "icon": "user-shield",
151
- "pages": [
152
- "clients/auth/oauth",
153
- "clients/auth/bearer"
154
- ]
155
  }
156
  ]
157
  },
@@ -166,6 +163,7 @@
166
  "integrations/cursor",
167
  "integrations/eunomia-authorization",
168
  "integrations/fastapi",
 
169
  "integrations/gemini",
170
  "integrations/mcp-json-configuration",
171
  "integrations/openai",
@@ -179,7 +177,6 @@
179
  "pages": [
180
  "patterns/tool-transformation",
181
  "patterns/decorating-methods",
182
- "patterns/testing",
183
  "patterns/cli",
184
  "patterns/contrib"
185
  ]
@@ -197,17 +194,12 @@
197
  },
198
  {
199
  "anchor": "What's New",
200
- "pages": [
201
- "updates",
202
- "changelog"
203
- ]
204
  },
205
  {
206
  "anchor": "Community",
207
  "icon": "users",
208
- "pages": [
209
- "community/showcase"
210
- ]
211
  }
212
  ]
213
  },
 
20
  "background": "/assets/brand/card-background.png"
21
  },
22
  "banner": {
23
+ "content": "Remote MCP that just works: [FastMCP Cloud is here!](https://fastmcp.link/IhmBxWn) "
24
  },
25
  "colors": {
26
  "dark": "#f72585",
 
70
  {
71
  "group": "Servers",
72
  "pages": [
73
+ "servers/server",
 
 
 
 
 
 
 
74
  {
75
  "group": "Core Components",
76
  "icon": "toolbox",
 
103
  "servers/auth/token-verification",
104
  "servers/auth/full-oauth-server"
105
  ]
106
+ },
107
+ {
108
+ "group": "Deployment",
109
+ "icon": "rocket",
110
+ "pages": [
111
+ "deployment/running-server",
112
+ "deployment/testing",
113
+ "deployment/self-hosted",
114
+ "deployment/fastmcp-cloud"
115
+ ]
116
  }
117
  ]
118
  },
 
122
  {
123
  "group": "Essentials",
124
  "icon": "cube",
125
+ "pages": ["clients/client", "clients/transports"]
 
 
 
126
  },
127
  {
128
  "group": "Core Operations",
 
148
  {
149
  "group": "Authentication",
150
  "icon": "user-shield",
151
+ "pages": ["clients/auth/oauth", "clients/auth/bearer"]
 
 
 
152
  }
153
  ]
154
  },
 
163
  "integrations/cursor",
164
  "integrations/eunomia-authorization",
165
  "integrations/fastapi",
166
+ "deployment/fastmcp-cloud",
167
  "integrations/gemini",
168
  "integrations/mcp-json-configuration",
169
  "integrations/openai",
 
177
  "pages": [
178
  "patterns/tool-transformation",
179
  "patterns/decorating-methods",
 
180
  "patterns/cli",
181
  "patterns/contrib"
182
  ]
 
194
  },
195
  {
196
  "anchor": "What's New",
197
+ "pages": ["updates", "changelog"]
 
 
 
198
  },
199
  {
200
  "anchor": "Community",
201
  "icon": "users",
202
+ "pages": ["community/showcase"]
 
 
203
  }
204
  ]
205
  },
docs/patterns/testing.mdx DELETED
@@ -1,48 +0,0 @@
1
- ---
2
- title: Testing MCP Servers
3
- sidebarTitle: Testing
4
- description: Learn how to test your FastMCP servers effectively
5
- icon: vial
6
- ---
7
-
8
-
9
- Testing your MCP servers thoroughly is essential for ensuring they work correctly when deployed. FastMCP makes this easy through a variety of testing patterns.
10
-
11
- ## In-Memory Testing
12
-
13
- The most efficient way to test an MCP server is to pass your FastMCP server instance directly to a Client. This enables in-memory testing without having to start a separate server process, which is particularly useful because managing an MCP server programmatically can be challenging.
14
-
15
- Here is an example of using a `Client` to test a server with pytest:
16
-
17
- ```python
18
- import pytest
19
- from fastmcp import FastMCP, Client
20
-
21
- @pytest.fixture
22
- def mcp_server():
23
- server = FastMCP("TestServer")
24
-
25
- @server.tool
26
- def greet(name: str) -> str:
27
- return f"Hello, {name}!"
28
-
29
- return server
30
-
31
- async def test_tool_functionality(mcp_server):
32
- # Pass the server directly to the Client constructor
33
- async with Client(mcp_server) as client:
34
- result = await client.call_tool("greet", {"name": "World"})
35
- assert result.data == "Hello, World!"
36
- ```
37
-
38
- This pattern creates a direct connection between the client and server, allowing you to test your server's functionality efficiently.
39
-
40
- <Tip>
41
- If you're using pytest for async tests, as shown above, you may need to configure appropriate markers or set `asyncio_mode = "auto"` in your pytest configuration in order to handle async test functions automatically.
42
- </Tip>
43
-
44
-
45
- ## Mocking
46
-
47
- FastMCP servers are designed to work seamlessly with standard Python testing tools and patterns. There's nothing special about testing FastMCP servers - you can use all the familiar Python mocking, patching, and testing techniques you already know.
48
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docs/servers/server.mdx CHANGED
@@ -215,6 +215,31 @@ The server can also be run using the FastMCP CLI.
215
 
216
  For detailed information on each transport, how to configure them (host, port, paths), and when to use which, please refer to the [**Running Your FastMCP Server**](/deployment/running-server) guide.
217
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
 
219
  ## Composing Servers
220
 
 
215
 
216
  For detailed information on each transport, how to configure them (host, port, paths), and when to use which, please refer to the [**Running Your FastMCP Server**](/deployment/running-server) guide.
217
 
218
+ ## Custom Routes
219
+
220
+ When running your server with HTTP transport, you can add custom web routes alongside your MCP endpoint using the `@custom_route` decorator. This is useful for simple endpoints like health checks that need to be served alongside your MCP server:
221
+
222
+ ```python
223
+ from fastmcp import FastMCP
224
+ from starlette.requests import Request
225
+ from starlette.responses import PlainTextResponse
226
+
227
+ mcp = FastMCP("MyServer")
228
+
229
+ @mcp.custom_route("/health", methods=["GET"])
230
+ async def health_check(request: Request) -> PlainTextResponse:
231
+ return PlainTextResponse("OK")
232
+
233
+ if __name__ == "__main__":
234
+ mcp.run(transport="http") # Health check at http://localhost:8000/health
235
+ ```
236
+
237
+ Custom routes are served alongside your MCP endpoint and are useful for:
238
+ - Health check endpoints for monitoring
239
+ - Simple status or info endpoints
240
+ - Basic webhooks or callbacks
241
+
242
+ For more complex web applications, consider [mounting your MCP server into a FastAPI or Starlette app](/deployment/self-hosted#integration-with-web-frameworks).
243
 
244
  ## Composing Servers
245