Skip to main content

CrossProtocolCodec

Trait CrossProtocolCodec 

Source
pub trait CrossProtocolCodec:
    Send
    + Sync
    + Debug {
    // Required methods
    fn downstream_protocol(&self) -> ProtocolSide;
    fn encode_request(
        &self,
        downstream_side: ProtocolSide,
        ir_method: &str,
        raw_envelope: &Map<String, Value>,
        report: &mut RequestCodecReport,
    ) -> Result<Map<String, Value>, CrossProtocolError>;
    fn decode_reply(
        &self,
        downstream_side: ProtocolSide,
        ir_method: &str,
        reply: &Map<String, Value>,
        report: &mut RequestCodecReport,
    ) -> Result<Map<String, Value>, CrossProtocolError>;
}
Expand description

A codec that translates request and reply envelopes between the downstream leg’s protocol and the upstream’s protocol.

The downstream leg’s protocol is the one the client spoke; the upstream is the one the bridge is calling out to. The two are usually different in the cross-protocol case (an MCP client on one side, an A2A agent on the other), and a BridgePeer for the upstream is a real connection to that agent.

§Why the trait takes Leg not ProtocolVersion

The downstream leg’s ProtocolVersion says which MCP revision the client negotiated. The cross-protocol decision is bigger than that — it is “is this MCP at all, or is it A2A?” — and Leg already carries the protocol shape. A bridge that only sees one leg’s protocol can answer “MCP” or “A2A” and skip the per-revision question entirely, which is what the per-revision ToolResultCodec is for on the way back.

§Why the codec takes the raw downstream envelope, not just the IR

The IR is protocol-agnostic at the method-name level (it carries the canonical name the bridge has assigned), but the parameters are opaque: a tools/call arguments value is just an entry in IrParams, indistinguishable from a SendMessage message field. The codec needs the raw wire shape to know which entry is which, so it re-reads raw_envelope rather than trying to re-derive the shape from the IR. The bridge already has both — the IR for routing, the raw envelope for translation.

Required Methods§

Source

fn downstream_protocol(&self) -> ProtocolSide

The protocol this codec expects the downstream leg to speak.

Source

fn encode_request( &self, downstream_side: ProtocolSide, ir_method: &str, raw_envelope: &Map<String, Value>, report: &mut RequestCodecReport, ) -> Result<Map<String, Value>, CrossProtocolError>

Translates a downstream request envelope into the upstream’s wire form.

downstream_side is the protocol the downstream leg speaks (A2A or MCP). ir_method is the canonical method name the bridge has assigned (e.g. SendMessage for an A2A call, tools/call for an MCP call). raw_envelope is the downstream’s original wire shape, so the codec can read the parameters in their native form.

§Errors

CrossProtocolError::MethodNotBridged if the method is one this codec has no rule for.

Source

fn decode_reply( &self, downstream_side: ProtocolSide, ir_method: &str, reply: &Map<String, Value>, report: &mut RequestCodecReport, ) -> Result<Map<String, Value>, CrossProtocolError>

Translates an upstream reply envelope back into the downstream’s wire form.

downstream_side is the protocol the downstream leg speaks. ir_method is the canonical method name the request carried; the codec uses it to know which reply shape to expect (an A2A Task reply for a SendMessage request, a Content list for a tools/call request).

§Errors

The same set of errors as encode_request.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl CrossProtocolCodec for Arc<A2aMcpCodec>

Source§

fn downstream_protocol(&self) -> ProtocolSide

Source§

fn encode_request( &self, downstream_side: ProtocolSide, ir_method: &str, raw_envelope: &Map<String, Value>, report: &mut RequestCodecReport, ) -> Result<Map<String, Value>, CrossProtocolError>

Source§

fn decode_reply( &self, downstream_side: ProtocolSide, ir_method: &str, reply: &Map<String, Value>, report: &mut RequestCodecReport, ) -> Result<Map<String, Value>, CrossProtocolError>

Implementors§