Skip to content

feat: add local feature for !Send tool handler support#740

Merged
DaleSeo merged 2 commits intomainfrom
feat/local-feature-send-bounds
Mar 11, 2026
Merged

feat: add local feature for !Send tool handler support#740
DaleSeo merged 2 commits intomainfrom
feat/local-feature-send-bounds

Conversation

@DaleSeo
Copy link
Member

@DaleSeo DaleSeo commented Mar 9, 2026

Closes #728

Motivation and Context

Some MCP server use cases involve state that isn't Send. For example, this includes holding a raw pointer, an Rc, or a thread-local resource. The current service stack requires Send + Sync everywhere, which completely rules these out. This PR introduces a local Cargo feature that relaxes all Send and Sync bounds across the service stack. This change allows servers with !Send handlers to run on a single-threaded runtime using tokio::task::LocalSet and spawn_local.

How Has This Been Tested?

The full test suite passes in both modes:

  • cargo test --features server,client (default, no behavior change)
  • cargo test --features server,client,local (new path).

Breaking Changes

None. Without the local feature the effective trait bounds are identical to before — MaybeSend resolves to Send + Sync and MaybeSendFuture resolves to Send via blanket impls. The feature is strictly opt-in.

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

@DaleSeo DaleSeo self-assigned this Mar 9, 2026
@github-actions github-actions bot added T-dependencies Dependencies related changes T-test Testing related changes T-config Configuration file changes T-core Core library changes T-handler Handler implementation changes T-macros Macro changes T-service Service layer changes T-transport Transport layer changes T-documentation Documentation improvements labels Mar 9, 2026
@DaleSeo DaleSeo force-pushed the feat/local-feature-send-bounds branch from 1ebf858 to 8ef36fd Compare March 10, 2026 13:31
@DaleSeo DaleSeo marked this pull request as ready for review March 10, 2026 14:30
@DaleSeo DaleSeo requested a review from a team as a code owner March 10, 2026 14:30
Copy link
Contributor

@alexhancock alexhancock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It LGTM as an opt-in thing.

Perhaps good to get @Stranmor to look as well to double confirm it addresses the need?

@Stranmor
Copy link

This PR fully addresses the use case I described in #728. The global local feature approach works well for us — MCP servers are typically single-threaded, so relaxing Send+Sync bounds across the board is a practical trade-off. Appreciate the clean implementation with MaybeSend/MaybeSyncSend traits. Thanks @DaleSeo for picking this up!

@DaleSeo DaleSeo merged commit 1a4a52a into main Mar 11, 2026
16 checks passed
@DaleSeo DaleSeo deleted the feat/local-feature-send-bounds branch March 11, 2026 21:22
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-dependencies Dependencies related changes T-documentation Documentation improvements T-handler Handler implementation changes T-macros Macro changes T-service Service layer changes T-test Testing related changes T-transport Transport layer changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Support for !Send futures in #[tool] handlers (e.g. #[tool(local)])

3 participants