Skip to content

Commit a359b0b

Browse files
authored
Document client meta parameter for sending ancillary request data (#2367)
1 parent 80d10d2 commit a359b0b

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

docs/clients/tools.mdx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,31 @@ async with client:
101101
- `arguments`: Dictionary of arguments to pass to the tool (optional)
102102
- `timeout`: Maximum execution time in seconds (optional, overrides client-level timeout)
103103
- `progress_handler`: Progress callback function (optional, overrides client-level handler)
104+
- `meta`: Dictionary of metadata to send with the request (optional, see below)
105+
106+
## Sending Metadata
107+
108+
<VersionBadge version="2.13.1" />
109+
110+
The `meta` parameter sends ancillary information alongside tool calls. This can be used for various purposes like observability, debugging, client identification, or any context the server may need beyond the tool's primary arguments.
111+
112+
```python
113+
async with client:
114+
result = await client.call_tool(
115+
name="send_email",
116+
arguments={
117+
118+
"subject": "Hello",
119+
"body": "Welcome!"
120+
},
121+
meta={
122+
"trace_id": "abc-123",
123+
"request_source": "mobile_app"
124+
}
125+
)
126+
```
127+
128+
The structure and usage of `meta` is determined by your application. See [Client Metadata](/servers/context#client-metadata) in the server documentation to learn how to access this data in your tool implementations.
104129

105130
## Handling Results
106131

docs/servers/context.mdx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,35 @@ async def request_info(ctx: Context) -> dict:
313313
- **`ctx.client_id -> str | None`**: Get the ID of the client making the request, if provided during initialization
314314
- **`ctx.session_id -> str | None`**: Get the MCP session ID for session-based data sharing (HTTP transports only)
315315

316+
#### Client Metadata
317+
318+
<VersionBadge version="2.13.1" />
319+
320+
Clients can send contextual information with their requests using the `meta` parameter. This metadata is accessible through `ctx.request_context.meta` and is available for all MCP operations (tools, resources, prompts).
321+
322+
The `meta` field is `None` when clients don't provide metadata. When provided, metadata is accessible via attribute access (e.g., `meta.user_id`) rather than dictionary access. The structure of metadata is determined by the client making the request.
323+
324+
```python
325+
@mcp.tool
326+
def send_email(to: str, subject: str, body: str, ctx: Context) -> str:
327+
"""Send an email, logging metadata about the request."""
328+
329+
# Access client-provided metadata
330+
meta = ctx.request_context.meta
331+
332+
if meta:
333+
# Meta is accessed as an object with attribute access
334+
user_id = meta.user_id if hasattr(meta, 'user_id') else None
335+
trace_id = meta.trace_id if hasattr(meta, 'trace_id') else None
336+
337+
# Use metadata for logging, observability, etc.
338+
if trace_id:
339+
log_with_trace(f"Sending email for user {user_id}", trace_id)
340+
341+
# Send the email...
342+
return f"Email sent to {to}"
343+
```
344+
316345
<Warning>
317346
The MCP request is part of the low-level MCP SDK and intended for advanced use cases. Most users will not need to use it directly.
318347
</Warning>

src/fastmcp/client/client.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -892,7 +892,10 @@ async def call_tool_mcp(
892892
arguments (dict[str, Any]): Arguments to pass to the tool.
893893
timeout (datetime.timedelta | float | int | None, optional): The timeout for the tool call. Defaults to None.
894894
progress_handler (ProgressHandler | None, optional): The progress handler to use for the tool call. Defaults to None.
895-
meta (dict[str, Any] | None, optional): Additional metadata to send with the tool call.
895+
meta (dict[str, Any] | None, optional): Additional metadata to include with the request.
896+
This is useful for passing contextual information (like user IDs, trace IDs, or preferences)
897+
that shouldn't be tool arguments but may influence server-side processing. The server
898+
can access this via `context.request_context.meta`. Defaults to None.
896899
897900
Returns:
898901
mcp.types.CallToolResult: The complete response object from the protocol,
@@ -935,7 +938,10 @@ async def call_tool(
935938
timeout (datetime.timedelta | float | int | None, optional): The timeout for the tool call. Defaults to None.
936939
progress_handler (ProgressHandler | None, optional): The progress handler to use for the tool call. Defaults to None.
937940
raise_on_error (bool, optional): Whether to raise a ToolError if the tool call results in an error. Defaults to True.
938-
meta (dict[str, Any] | None, optional): Additional metadata to send with the tool call.
941+
meta (dict[str, Any] | None, optional): Additional metadata to include with the request.
942+
This is useful for passing contextual information (like user IDs, trace IDs, or preferences)
943+
that shouldn't be tool arguments but may influence server-side processing. The server
944+
can access this via `context.request_context.meta`. Defaults to None.
939945
940946
Returns:
941947
CallToolResult:

0 commit comments

Comments
 (0)