Skip to content

[RUST]: Implement translate-grpc module in Rust #1622

@crivetimihai

Description

@crivetimihai

Summary

Implement translate-grpc in Rust - a gRPC-to-MCP bridge with Protobuf-JSON conversion and reflection-based discovery. This is a natural fit for Rust's type system and high-performance Protobuf handling.

Motivation

gRPC is widely used in enterprise environments. A high-performance bridge allows MCP to integrate with existing gRPC services without requiring service modifications.

Rust Benefits

Aspect Python (grpcio) Rust (tonic/prost)
Protobuf parsing ~10K msg/s ~500K msg/s (50x)
Protobuf serialization ~15K msg/s ~750K msg/s (50x)
Memory per message ~5KB overhead ~100 bytes overhead
Startup time ~500ms (reflection) ~50ms

Key Improvements

  1. tonic/prost handle Protobuf 10-50x faster than Python's google.protobuf
  2. Natural fit for Rust's type system - Protobuf maps cleanly to Rust structs
  3. Efficient reflection - Rust can cache descriptor pools
  4. Lower memory - No Python object overhead per message

Proposed Architecture

┌─────────────────────────────────────────────────────────┐
│                 MCP Gateway (Python)                     │
├─────────────────────────────────────────────────────────┤
│                    PyO3 Bridge                           │
├─────────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────────┐    │
│  │              translate-grpc (Rust)               │    │
│  ├─────────────────────────────────────────────────┤    │
│  │  ┌───────────┐  ┌───────────┐  ┌─────────────┐  │    │
│  │  │  Service  │  │ Protobuf  │  │   JSON      │  │    │
│  │  │ Discovery │  │  Codec    │  │  Converter  │  │    │
│  │  │(reflection│  │(prost)    │  │(serde_json) │  │    │
│  │  └───────────┘  └───────────┘  └─────────────┘  │    │
│  └─────────────────────────────────────────────────┘    │
│                    Rust Core                             │
├─────────────────────────────────────────────────────────┤
│                  gRPC Services                           │
└─────────────────────────────────────────────────────────┘

Core Components

1. Service Discovery (Reflection)

use tonic::transport::Channel;
use tonic_reflection::pb::server_reflection_client::ServerReflectionClient;

pub struct GrpcDiscovery {
    reflection_client: ServerReflectionClient<Channel>,
    descriptor_pool: DescriptorPool,
}

impl GrpcDiscovery {
    pub async fn discover_services(&mut self) -> Vec<ServiceDescriptor> {
        // Use gRPC reflection to discover available services
    }
    
    pub fn get_method_descriptor(&self, service: &str, method: &str) 
        -> Option<MethodDescriptor> {
        // Cached lookup of method descriptors
    }
}

2. Protobuf-JSON Conversion

use prost_reflect::{DynamicMessage, ReflectMessage};
use serde_json::Value;

pub fn proto_to_json(msg: &DynamicMessage) -> Value {
    // Convert Protobuf to JSON using reflection
}

pub fn json_to_proto(json: &Value, descriptor: &MessageDescriptor) 
    -> Result<DynamicMessage> {
    // Convert JSON to Protobuf dynamically
}

3. MCP Tool Mapping

pub struct GrpcMcpBridge {
    discovery: GrpcDiscovery,
    channel: Channel,
}

impl GrpcMcpBridge {
    /// Convert gRPC service to MCP tools
    pub fn service_to_tools(&self, service: &ServiceDescriptor) -> Vec<McpTool> {
        service.methods()
            .map(|method| McpTool {
                name: format!("{}.{}", service.name(), method.name()),
                description: method.options().description(),
                input_schema: self.message_to_json_schema(method.input()),
            })
            .collect()
    }
    
    /// Invoke gRPC method as MCP tool call
    pub async fn invoke(&self, tool_name: &str, args: Value) -> Result<Value> {
        let (service, method) = parse_tool_name(tool_name)?;
        let descriptor = self.discovery.get_method_descriptor(service, method)?;
        
        let request = json_to_proto(&args, descriptor.input())?;
        let response = self.call_grpc(service, method, request).await?;
        
        Ok(proto_to_json(&response))
    }
}

Crates to Use

  • tonic - gRPC client/server
  • prost - Protobuf codegen
  • prost-reflect - Runtime reflection
  • tonic-reflection - gRPC reflection client
  • serde_json - JSON handling
  • pyo3 - Python bindings

Features

  • Service discovery via gRPC reflection
  • Dynamic Protobuf-JSON conversion
  • Automatic MCP tool generation from gRPC services
  • Streaming support (server, client, bidirectional)
  • Metadata/header passthrough
  • Connection pooling and retry logic

Acceptance Criteria

  • Protobuf parsing > 200K messages/second
  • Service discovery < 100ms
  • Support for all Protobuf scalar types
  • Support for nested messages, enums, oneof
  • Support for repeated fields and maps
  • Streaming gRPC methods exposed as streaming MCP tools

References

Metadata

Metadata

Labels

WOULDP4: Not a priority for current scope; very likely to move to future releasesenhancementNew feature or requestperformancePerformance related itemsreadyValidated, ready-to-work-on itemsrustRust programming

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions