A Rust port of grpcurl -- a
command-line tool for interacting with gRPC servers. Like curl for gRPC.
grpcurl supports all core features from the Go version: server reflection, proto/protoset file sources, all four RPC types (unary, server streaming, client streaming, bidi streaming), TLS/mTLS, verbose output, and descriptor export.
cargo install --locked grpcurlgit clone https://github.com/shuozeli/grpcurl-rs.git
cd grpcurl-rs
cargo build --release
# Binary at target/release/grpcurl# Via server reflection
grpcurl --plaintext localhost:50051 list
# Via proto file (no server needed)
grpcurl --proto service.proto list
# Via protoset file (no server needed)
grpcurl --protoset descriptors.pb listgrpcurl --plaintext localhost:50051 list my.package.MyService# Describe a service
grpcurl --plaintext localhost:50051 describe my.package.MyService
# Describe a message with a JSON template
grpcurl --msg-template --plaintext localhost:50051 describe my.package.MyRequest# Unary call with inline JSON
grpcurl --plaintext -d '{"name": "world"}' localhost:50051 my.package.Greeter/SayHello
# Read request from stdin
echo '{"name": "world"}' | grpcurl --plaintext -d @ localhost:50051 my.package.Greeter/SayHello
# Server streaming
grpcurl --plaintext -d '{"query": "foo"}' localhost:50051 my.package.MyService/Search
# Verbose output (headers, trailers, metadata)
grpcurl -v --plaintext -d '{}' localhost:50051 my.package.MyService/GetItem# Standard TLS (system root CAs)
grpcurl localhost:50051 list
# Custom CA certificate
grpcurl --cacert ca.pem localhost:50051 list
# Mutual TLS (client certificate)
grpcurl --cert client.pem --key client-key.pem localhost:50051 list
# Skip certificate verification (insecure)
grpcurl --insecure localhost:50051 list
# Plaintext (no TLS)
grpcurl --plaintext localhost:50051 list# Add headers to all requests
grpcurl -H "Authorization: Bearer token" --plaintext localhost:50051 list
# RPC-only headers (excluded from reflection)
grpcurl --rpc-header "x-request-id: 123" --plaintext -d '{}' localhost:50051 my.Service/Method
# Reflection-only headers
grpcurl --reflect-header "Authorization: Bearer token" --plaintext localhost:50051 list
# Expand environment variables in headers
grpcurl --expand-headers -H 'Authorization: Bearer ${TOKEN}' --plaintext localhost:50051 list# Export as protoset (binary FileDescriptorSet)
grpcurl --protoset-out output.pb --plaintext localhost:50051 describe my.package.Service
# Export as .proto source files
grpcurl --proto-out-dir ./protos --plaintext localhost:50051 describe my.package.Servicegrpcurl achieves 95.8% feature parity with the Go version (69/72 verification cases match byte-for-byte).
- All three modes:
list,describe,invoke - Server reflection (v1 and v1alpha with auto-negotiation)
- Proto source files (
--proto,--import-path) - Protoset files (
--protoset) - Composite source (reflection + file fallback)
- All four RPC types: unary, server streaming, client streaming, bidi streaming
- JSON and text format (
--format json|text) - Verbose output (
-v,--vv) - TLS, mTLS, insecure, plaintext connections
- Unix domain sockets (
--unix) - Custom headers (
-H,--rpc-header,--reflect-header,--expand-headers) --emit-defaults,--allow-unknown-fields,--msg-template--protoset-out,--proto-out-dirdescriptor export--max-msg-sz,--max-time,--connect-timeout,--keepalive-time--format-errorfor structured error outputSSLKEYLOGFILEsupport- Gzip compression (transparent decompression)
- gRPC status code to exit code mapping (+64 offset)
- Single-dash flag compatibility (
-plaintextworks like--plaintext)
| Area | Go grpcurl | grpcurl (Rust) | Impact |
|---|---|---|---|
| Help output | -plaintext |
--plaintext |
Both accepted at runtime |
| Text format | Legacy <> syntax |
Modern {} syntax |
Both valid protobuf text format |
--vv timing |
Timing data tree | Omitted | Stretch goal |
| ALTS | Supported | Not supported | No Rust equivalent exists |
| xDS | Supported | Not supported | No Rust equivalent exists |
grpcurl-rs/
grpcurl-core/ -- Library crate (descriptor sources, connection, formatting, invocation)
grpcurl-cli/ -- Binary crate (CLI parsing, validation, main entry point)
testing/
testserver/ -- Test gRPC server with reflection
bankdemo/ -- Bank demo gRPC server (auth, streaming, chat)
tls/ -- Test TLS certificates
The grpcurl-core crate can be used programmatically:
use grpcurl_core::connection::{ConnectionConfig, create_channel};
use grpcurl_core::reflection::ServerSource;
use grpcurl_core::descriptor::DescriptorSource;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ConnectionConfig {
plaintext: true,
..Default::default()
};
let channel = create_channel(&config, "localhost:50051").await?;
let source = ServerSource::new(channel);
let services = source.list_services().await?;
for svc in services {
println!("{svc}");
}
Ok(())
}- CLI Usage Guide -- comprehensive flag reference, examples, and patterns
- Architecture -- crate split, module map, data flow, design decisions
- Contributing -- build, test, add flags, release process
# Run offline tests (no server needed)
cargo test -p grpcurl-core -p grpcurl
# Run all tests including server-dependent tests
cargo test -- --include-ignoredSee docs/CONTRIBUTING.md for details on the test infrastructure and categories.
MIT