Skip to content

Conversation

@DaleSeo
Copy link
Contributor

@DaleSeo DaleSeo commented Jan 24, 2026

Closes #552

Motivation and Context

This PR implements SEP-1577: Sampling With Tools, enabling MCP servers to run agentic loops using the client's LLM while maintaining user supervision.

Key additions:

  • ToolChoice / ToolChoiceMode - Control tool selection behavior
  • ToolUseContent / ToolResultContent - Tool calling content types
  • SamplingContent<T> - Single or array content wrapper
  • SamplingMessageContent - Unified content enum with ToolUse and ToolResult variants
  • SamplingCapability - Structured capability with tools and context sub-capabilities

Reference implementations:

How Has This Been Tested?

  • New unit tests covering serialization, deserialization, and API usage for all new types
  • All existing tests updated and passing
  • Backward compatibility tests verifying old JSON formats still deserialize correctly

Breaking Changes

The type signature of SamplingMessage.content changed from Content to SamplingContent<SamplingMessageContent>.

Migration Made Easy

Convenience constructors (recommended):

// Before
let msg = SamplingMessage { role: Role::User, content: Content::text("hi") };

// After - use the new helper methods
let msg = SamplingMessage::user_text("hi");
let msg = SamplingMessage::assistant_text("Hello");

Converting existing Content values:

use std::convert::TryInto;

let content: Content = Content::text("hello");

// Convert to SamplingMessageContent
let sampling_content: SamplingMessageContent = content.try_into()?;

// Or convert directly to SamplingContent<SamplingMessageContent>
let content: Content = Content::text("hello");
let wrapped: SamplingContent<SamplingMessageContent> = content.try_into()?;

Note: TryFrom is used because Content::Resource and Content::ResourceLink variants are not supported in sampling messages.

Wire Format Compatibility

  • Deserialization is backward compatible - Old JSON format (single content object) still deserializes correctly
  • ClientCapabilities.sampling - Empty {} JSON still deserializes to SamplingCapability

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

// Advertise capability
let capabilities = ClientCapabilities::builder()
    .enable_sampling()
    .enable_sampling_tools()
    .build();

// Create request with tools
let params = CreateMessageRequestParams {
    messages: vec![SamplingMessage::user_text("What's the weather?")],
    tools: Some(vec![weather_tool]),
    tool_choice: Some(ToolChoice::auto()),
    max_tokens: 1000,
    ..Default::default()
};

// Handle tool use response  
if result.stop_reason.as_deref() == Some(CreateMessageResult::STOP_REASON_TOOL_USE) {
    for content in result.message.content.iter() {
        if let Some(tool_use) = content.as_tool_use() {
            // Execute tool and continue conversation
        }
    }
}

@github-actions github-actions bot added T-test Testing related changes T-config Configuration file changes T-core Core library changes T-examples Example code changes T-model Model/data structure changes labels Jan 24, 2026
@github-actions github-actions bot added the T-documentation Documentation improvements label Jan 24, 2026
@github-actions github-actions bot removed the T-documentation Documentation improvements label Jan 24, 2026
@DaleSeo DaleSeo marked this pull request as ready for review January 25, 2026 02:37
@DaleSeo DaleSeo force-pushed the SEP-1577 branch 6 times, most recently from c2da172 to f037e01 Compare January 25, 2026 03:08
@DaleSeo
Copy link
Contributor Author

DaleSeo commented Jan 28, 2026

Hi @alexhancock, could you please take a look at this PR? Thanks!

@alexhancock alexhancock self-requested a review January 30, 2026 20:20
@alexhancock
Copy link
Collaborator

@DaleSeo Sorry it took me a bit. I'm glad to have support for this, but a little worried about the breaking change. Can you think of any alternatives that would keep compat, or make it a but lighter for updaters?

Interested to discuss!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-config Configuration file changes T-core Core library changes T-examples Example code changes T-model Model/data structure changes T-test Testing related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement SEP-1577: Sampling With Tools

2 participants