Python: [BREAKING] Add sampling guardrails to MCP tools#6413
Merged
Conversation
Contributor
Python Test Coverage Report •
Python Unit Test Overview
|
||||||||||||||||||||||||||||||
Contributor
There was a problem hiding this comment.
Pull request overview
Adds opt-in safety guardrails around server-initiated MCP sampling (sampling/createMessage) in the Python Agent Framework MCP tools, making sampling deny-by-default unless explicitly approved by the caller.
Changes:
- Introduces
sampling_approval_callback,sampling_max_tokens, andsampling_max_requestsconstructor parameters onMCPTooland subclasses, and enforces them in the defaultsampling_callback. - Exports
SamplingApprovalCallbackin the public Python API and documents the new deny-by-default behavior (including changelog entry). - Adds unit tests plus a new sample demonstrating human-in-the-loop sampling approval.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| python/samples/02-agents/mcp/README.md | Adds the new sampling-approval sample to the MCP samples index. |
| python/samples/02-agents/mcp/mcp_sampling_approval.py | New sample showing approval gating + token/request caps for MCP sampling. |
| python/packages/core/tests/core/test_mcp.py | Adds coverage for deny-by-default, callback approval/denial, maxTokens clamping, and per-session request caps. |
| python/packages/core/AGENTS.md | Documents the sampling guardrails and their default behavior/order of enforcement. |
| python/packages/core/agent_framework/_mcp.py | Implements sampling guardrails (approval gate, maxTokens cap, per-session request cap) and warning-level logging (counts only). |
| python/packages/core/agent_framework/init.py | Exports SamplingApprovalCallback from the package public surface. |
| python/CHANGELOG.md | Documents the breaking deny-by-default MCP sampling behavior under Security. |
TaoChenOSU
approved these changes
Jun 9, 2026
moonbox3
approved these changes
Jun 10, 2026
52843e6 to
cada5f7
Compare
Add approval, token, and request-count controls to the MCP sampling callback used when an MCPTool is configured with a chat client. - Add `sampling_approval_callback`, `sampling_max_tokens`, and `sampling_max_requests` parameters to `MCPTool` and its `MCPStdioTool`, `MCPStreamableHTTPTool`, and `MCPWebsocketTool` subclasses, positioned directly after `client`. - Gate each server-initiated `sampling/createMessage` request behind the approval callback, which denies by default when no callback is provided. - Clamp the requested `maxTokens` to `sampling_max_tokens` and enforce a per-session request count via `sampling_max_requests`. - Log incoming sampling requests at WARNING level (counts only). - Export `SamplingApprovalCallback` from the public API. - Add tests, a sample, and documentation updates. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Distinguish the deny-by-default case (no approval callback configured) from an explicit denial by a configured `sampling_approval_callback`, so the returned ErrorData message is accurate for callback-driven denials and exceptions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
cada5f7 to
87aab48
Compare
moonbox3
approved these changes
Jun 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation and Context
The MCP tools (
MCPStdioTool,MCPStreamableHTTPTool,MCPWebsocketTool)register a
sampling_callbackwhenever they are configured with a chatclient. Previously every server-initiated
sampling/createMessagerequestwas forwarded to the chat client as-is, with no caller control over whether
the request was allowed, how many tokens it could request, or how many
requests a session could make.
Description
Adds opt-in guardrails to the MCP sampling callback, exposed as three new
constructor parameters on
MCPTooland its subclasses, positioned directlyafter
client:sampling_approval_callback: a sync or async gate invoked with the rawCreateMessageRequestParamsbefore the request reaches the chat client.A truthy return approves the request, a falsy return denies it. When
None(the default) every sampling request is denied.sampling_max_tokens: clamps an approved request'smaxTokenstomin(requested, cap). Defaults to 4096;Nonedisables the clamp.sampling_max_requests: per-session cap on the number of samplingrequests, reset on reconnect. Defaults to 25;
Nonedisables the cap.Additional changes:
content).
SamplingApprovalCallbackis exported from the public API.mcp_sampling_approval.py), and documentationupdates.
This is a breaking change: by default, sampling requests are now denied
unless a
sampling_approval_callbackis supplied. To restore the previousauto-approve behavior, pass
sampling_approval_callback=lambda params: True.Contribution Checklist