Jeremiah Lowin commited on
Commit
7682ff5
·
1 Parent(s): 4d88236

Update docs

Browse files
Files changed (1) hide show
  1. docs/servers/composition.mdx +81 -9
docs/servers/composition.mdx CHANGED
@@ -26,9 +26,10 @@ The choice of importing or mounting depends on your use case and requirements.
26
 
27
  | Feature | Importing | Mounting |
28
  |---------|----------------|---------|
29
- | **Method** | `FastMCP.import_server()` | `FastMCP.mount()` |
30
  | **Composition Type** | One-time copy (static) | Live link (dynamic) |
31
  | **Updates** | Changes to subserver NOT reflected | Changes to subserver immediately reflected |
 
32
  | **Best For** | Bundling finalized components | Modular runtime composition |
33
 
34
  ### Proxy Servers
@@ -41,7 +42,7 @@ You can also create proxies from configuration dictionaries that follow the MCPC
41
 
42
  ## Importing (Static Composition)
43
 
44
- The `import_server()` method copies all components (tools, resources, templates, prompts) from one `FastMCP` instance (the *subserver*) into another (the *main server*). A `prefix` is added to avoid naming conflicts.
45
 
46
  ```python
47
  from fastmcp import FastMCP
@@ -65,7 +66,7 @@ main_mcp = FastMCP(name="MainApp")
65
 
66
  # Import subserver
67
  async def setup():
68
- await main_mcp.import_server("weather", weather_mcp)
69
 
70
  # Result: main_mcp now contains prefixed components:
71
  # - Tool: "weather_get_forecast"
@@ -78,7 +79,7 @@ if __name__ == "__main__":
78
 
79
  ### How Importing Works
80
 
81
- When you call `await main_mcp.import_server(prefix, subserver)`:
82
 
83
  1. **Tools**: All tools from `subserver` are added to `main_mcp` with names prefixed using `{prefix}_`.
84
  - `subserver.tool(name="my_tool")` becomes `main_mcp.tool(name="{prefix}_my_tool")`.
@@ -91,9 +92,63 @@ When you call `await main_mcp.import_server(prefix, subserver)`:
91
 
92
  Note that `import_server` performs a **one-time copy** of components. Changes made to the `subserver` *after* importing **will not** be reflected in `main_mcp`. The `subserver`'s `lifespan` context is also **not** executed by the main server.
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  ## Mounting (Live Linking)
95
 
96
- The `mount()` method creates a **live link** between the `main_mcp` server and the `subserver`. Instead of copying components, requests for components matching the `prefix` are **delegated** to the `subserver` at runtime.
97
 
98
  ```python
99
  import asyncio
@@ -109,7 +164,7 @@ def initial_tool():
109
 
110
  # Mount subserver (synchronous operation)
111
  main_mcp = FastMCP(name="MainAppLive")
112
- main_mcp.mount("dynamic", dynamic_mcp)
113
 
114
  # Add a tool AFTER mounting - it will be accessible through main_mcp
115
  @dynamic_mcp.tool
@@ -143,6 +198,20 @@ When mounting is configured:
143
 
144
  The same prefixing rules apply as with `import_server` for naming tools, resources, templates, and prompts.
145
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  ### Direct vs. Proxy Mounting
147
 
148
  <VersionBadge version="2.2.7" />
@@ -161,10 +230,13 @@ FastMCP supports two mounting modes:
161
 
162
  ```python
163
  # Direct mounting (default when no custom lifespan)
164
- main_mcp.mount("api", api_server)
165
 
166
  # Proxy mounting (preserves full client lifecycle)
167
- main_mcp.mount("api", api_server, as_proxy=True)
 
 
 
168
  ```
169
 
170
  FastMCP automatically uses proxy mounting when the mounted server has a custom lifespan, but you can override this behavior with the `as_proxy` parameter.
@@ -178,7 +250,7 @@ When using `FastMCP.as_proxy()` to create a proxy server, mounting that server w
178
  remote_proxy = FastMCP.as_proxy(Client("http://example.com/mcp"))
179
 
180
  # Mount the proxy (always uses proxy mounting)
181
- main_server.mount("remote", remote_proxy)
182
  ```
183
 
184
 
 
26
 
27
  | Feature | Importing | Mounting |
28
  |---------|----------------|---------|
29
+ | **Method** | `FastMCP.import_server(server, prefix=None)` | `FastMCP.mount(server, prefix=None)` |
30
  | **Composition Type** | One-time copy (static) | Live link (dynamic) |
31
  | **Updates** | Changes to subserver NOT reflected | Changes to subserver immediately reflected |
32
+ | **Prefix** | Optional - omit for original names | Optional - omit for original names |
33
  | **Best For** | Bundling finalized components | Modular runtime composition |
34
 
35
  ### Proxy Servers
 
42
 
43
  ## Importing (Static Composition)
44
 
45
+ The `import_server()` method copies all components (tools, resources, templates, prompts) from one `FastMCP` instance (the *subserver*) into another (the *main server*). An optional `prefix` can be provided to avoid naming conflicts. If no prefix is provided, components are imported without modification. When multiple servers are imported with the same prefix (or no prefix), the most recently imported server's components take precedence.
46
 
47
  ```python
