fastmcp 2.2.4__tar.gz → 2.2.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fastmcp-2.2.4 → fastmcp-2.2.6}/PKG-INFO +2 -2
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/clients/client.mdx +71 -64
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/docs.json +2 -1
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/patterns/fastapi.mdx +35 -14
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/patterns/openapi.mdx +97 -27
- fastmcp-2.2.6/docs/patterns/testing.mdx +38 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/servers/context.mdx +69 -15
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/servers/prompts.mdx +12 -21
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/servers/resources.mdx +40 -29
- fastmcp-2.2.6/docs/servers/tools.mdx +666 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/smart_home/src/smart_home/lights/server.py +25 -13
- {fastmcp-2.2.4 → fastmcp-2.2.6}/pyproject.toml +1 -1
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/__init__.py +1 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/client/client.py +12 -8
- fastmcp-2.2.6/src/fastmcp/client/logging.py +13 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/client/sampling.py +2 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/client/transports.py +37 -4
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/prompts/prompt.py +43 -4
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/prompts/prompt_manager.py +14 -3
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/resources/resource.py +12 -2
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/resources/resource_manager.py +20 -5
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/resources/template.py +43 -4
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/resources/types.py +55 -11
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/server/context.py +15 -13
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/server/openapi.py +86 -31
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/server/proxy.py +38 -21
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/server/server.py +49 -15
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/tools/tool.py +22 -6
- fastmcp-2.2.6/tests/client/test_logs.py +60 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/server/test_openapi.py +203 -5
- fastmcp-2.2.6/tests/server/test_server.py +736 -0
- fastmcp-2.2.4/tests/server/test_server.py → fastmcp-2.2.6/tests/server/test_server_interactions.py +606 -784
- fastmcp-2.2.6/tests/tools/__init__.py +0 -0
- fastmcp-2.2.4/docs/servers/tools.mdx +0 -341
- fastmcp-2.2.4/src/fastmcp/client/base.py +0 -1
- {fastmcp-2.2.4 → fastmcp-2.2.6}/.cursor/rules/core-mcp-objects.mdc +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/.github/ISSUE_TEMPLATE/enhancement.yml +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/.github/release.yml +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/.github/workflows/publish.yml +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/.github/workflows/run-static.yml +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/.github/workflows/run-tests.yml +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/.gitignore +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/.pre-commit-config.yaml +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/LICENSE +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/README.md +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/Windows_Notes.md +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/assets/demo-inspector.png +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/clients/transports.mdx +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/getting-started/installation.mdx +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/getting-started/quickstart.mdx +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/getting-started/welcome.mdx +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/patterns/composition.mdx +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/patterns/contrib.mdx +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/patterns/decorating-methods.mdx +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/patterns/proxy.mdx +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/servers/fastmcp.mdx +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/snippets/version-badge.mdx +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/docs/style.css +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/complex_inputs.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/desktop.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/echo.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/memory.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/mount_example.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/readme-quickstart.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/sampling.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/screenshot.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/simple_echo.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/smart_home/README.md +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/smart_home/pyproject.toml +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/smart_home/src/smart_home/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/smart_home/src/smart_home/__main__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/smart_home/src/smart_home/hub.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/smart_home/src/smart_home/lights/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/smart_home/src/smart_home/lights/hue_utils.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/smart_home/src/smart_home/py.typed +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/smart_home/src/smart_home/settings.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/smart_home/uv.lock +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/examples/text_me.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/justfile +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/cli/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/cli/claude.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/cli/cli.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/client/__init__.py +0 -0
- /fastmcp-2.2.4/src/fastmcp/py.typed → /fastmcp-2.2.6/src/fastmcp/client/base.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/client/roots.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/contrib/README.md +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/contrib/bulk_tool_caller/README.md +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/contrib/bulk_tool_caller/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/contrib/bulk_tool_caller/example.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/contrib/mcp_mixin/README.md +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/contrib/mcp_mixin/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/contrib/mcp_mixin/example.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/contrib/mcp_mixin/mcp_mixin.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/exceptions.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/prompts/__init__.py +0 -0
- /fastmcp-2.2.4/tests/__init__.py → /fastmcp-2.2.6/src/fastmcp/py.typed +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/resources/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/server/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/settings.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/tools/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/tools/tool_manager.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/utilities/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/utilities/decorators.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/utilities/func_metadata.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/utilities/logging.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/utilities/openapi.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/src/fastmcp/utilities/types.py +0 -0
- {fastmcp-2.2.4/tests/prompts → fastmcp-2.2.6/tests}/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/cli/test_run.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/client/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/client/test_client.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/client/test_roots.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/client/test_sampling.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/conftest.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/contrib/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/contrib/test_bulk_tool_caller.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/contrib/test_mcp_mixin.py +0 -0
- {fastmcp-2.2.4/tests/resources → fastmcp-2.2.6/tests/prompts}/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/prompts/test_base.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/prompts/test_prompt_manager.py +0 -0
- {fastmcp-2.2.4/tests/server → fastmcp-2.2.6/tests/resources}/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/resources/test_file_resources.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/resources/test_function_resources.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/resources/test_resource_manager.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/resources/test_resource_template.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/resources/test_resources.py +0 -0
- {fastmcp-2.2.4/tests/tools → fastmcp-2.2.6/tests/server}/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/server/test_file_server.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/server/test_import_server.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/server/test_lifespan.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/server/test_mount.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/server/test_proxy.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/server/test_run_server.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/test_servers/fastmcp_server.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/test_servers/sse.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/test_servers/stdio.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/tools/test_tool_manager.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/utilities/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/utilities/openapi/__init__.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/utilities/openapi/conftest.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/utilities/openapi/test_openapi.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/utilities/openapi/test_openapi_advanced.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/utilities/openapi/test_openapi_fastapi.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/utilities/test_decorated_function.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/utilities/test_func_metadata.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/tests/utilities/test_logging.py +0 -0
- {fastmcp-2.2.4 → fastmcp-2.2.6}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastmcp
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.6
|
|
4
4
|
Summary: The fast, Pythonic way to build MCP servers.
|
|
5
5
|
Project-URL: Homepage, https://gofastmcp.com
|
|
6
6
|
Project-URL: Repository, https://github.com/jlowin/fastmcp
|
|
@@ -24,7 +24,7 @@ Requires-Dist: openapi-pydantic>=0.5.1
|
|
|
24
24
|
Requires-Dist: python-dotenv>=1.1.0
|
|
25
25
|
Requires-Dist: rich>=13.9.4
|
|
26
26
|
Requires-Dist: typer>=0.15.2
|
|
27
|
-
Requires-Dist: websockets>=
|
|
27
|
+
Requires-Dist: websockets>=14.0
|
|
28
28
|
Description-Content-Type: text/markdown
|
|
29
29
|
|
|
30
30
|
<div align="center">
|
|
@@ -149,83 +149,90 @@ The `Client` provides methods corresponding to standard MCP requests:
|
|
|
149
149
|
* **`list_prompts()`**: Retrieves available prompt templates.
|
|
150
150
|
* **`get_prompt(name: str, arguments: dict[str, Any] | None = None)`**: Retrieves a rendered prompt message list.
|
|
151
151
|
|
|
152
|
-
###
|
|
152
|
+
### Advanced Features
|
|
153
153
|
|
|
154
|
-
MCP allows servers to
|
|
154
|
+
MCP allows servers to interact with clients in order to provide additional capabilities. The `Client` constructor accepts additional configuration to handle these server requests.
|
|
155
155
|
|
|
156
|
-
#### Roots
|
|
157
156
|
|
|
158
|
-
|
|
159
|
-
```python
|
|
160
|
-
from pathlib import Path
|
|
161
|
-
from fastmcp.client.roots import RootsHandler, RootsList
|
|
162
|
-
from mcp.shared.context import RequestContext # For type hint
|
|
163
|
-
|
|
164
|
-
# Option 1: Static list
|
|
165
|
-
static_roots: RootsList = [str(Path.home() / "Documents")]
|
|
166
|
-
|
|
167
|
-
# Option 2: Dynamic function
|
|
168
|
-
def dynamic_roots_handler(context: RequestContext) -> RootsList:
|
|
169
|
-
# Logic to determine accessible roots based on context
|
|
170
|
-
print(f"Server requested roots (Request ID: {context.request_id})")
|
|
171
|
-
return [str(Path.home() / "Downloads")]
|
|
172
|
-
|
|
173
|
-
client_with_roots = Client(
|
|
174
|
-
"my_server.py",
|
|
175
|
-
roots=dynamic_roots_handler # or roots=static_roots
|
|
176
|
-
)
|
|
157
|
+
#### LLM Sampling
|
|
177
158
|
|
|
178
|
-
|
|
179
|
-
# async with client_with_roots:
|
|
180
|
-
# await client_with_roots.send_roots_list_changed()
|
|
181
|
-
```
|
|
182
|
-
See `fastmcp.client.roots` for helpers.
|
|
159
|
+
MCP Servers can request LLM completions from clients. The client can provide a `sampling_handler` to handle these requests. The sampling handler receives a list of messages and other parameters from the server, and should return a string completion.
|
|
183
160
|
|
|
184
|
-
|
|
161
|
+
The following example uses the `marvin` library to generate a completion:
|
|
185
162
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
response_text = f"LLM processed: {prompt[:50]}..."
|
|
204
|
-
# Return simple string (becomes TextContent) or a MessageResult object
|
|
205
|
-
return response_text
|
|
206
|
-
|
|
207
|
-
client_with_sampling = Client(
|
|
208
|
-
"my_server.py",
|
|
209
|
-
sampling_handler=my_llm_handler
|
|
163
|
+
```python {8-17, 21}
|
|
164
|
+
import marvin
|
|
165
|
+
from fastmcp import Client
|
|
166
|
+
from fastmcp.client.sampling import (
|
|
167
|
+
SamplingMessage,
|
|
168
|
+
SamplingParams,
|
|
169
|
+
RequestContext,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
async def sampling_handler(
|
|
173
|
+
messages: list[SamplingMessage],
|
|
174
|
+
params: SamplingParams,
|
|
175
|
+
context: RequestContext
|
|
176
|
+
) -> str:
|
|
177
|
+
return await marvin.say_async(
|
|
178
|
+
message=[m.content.text for m in messages],
|
|
179
|
+
instructions=params.systemPrompt,
|
|
210
180
|
)
|
|
211
|
-
|
|
212
|
-
|
|
181
|
+
|
|
182
|
+
client = Client(
|
|
183
|
+
...,
|
|
184
|
+
sampling_handler=sampling_handler,
|
|
185
|
+
)
|
|
186
|
+
```
|
|
213
187
|
|
|
214
188
|
#### Logging
|
|
215
189
|
|
|
216
|
-
|
|
217
|
-
```python
|
|
218
|
-
from mcp.client.session import LoggingFnT, LogLevel
|
|
190
|
+
MCP servers can emit logs to clients. The client can set a logging callback to receive these logs.
|
|
219
191
|
|
|
220
|
-
|
|
221
|
-
|
|
192
|
+
```python {4-5, 9}
|
|
193
|
+
from fastmcp import Client
|
|
194
|
+
from fastmcp.client.logging import LogHandler, LogMessage
|
|
222
195
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
log_handler=my_log_handler
|
|
226
|
-
)
|
|
227
|
-
```
|
|
196
|
+
async def my_log_handler(params: LogMessage):
|
|
197
|
+
print(f"[Server Log - {params.level.upper()}] {params.logger or 'default'}: {params.data}")
|
|
228
198
|
|
|
199
|
+
client_with_logging = Client(
|
|
200
|
+
...,
|
|
201
|
+
log_handler=my_log_handler,
|
|
202
|
+
)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
#### Roots
|
|
206
|
+
|
|
207
|
+
Roots are a way for clients to inform servers about the resources they have access to or certain boundaries on their access. The server can use this information to adjust behavior or provide more accurate responses.
|
|
208
|
+
|
|
209
|
+
Servers can request roots from clients, and clients can notify servers when their roots change.
|
|
210
|
+
|
|
211
|
+
To set the roots when creating a client, users can either provide a list of roots (which can be a list of strings) or an async function that returns a list of roots.
|
|
212
|
+
|
|
213
|
+
<CodeGroup>
|
|
214
|
+
```python Static Roots {5}
|
|
215
|
+
from fastmcp import Client
|
|
216
|
+
|
|
217
|
+
client = Client(
|
|
218
|
+
...,
|
|
219
|
+
roots=["/path/to/root1", "/path/to/root2"],
|
|
220
|
+
)
|
|
221
|
+
```
|
|
222
|
+
```python Dynamic Roots Callback {4-6, 10}
|
|
223
|
+
from fastmcp import Client
|
|
224
|
+
from fastmcp.client.roots import RequestContext
|
|
225
|
+
|
|
226
|
+
async def roots_callback(context: RequestContext) -> list[str]:
|
|
227
|
+
print(f"Server requested roots (Request ID: {context.request_id})")
|
|
228
|
+
return ["/path/to/root1", "/path/to/root2"]
|
|
229
|
+
|
|
230
|
+
client = Client(
|
|
231
|
+
...,
|
|
232
|
+
roots=roots_callback,
|
|
233
|
+
)
|
|
234
|
+
```
|
|
235
|
+
</CodeGroup>
|
|
229
236
|
### Utility Methods
|
|
230
237
|
|
|
231
238
|
* **`ping()`**: Sends a ping request to the server to verify connectivity.
|
|
@@ -44,6 +44,19 @@ if __name__ == "__main__":
|
|
|
44
44
|
mcp.run() # Start the MCP server
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
## Configuration Options
|
|
48
|
+
|
|
49
|
+
### Timeout
|
|
50
|
+
|
|
51
|
+
You can set a timeout for all API requests:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
# Set a 5 second timeout for all requests
|
|
55
|
+
mcp = FastMCP.from_fastapi(app=app, timeout=5.0)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This timeout is applied to all requests made by tools, resources, and resource templates.
|
|
59
|
+
|
|
47
60
|
## Route Mapping
|
|
48
61
|
|
|
49
62
|
By default, FastMCP will map FastAPI routes to MCP components according to the following rules:
|
|
@@ -60,7 +73,7 @@ For more details on route mapping or custom mapping rules, see the [OpenAPI inte
|
|
|
60
73
|
|
|
61
74
|
Here's a more detailed example with a data model:
|
|
62
75
|
|
|
63
|
-
```python
|
|
76
|
+
```python [expandable]
|
|
64
77
|
import asyncio
|
|
65
78
|
from fastapi import FastAPI, HTTPException
|
|
66
79
|
from pydantic import BaseModel
|
|
@@ -95,24 +108,32 @@ def create_item(item: Item):
|
|
|
95
108
|
return items[item_id]
|
|
96
109
|
|
|
97
110
|
# Test your MCP server with a client
|
|
98
|
-
async def
|
|
99
|
-
# Create MCP server from FastAPI app
|
|
100
|
-
mcp = await FastMCP.from_fastapi(app=app)
|
|
101
|
-
|
|
111
|
+
async def check_mcp(mcp: FastMCP):
|
|
102
112
|
# List the components that were created
|
|
103
|
-
tools = await mcp.
|
|
104
|
-
resources = await mcp.
|
|
105
|
-
templates = await mcp.
|
|
113
|
+
tools = await mcp.get_tools()
|
|
114
|
+
resources = await mcp.get_resources()
|
|
115
|
+
templates = await mcp.get_resource_templates()
|
|
106
116
|
|
|
107
|
-
print(
|
|
108
|
-
|
|
109
|
-
|
|
117
|
+
print(
|
|
118
|
+
f"{len(tools)} Tool(s): {', '.join([t.name for t in tools.values()])}"
|
|
119
|
+
)
|
|
120
|
+
print(
|
|
121
|
+
f"{len(resources)} Resource(s): {', '.join([r.name for r in resources.values()])}"
|
|
122
|
+
)
|
|
123
|
+
print(
|
|
124
|
+
f"{len(templates)} Resource Template(s): {', '.join([t.name for t in templates.values()])}"
|
|
125
|
+
)
|
|
110
126
|
|
|
111
|
-
|
|
112
|
-
# mcp.run()
|
|
127
|
+
return mcp
|
|
113
128
|
|
|
114
129
|
if __name__ == "__main__":
|
|
115
|
-
|
|
130
|
+
# Create MCP server from FastAPI app
|
|
131
|
+
mcp = FastMCP.from_fastapi(app=app)
|
|
132
|
+
|
|
133
|
+
asyncio.run(check_mcp(mcp))
|
|
134
|
+
|
|
135
|
+
# In a real scenario, you would run the server:
|
|
136
|
+
mcp.run()
|
|
116
137
|
```
|
|
117
138
|
|
|
118
139
|
## Benefits
|
|
@@ -27,6 +27,23 @@ if __name__ == "__main__":
|
|
|
27
27
|
mcp.run()
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
## Configuration Options
|
|
31
|
+
|
|
32
|
+
### Timeout
|
|
33
|
+
|
|
34
|
+
You can set a timeout for all API requests:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
# Set a 5 second timeout for all requests
|
|
38
|
+
mcp = FastMCP.from_openapi(
|
|
39
|
+
openapi_spec=spec,
|
|
40
|
+
client=api_client,
|
|
41
|
+
timeout=5.0
|
|
42
|
+
)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
This timeout is applied to all requests made by tools, resources, and resource templates.
|
|
46
|
+
|
|
30
47
|
## Route Mapping
|
|
31
48
|
|
|
32
49
|
By default, OpenAPI routes are mapped to MCP components based on these rules:
|
|
@@ -89,26 +106,67 @@ mcp = await FastMCP.from_openapi(
|
|
|
89
106
|
- It sends the request through the provided httpx client
|
|
90
107
|
- It translates the HTTP response to the appropriate MCP format
|
|
91
108
|
|
|
92
|
-
|
|
109
|
+
### Request Parameter Handling
|
|
110
|
+
|
|
111
|
+
FastMCP carefully handles different types of parameters in OpenAPI requests:
|
|
112
|
+
|
|
113
|
+
#### Query Parameters
|
|
114
|
+
|
|
115
|
+
By default, FastMCP will only include query parameters that have non-empty values. Parameters with `None` values or empty strings (`""`) are automatically filtered out of requests. This ensures that API servers don't receive unnecessary empty parameters that might cause issues.
|
|
93
116
|
|
|
117
|
+
For example, if you call a tool with these parameters:
|
|
94
118
|
```python
|
|
119
|
+
await client.call_tool("search_products", {
|
|
120
|
+
"category": "electronics", # Will be included
|
|
121
|
+
"min_price": 100, # Will be included
|
|
122
|
+
"max_price": None, # Will be excluded
|
|
123
|
+
"brand": "", # Will be excluded
|
|
124
|
+
})
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The resulting HTTP request will only include `category=electronics&min_price=100`.
|
|
128
|
+
|
|
129
|
+
#### Path Parameters
|
|
130
|
+
|
|
131
|
+
For path parameters, which are typically required by REST APIs, FastMCP filters out `None` values and checks that all required path parameters are provided. If a required path parameter is missing or `None`, an error will be raised.
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
# This will work
|
|
135
|
+
await client.call_tool("get_product", {"product_id": 123})
|
|
136
|
+
|
|
137
|
+
# This will raise ValueError: "Missing required path parameters: {'product_id'}"
|
|
138
|
+
await client.call_tool("get_product", {"product_id": None})
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Complete Example
|
|
142
|
+
|
|
143
|
+
```python [expandable]
|
|
95
144
|
import asyncio
|
|
145
|
+
|
|
96
146
|
import httpx
|
|
147
|
+
|
|
97
148
|
from fastmcp import FastMCP
|
|
98
149
|
|
|
99
150
|
# Sample OpenAPI spec for a Pet Store API
|
|
100
151
|
petstore_spec = {
|
|
101
152
|
"openapi": "3.0.0",
|
|
153
|
+
"info": {
|
|
154
|
+
"title": "Pet Store API",
|
|
155
|
+
"version": "1.0.0",
|
|
156
|
+
"description": "A sample API for managing pets",
|
|
157
|
+
},
|
|
102
158
|
"paths": {
|
|
103
159
|
"/pets": {
|
|
104
160
|
"get": {
|
|
105
161
|
"operationId": "listPets",
|
|
106
|
-
"summary": "List all pets"
|
|
162
|
+
"summary": "List all pets",
|
|
163
|
+
"responses": {"200": {"description": "A list of pets"}},
|
|
107
164
|
},
|
|
108
165
|
"post": {
|
|
109
166
|
"operationId": "createPet",
|
|
110
|
-
"summary": "Create a new pet"
|
|
111
|
-
|
|
167
|
+
"summary": "Create a new pet",
|
|
168
|
+
"responses": {"201": {"description": "Pet created successfully"}},
|
|
169
|
+
},
|
|
112
170
|
},
|
|
113
171
|
"/pets/{petId}": {
|
|
114
172
|
"get": {
|
|
@@ -119,38 +177,50 @@ petstore_spec = {
|
|
|
119
177
|
"name": "petId",
|
|
120
178
|
"in": "path",
|
|
121
179
|
"required": True,
|
|
122
|
-
"schema": {"type": "string"}
|
|
180
|
+
"schema": {"type": "string"},
|
|
123
181
|
}
|
|
124
|
-
]
|
|
182
|
+
],
|
|
183
|
+
"responses": {
|
|
184
|
+
"200": {"description": "Pet details"},
|
|
185
|
+
"404": {"description": "Pet not found"},
|
|
186
|
+
},
|
|
125
187
|
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
188
|
+
},
|
|
189
|
+
},
|
|
128
190
|
}
|
|
129
191
|
|
|
130
|
-
|
|
192
|
+
|
|
193
|
+
async def check_mcp(mcp: FastMCP):
|
|
194
|
+
# List what components were created
|
|
195
|
+
tools = await mcp.get_tools()
|
|
196
|
+
resources = await mcp.get_resources()
|
|
197
|
+
templates = await mcp.get_resource_templates()
|
|
198
|
+
|
|
199
|
+
print(
|
|
200
|
+
f"{len(tools)} Tool(s): {', '.join([t.name for t in tools.values()])}"
|
|
201
|
+
) # Should include createPet
|
|
202
|
+
print(
|
|
203
|
+
f"{len(resources)} Resource(s): {', '.join([r.name for r in resources.values()])}"
|
|
204
|
+
) # Should include listPets
|
|
205
|
+
print(
|
|
206
|
+
f"{len(templates)} Resource Template(s): {', '.join([t.name for t in templates.values()])}"
|
|
207
|
+
) # Should include getPet
|
|
208
|
+
|
|
209
|
+
return mcp
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
if __name__ == "__main__":
|
|
131
213
|
# Client for the Pet Store API
|
|
132
214
|
client = httpx.AsyncClient(base_url="https://petstore.example.com/api")
|
|
133
|
-
|
|
215
|
+
|
|
134
216
|
# Create the MCP server
|
|
135
|
-
mcp =
|
|
136
|
-
openapi_spec=petstore_spec,
|
|
137
|
-
client=client,
|
|
138
|
-
name="PetStore"
|
|
217
|
+
mcp = FastMCP.from_openapi(
|
|
218
|
+
openapi_spec=petstore_spec, client=client, name="PetStore"
|
|
139
219
|
)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
resources = await mcp.list_resources()
|
|
144
|
-
templates = await mcp.list_resource_templates()
|
|
145
|
-
|
|
146
|
-
print(f"Tools: {len(tools)}") # Should include createPet
|
|
147
|
-
print(f"Resources: {len(resources)}") # Should include listPets
|
|
148
|
-
print(f"Templates: {len(templates)}") # Should include getPet
|
|
149
|
-
|
|
220
|
+
|
|
221
|
+
asyncio.run(check_mcp(mcp))
|
|
222
|
+
|
|
150
223
|
# Start the MCP server
|
|
151
224
|
mcp.run()
|
|
152
|
-
|
|
153
|
-
if __name__ == "__main__":
|
|
154
|
-
asyncio.run(main())
|
|
155
225
|
```
|
|
156
226
|
|
|
@@ -0,0 +1,38 @@
|
|
|
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 "Hello, World!" in str(result[0])
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
This pattern creates a direct connection between the client and server, allowing you to test your server's functionality efficiently.
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: MCP Context
|
|
3
3
|
sidebarTitle: Context
|
|
4
|
-
description: Access MCP capabilities like logging, progress, and resources within your
|
|
4
|
+
description: Access MCP capabilities like logging, progress, and resources within your MCP objects.
|
|
5
5
|
icon: rectangle-code
|
|
6
6
|
---
|
|
7
7
|
import { VersionBadge } from '/snippets/version-badge.mdx'
|
|
8
8
|
|
|
9
|
-
When defining FastMCP [tools](/servers/tools), your functions might need to interact with the underlying MCP session or access server capabilities. FastMCP provides the `Context` object for this purpose.
|
|
9
|
+
When defining FastMCP [tools](/servers/tools), [resources](/servers/resources), resource templates, or [prompts](/servers/prompts), your functions might need to interact with the underlying MCP session or access server capabilities. FastMCP provides the `Context` object for this purpose.
|
|
10
10
|
|
|
11
11
|
## What Is Context?
|
|
12
12
|
|
|
13
|
-
The `Context` object provides a clean interface to access MCP features within your
|
|
13
|
+
The `Context` object provides a clean interface to access MCP features within your functions, including:
|
|
14
14
|
|
|
15
15
|
- **Logging**: Send debug, info, warning, and error messages back to the client
|
|
16
16
|
- **Progress Reporting**: Update the client on the progress of long-running operations
|
|
@@ -19,9 +19,9 @@ The `Context` object provides a clean interface to access MCP features within yo
|
|
|
19
19
|
- **Request Information**: Access metadata about the current request
|
|
20
20
|
- **Server Access**: When needed, access the underlying FastMCP server instance
|
|
21
21
|
|
|
22
|
-
## Accessing Context
|
|
22
|
+
## Accessing the Context
|
|
23
23
|
|
|
24
|
-
To use the context object within your
|
|
24
|
+
To use the context object within any of your functions, simply add a parameter to your function signature and type-hint it as `Context`. FastMCP will automatically inject the context instance when your function is called.
|
|
25
25
|
|
|
26
26
|
```python
|
|
27
27
|
from fastmcp import FastMCP, Context
|
|
@@ -65,15 +65,15 @@ async def process_file(file_uri: str, ctx: Context) -> str:
|
|
|
65
65
|
|
|
66
66
|
- The parameter name (e.g., `ctx`, `context`) doesn't matter, only the type hint `Context` is important.
|
|
67
67
|
- The context parameter can be placed anywhere in your function's signature.
|
|
68
|
-
- The context is optional -
|
|
69
|
-
- Context is only available
|
|
70
|
-
- Context methods are async, so your
|
|
68
|
+
- The context is optional - functions that don't need it can omit the parameter.
|
|
69
|
+
- Context is only available during a request; attempting to use context methods outside a request will raise errors.
|
|
70
|
+
- Context methods are async, so your function usually needs to be async as well.
|
|
71
71
|
|
|
72
72
|
## Context Capabilities
|
|
73
73
|
|
|
74
74
|
### Logging
|
|
75
75
|
|
|
76
|
-
Send log messages back to the MCP client. This is useful for debugging and providing visibility into
|
|
76
|
+
Send log messages back to the MCP client. This is useful for debugging and providing visibility into function execution during a request.
|
|
77
77
|
|
|
78
78
|
```python
|
|
79
79
|
@mcp.tool()
|
|
@@ -97,14 +97,14 @@ async def analyze_data(data: list[float], ctx: Context) -> dict:
|
|
|
97
97
|
**Available Logging Methods:**
|
|
98
98
|
|
|
99
99
|
- **`ctx.debug(message: str)`**: Low-level details useful for debugging
|
|
100
|
-
- **`ctx.info(message: str)`**: General information about
|
|
100
|
+
- **`ctx.info(message: str)`**: General information about execution
|
|
101
101
|
- **`ctx.warning(message: str)`**: Potential issues that didn't prevent execution
|
|
102
102
|
- **`ctx.error(message: str)`**: Errors that occurred during execution
|
|
103
103
|
- **`ctx.log(level: Literal["debug", "info", "warning", "error"], message: str, logger_name: str | None = None)`**: Generic log method supporting custom logger names
|
|
104
104
|
|
|
105
105
|
### Progress Reporting
|
|
106
106
|
|
|
107
|
-
For long-running
|
|
107
|
+
For long-running operations, notify the client about the progress. This allows clients to display progress indicators and provide a better user experience.
|
|
108
108
|
|
|
109
109
|
```python
|
|
110
110
|
@mcp.tool()
|
|
@@ -137,7 +137,7 @@ Progress reporting requires the client to have sent a `progressToken` in the ini
|
|
|
137
137
|
|
|
138
138
|
### Resource Access
|
|
139
139
|
|
|
140
|
-
Read data from resources registered with your FastMCP server. This allows
|
|
140
|
+
Read data from resources registered with your FastMCP server. This allows functions to access files, configuration, or dynamically generated content.
|
|
141
141
|
|
|
142
142
|
```python
|
|
143
143
|
@mcp.tool()
|
|
@@ -177,7 +177,7 @@ The returned content is typically accessed via `content_list[0].content` and can
|
|
|
177
177
|
|
|
178
178
|
<VersionBadge version="2.0.0" />
|
|
179
179
|
|
|
180
|
-
Request the client's LLM to generate text based on provided messages. This is useful when your
|
|
180
|
+
Request the client's LLM to generate text based on provided messages. This is useful when your function needs to leverage the LLM's capabilities to process data or generate responses.
|
|
181
181
|
|
|
182
182
|
```python
|
|
183
183
|
@mcp.tool()
|
|
@@ -279,6 +279,60 @@ async def advanced_tool(ctx: Context) -> str:
|
|
|
279
279
|
Direct use of `session` or `request_context` requires understanding the low-level MCP Python SDK and may be less stable than using the methods provided directly on the `Context` object.
|
|
280
280
|
</Warning>
|
|
281
281
|
|
|
282
|
-
## Using Context in
|
|
282
|
+
## Using Context in Different Components
|
|
283
283
|
|
|
284
|
-
|
|
284
|
+
All FastMCP components (tools, resources, templates, and prompts) can use the Context object following the same pattern - simply add a parameter with the `Context` type annotation.
|
|
285
|
+
|
|
286
|
+
### Context in Resources and Templates
|
|
287
|
+
|
|
288
|
+
Resources and resource templates can access context to customize their behavior:
|
|
289
|
+
|
|
290
|
+
```python
|
|
291
|
+
@mcp.resource("resource://user-data")
|
|
292
|
+
async def get_user_data(ctx: Context) -> dict:
|
|
293
|
+
"""Fetch personalized user data based on the request context."""
|
|
294
|
+
user_id = ctx.client_id or "anonymous"
|
|
295
|
+
await ctx.info(f"Fetching data for user {user_id}")
|
|
296
|
+
|
|
297
|
+
# Example of using context for dynamic resource generation
|
|
298
|
+
return {
|
|
299
|
+
"user_id": user_id,
|
|
300
|
+
"last_access": datetime.now().isoformat(),
|
|
301
|
+
"request_id": ctx.request_id
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
@mcp.resource("resource://users/{user_id}/profile")
|
|
305
|
+
async def get_user_profile(user_id: str, ctx: Context) -> dict:
|
|
306
|
+
"""Fetch user profile from database with context-aware logging."""
|
|
307
|
+
await ctx.info(f"Fetching profile for user {user_id}")
|
|
308
|
+
|
|
309
|
+
# Example of using context in a template resource
|
|
310
|
+
# In a real implementation, you might query a database
|
|
311
|
+
return {
|
|
312
|
+
"id": user_id,
|
|
313
|
+
"name": f"User {user_id}",
|
|
314
|
+
"request_id": ctx.request_id
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Context in Prompts
|
|
319
|
+
|
|
320
|
+
Prompts can use context to generate more dynamic templates:
|
|
321
|
+
|
|
322
|
+
```python
|
|
323
|
+
@mcp.prompt()
|
|
324
|
+
async def data_analysis_request(dataset: str, ctx: Context) -> str:
|
|
325
|
+
"""Generate a request to analyze data with contextual information."""
|
|
326
|
+
await ctx.info(f"Generating data analysis prompt for {dataset}")
|
|
327
|
+
|
|
328
|
+
# Could use context to read configuration or personalize the prompt
|
|
329
|
+
return f"""Please analyze the following dataset: {dataset}
|
|
330
|
+
|
|
331
|
+
Request initiated at: {datetime.now().isoformat()}
|
|
332
|
+
Request ID: {ctx.request_id}
|
|
333
|
+
"""
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
<VersionBadge version="2.3.0" />
|
|
337
|
+
|
|
338
|
+
All FastMCP objects now support context injection using the same consistent pattern, making it easy to add session-aware capabilities to all aspects of your MCP server.
|
|
@@ -20,7 +20,7 @@ Prompts provide parameterized message templates for LLMs. When a client requests
|
|
|
20
20
|
|
|
21
21
|
This allows you to define consistent, reusable templates that LLMs can use across different clients and contexts.
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## Prompts
|
|
24
24
|
|
|
25
25
|
### The `@prompt` Decorator
|
|
26
26
|
|
|
@@ -171,33 +171,24 @@ async def data_based_prompt(data_id: str) -> str:
|
|
|
171
171
|
|
|
172
172
|
Use `async def` when your prompt function performs I/O operations like network requests, database queries, file I/O, or external service calls.
|
|
173
173
|
|
|
174
|
-
###
|
|
174
|
+
### Accessing MCP Context
|
|
175
175
|
|
|
176
|
-
|
|
176
|
+
<VersionBadge version="2.2.5" />
|
|
177
177
|
|
|
178
|
-
|
|
179
|
-
|
|
178
|
+
Prompts can access additional MCP information and features through the `Context` object. To access it, add a parameter to your prompt function with a type annotation of `Context`:
|
|
179
|
+
|
|
180
|
+
```python {6}
|
|
181
|
+
from fastmcp import FastMCP, Context
|
|
182
|
+
|
|
183
|
+
mcp = FastMCP(name="PromptServer")
|
|
180
184
|
|
|
181
185
|
@mcp.prompt()
|
|
182
186
|
async def generate_report_request(report_type: str, ctx: Context) -> str:
|
|
183
|
-
"""Generates a request for a report
|
|
184
|
-
|
|
185
|
-
await ctx.info(f"Generating prompt for report type: {report_type}")
|
|
186
|
-
|
|
187
|
-
# Could potentially use ctx.read_resource to fetch data
|
|
188
|
-
# Or ctx.sample to get additional input from the LLM
|
|
189
|
-
|
|
190
|
-
return f"Please create a {report_type} report based on the available data."
|
|
187
|
+
"""Generates a request for a report."""
|
|
188
|
+
return f"Please create a {report_type} report. Request ID: {ctx.request_id}"
|
|
191
189
|
```
|
|
192
190
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
- **Logging:** `ctx.debug()`, `ctx.info()`, etc.
|
|
196
|
-
- **Resource Access:** `ctx.read_resource(uri)`
|
|
197
|
-
- **LLM Sampling:** `ctx.sample(...)`
|
|
198
|
-
- **Request Info:** `ctx.request_id`, `ctx.client_id`
|
|
199
|
-
|
|
200
|
-
Refer to the [Context documentation](/servers/context) for more details on these capabilities.
|
|
191
|
+
For full documentation on the Context object and all its capabilities, see the [Context documentation](/servers/context).
|
|
201
192
|
|
|
202
193
|
## Server Behavior
|
|
203
194
|
|