Struct WebSocketTransport

Source
pub struct WebSocketTransport { /* private fields */ }
Expand description

WebSocket-based MCP transport

Provides real-time bidirectional communication with MCP servers over WebSocket connections. This transport supports secure connections (WSS), Bearer token authentication, and concurrent request/response handling with proper JSON-RPC 2.0 message correlation.

§Features

  • Async WebSocket Communication: Built on tokio-tungstenite for high-performance async I/O
  • Request/Response Matching: Automatic correlation of responses using atomic request IDs
  • Bearer Token Support: Authentication via Authorization header during handshake
  • Connection Management: Proper ping/pong and connection lifecycle handling
  • Concurrent Operations: Split stream architecture allows simultaneous read/write operations

§Architecture

The transport uses a split-stream design where the WebSocket connection is divided into separate read and write halves, each protected by async mutexes. This allows concurrent operations while maintaining thread safety. Request IDs are generated atomically to ensure unique identification of requests and proper response correlation.

§Example Usage

use mistralrs_mcp::transport::{WebSocketTransport, McpTransport};
use std::collections::HashMap;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Create headers with Bearer token
    let mut headers = HashMap::new();
    headers.insert("Authorization".to_string(), "Bearer your-token".to_string());

    // Connect to WebSocket MCP server
    let transport = WebSocketTransport::new(
        "wss://api.example.com/mcp".to_string(),
        Some(30), // 30 second timeout
        Some(headers)
    ).await?;

    // Use the transport for MCP communication
    let result = transport.send_request("tools/list", serde_json::Value::Null).await?;
    println!("Available tools: {}", result);

    Ok(())
}

§Protocol Compliance

This transport implements the Model Context Protocol (MCP) specification over WebSocket, adhering to JSON-RPC 2.0 message format with proper error handling and response correlation.

Implementations§

Source§

impl WebSocketTransport

Source

pub async fn new( url: String, _timeout_secs: Option<u64>, headers: Option<HashMap<String, String>>, ) -> Result<Self>

Creates a new WebSocket transport connection to an MCP server

§Arguments
  • url - WebSocket URL (ws:// or wss://)
  • _timeout_secs - Connection timeout (currently unused, reserved for future use)
  • headers - Optional HTTP headers for WebSocket handshake (e.g., Bearer tokens)
§Returns

A configured WebSocketTransport ready for MCP communication

§Errors
  • Invalid URL format
  • WebSocket connection failure
  • Header parsing errors
  • Network connectivity issues
§Example
use mistralrs_mcp::transport::WebSocketTransport;
use std::collections::HashMap;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let mut headers = HashMap::new();
    headers.insert("Authorization".to_string(), "Bearer token123".to_string());
     
    let transport = WebSocketTransport::new(
        "wss://mcp.example.com/api".to_string(),
        Some(30),
        Some(headers)
    ).await?;
     
    Ok(())
}

Trait Implementations§

Source§

impl McpTransport for WebSocketTransport

Source§

fn send_request<'life0, 'life1, 'async_trait>( &'life0 self, method: &'life1 str, params: Value, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Sends an MCP request over WebSocket and waits for the corresponding response

This method implements the JSON-RPC 2.0 protocol over WebSocket, handling:

  • Unique request ID generation for response correlation
  • Concurrent request processing with proper message ordering
  • Error handling for both transport and protocol errors
  • Message filtering to match responses with requests
§Arguments
  • method - The MCP method name (e.g., “tools/list”, “tools/call”)
  • params - JSON parameters for the method call
§Returns

The result portion of the JSON-RPC response

§Errors
  • WebSocket connection errors
  • JSON serialization/deserialization errors
  • MCP server errors (returned in JSON-RPC error field)
  • Timeout or connection closure
§Example
use mistralrs_mcp::transport::{WebSocketTransport, McpTransport};
use serde_json::json;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let transport = WebSocketTransport::new(
        "wss://api.example.com/mcp".to_string(),
        None,
        None
    ).await?;
     
    // List available tools
    let tools = transport.send_request("tools/list", serde_json::Value::Null).await?;
     
    // Call a specific tool
    let params = json!({"query": "example search"});
    let result = transport.send_request("tools/call", params).await?;
     
    Ok(())
}
Source§

fn ping<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Sends a WebSocket ping frame to test connection health

This method sends a ping frame to the server and expects a pong response, which helps verify that the WebSocket connection is still active and responsive.

§Returns

Ok(()) if the ping was sent successfully

§Errors
  • WebSocket send errors
  • Connection closure
Source§

fn close<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Gracefully closes the WebSocket connection

Sends a close frame to the server to properly terminate the connection according to the WebSocket protocol. The server should respond with its own close frame to complete the closing handshake.

§Returns

Ok(()) if the close frame was sent successfully

§Errors
  • WebSocket send errors
  • Connection already closed

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> ErasedDestructor for T
where T: 'static,

§

impl<T> Ungil for T
where T: Send,