48
  from fastmcp import FastMCP
 
66
 
67
  # Import subserver
68
  async def setup():
69
+ await main_mcp.import_server(weather_mcp, prefix="weather")
70
 
71
  # Result: main_mcp now contains prefixed components:
72
  # - Tool: "weather_get_forecast"
 
79
 
80
  ### How Importing Works
81
 
82
+ When you call `await main_mcp.import_server(subserver, prefix={whatever})`:
83
 
84
  1. **Tools**: All tools from `subserver` are added to `main_mcp` with names prefixed using `{prefix}_`.
85
  - `subserver.tool(name="my_tool")` becomes `main_mcp.tool(name="{prefix}_my_tool")`.
 
92
 
93
  Note that `import_server` performs a **one-time copy** of components. Changes made to the `subserver` *after* importing **will not** be reflected in `main_mcp`. The `subserver`'s `lifespan` context is also **not** executed by the main server.
94
 
95
+ <Tip>
96
+ The `prefix` parameter is optional. If omitted, components are imported without modification.
97
+ </Tip>
98
+
99
+ #### Importing Without Prefixes
100
+
101
+ <VersionBadge version="2.9.0" />
102
+
103
+ You can also import servers without specifying a prefix, which copies components using their original names:
104
+
105
+ ```python
106
+
107
+ from fastmcp import FastMCP
108
+ import asyncio
109
+
110
+ # Define subservers
111
+ weather_mcp = FastMCP(name="WeatherService")
112
+
113
+ @weather_mcp.tool
114
+ def get_forecast(city: str) -> dict:
115
+ """Get weather forecast."""
116
+ return {"city": city, "forecast": "Sunny"}
117
+
118
+ @weather_mcp.resource("data://cities/supported")
119
+ def list_supported_cities() -> list[str]:
120
+ """List cities with weather support."""
121
+ return ["London", "Paris", "Tokyo"]
122
+
123
+ # Define main server
124
+ main_mcp = FastMCP(name="MainApp")
125
+
126
+ # Import subserver
127
+ async def setup():
128
+ # Import without prefix - components keep original names
129
+ await main_mcp.import_server(weather_mcp)
130
+
131
+ # Result: main_mcp now contains:
132
+ # - Tool: "get_forecast" (original name preserved)
133
+ # - Resource: "data://cities/supported" (original URI preserved)
134
+
135
+ if __name__ == "__main__":
136
+ asyncio.run(setup())
137
+ main_mcp.run()
138
+ ```
139
+
140
+ #### Conflict Resolution
141
+
142
+ <VersionBadge version="2.9.0" />
143
+
144
+ When importing multiple servers with the same prefix, or no prefix, components from the **most recently imported** server take precedence.
145
+
146
+
147
+
148
+
149
  ## Mounting (Live Linking)
150
 
151
+ The `mount()` method creates a **live link** between the `main_mcp` server and the `subserver`. Instead of copying components, requests for components matching the optional `prefix` are **delegated** to the `subserver` at runtime. If no prefix is provided, the subserver's components are accessible without prefixing. When multiple servers are mounted with the same prefix (or no prefix), the most recently mounted server takes precedence for conflicting component names.
152
 
153
  ```python
154
  import asyncio
 
164
 
165
  # Mount subserver (synchronous operation)
166
  main_mcp = FastMCP(name="MainAppLive")
167
+ main_mcp.mount(dynamic_mcp, prefix="dynamic")
168
 
169
  # Add a tool AFTER mounting - it will be accessible through main_mcp
170
  @dynamic_mcp.tool
 
198
 
199
  The same prefixing rules apply as with `import_server` for naming tools, resources, templates, and prompts.
200
 
201
+ <Tip>
202
+ The `prefix` parameter is optional. If omitted, components are mounted without modification.
203
+ </Tip>
204
+
205
+
206
+ #### Mounting Without Prefixes
207
+
208
+ <VersionBadge version="2.9.0" />
209
+
210
+ You can also mount servers without specifying a prefix, which makes components accessible without prefixing. This works identically to [importing without prefixes](#importing-without-prefixes), including [conflict resolution](#conflict-resolution).
211
+
212
+
213
+
214
+
215
  ### Direct vs. Proxy Mounting
216
 
217
  <VersionBadge version="2.2.7" />
 
230
 
231
  ```python
232
  # Direct mounting (default when no custom lifespan)
233
+ main_mcp.mount(api_server, prefix="api")
234
 
235
  # Proxy mounting (preserves full client lifecycle)
236
+ main_mcp.mount(api_server, prefix="api", as_proxy=True)
237
+
238
+ # Mounting without a prefix (components accessible without prefixing)
239
+ main_mcp.mount(api_server)
240
  ```
241
 
242
  FastMCP automatically uses proxy mounting when the mounted server has a custom lifespan, but you can override this behavior with the `as_proxy` parameter.
 
250
  remote_proxy = FastMCP.as_proxy(Client("http://example.com/mcp"))
251
 
252
  # Mount the proxy (always uses proxy mounting)
253
+ main_server.mount(remote_proxy, prefix="remote")
254
  ```
255
 
256