Skip to content

feat: experimental Rust streamable HTTP transport backend (ADR-038)#2856

Open
MRSKYWAY wants to merge 17 commits intoIBM:mainfrom
MRSKYWAY:rust-streamable-http-transport
Open

feat: experimental Rust streamable HTTP transport backend (ADR-038)#2856
MRSKYWAY wants to merge 17 commits intoIBM:mainfrom
MRSKYWAY:rust-streamable-http-transport

Conversation

@MRSKYWAY
Copy link
Contributor

https://github.com/IBM/mcp-context-forge/blob/main/docs/docs/architecture/adr/038-experimental-rust-transport-backend.md

🔗 Related Issue

Closes #1621


📝 Summary

This PR implements the experimental Rust-based Streamable HTTP transport backend proposed in ADR-038.

The implementation introduces a feature-flagged Rust transport path using Tokio + PyO3, while preserving full backward compatibility with the existing Python asyncio transport.

The Rust backend is optional and enabled via MCP_USE_RUST_TRANSPORT=1. If the Rust module is unavailable or fails to initialize, the system falls back safely to the existing Python implementation.


🏷️ Type of Change

  • Bug fix
  • [ x] Feature / Enhancement
  • [ x] Documentation
  • Refactor
  • Chore (deps, CI, tooling)
  • Other (describe below)

🧪 Verification

Check Command Status
Lint suite make lint
Unit tests make test
Coverage ≥ 80% make coverage

✅ Checklist

  • [ x] Code formatted (make black isort pre-commit-done)
  • [ x] Tests added/updated for changes
  • [ x] Documentation updated (if applicable)
  • [ x] No secrets or credentials committed

📓 Notes (optional)

Design Notes

  • Transport API preserved.
  • JSON-RPC framing unchanged.
  • Explicit fallback to Python implementation if Rust bridge is unavailable.
  • Bridge exposes:
    • prepare_streamable_http_context
    • start_streamable_http_transport

Benchmark Notes

Initial local benchmarking using make load-test-ui, make load-test-light (100 users, spawn rate 10) shows comparable performance between Python and Rust paths in this environment.

Due to local system constraints, high-concurrency benchmarking was limited. Further benchmarking under production-like load is recommended before considering default enablement.

Future Work

  • Full stream semantic parity validation (partial reads, disconnects, malformed JSON)
  • SSE/session_id/keepalive audit
  • Extended high-concurrency benchmarking
  • Error mapping equivalence verification

Signed-off-by: MRSKYWAY <sujyot.kamble1114@gmail.com>
Signed-off-by: MRSKYWAY <sujyot.kamble1114@gmail.com>
Signed-off-by: MRSKYWAY <sujyot.kamble1114@gmail.com>
Signed-off-by: MRSKYWAY <sujyot.kamble1114@gmail.com>
Signed-off-by: MRSKYWAY <sujyot.kamble1114@gmail.com>
Signed-off-by: MRSKYWAY <sujyot.kamble1114@gmail.com>
Signed-off-by: MRSKYWAY <sujyot.kamble1114@gmail.com>
@MRSKYWAY MRSKYWAY force-pushed the rust-streamable-http-transport branch from 8062bfd to 9ca4427 Compare February 12, 2026 09:18
…and affinity registration

Signed-off-by: MRSKYWAY <sujyot.kamble1114@gmail.com>
Signed-off-by: MRSKYWAY <sujyot.kamble1114@gmail.com>
Signed-off-by: MRSKYWAY <sujyot.kamble1114@gmail.com>
Signed-off-by: MRSKYWAY <sujyot.kamble1114@gmail.com>
Signed-off-by: MRSKYWAY <sujyot.kamble1114@gmail.com>
Signed-off-by: MRSKYWAY <sujyot.kamble1114@gmail.com>
@MRSKYWAY MRSKYWAY force-pushed the rust-streamable-http-transport branch from eceb76d to 073ccc0 Compare February 12, 2026 13:34
@MRSKYWAY
Copy link
Contributor Author

All checks are passing now ✅
This implements the experimental Rust transport per ADR-038 and closes #1621.
Ready for review — happy to address any feedback.

@crivetimihai
Copy link
Member

Thanks @MRSKYWAY. Well-structured integration — the bridge pattern with Python fallback is clean, and the ADR lessons learned (especially "transport may not be the primary bottleneck") are honest and valuable.

Observations from the diff:

  1. start_streamable_http_transport always returns false: The Rust request handler is a stub — all requests fall through to Python. This means the PR is currently context-preparation-only. The ADR should note this explicitly as "Phase 1: context normalization only."
  2. Duplicate request_headers_var.set and server_id_var.set: In streamablehttp_transport.py, these are called twice — once before send_with_capture and again after. The second set overwrites the first with the same values. This looks like a merge artifact.
  3. pytest_cov_compat.py: This is an unrelated utility that was bundled in — it handles missing pytest-cov. Consider splitting it into a separate PR.
  4. Cargo.lock committed: This is correct for binary/cdylib crates, good.
  5. Tests: The bridge tests cover disabled, enabled, fallback-on-error, and sync handler paths — solid coverage.

@MRSKYWAY
Copy link
Contributor Author

Thanks for the detailed review — really appreciate the feedback.

You’re absolutely right:

• The current implementation is effectively Phase 1 (context normalization + bridge + fallback), with the Rust handler stubbed.
• The duplicate request_headers_var.set / server_id_var.set calls look like a merge artifact — I’ll clean that up.
• Agreed on splitting pytest_cov_compat.py into a separate PR.

I’ll push an update addressing the duplicate state issue and split the pytest utility out.

For the Rust handler itself — would you prefer:

  1. Merge this as Phase 1 (bridge + normalization only), or
  2. Expand this PR to include full Rust request handling before merge?

Happy to proceed either way.

@crivetimihai crivetimihai self-assigned this Feb 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[RUST]: Rewrite transport layer in Rust

2 participants