grpcurl gRPC Client

grpcurl cheatsheet — list services, describe methods, call RPCs. grpcurl -plaintext localhost:50051 list, grpcurl -d '{"name":"World"}'. The curl for gRPC APIs.

6 min read

What it is

grpcurl is a command-line tool for interacting with gRPC servers, allowing you to explore services, methods, and send requests without writing client code.

Installation

Linux:

sudo apt update && sudo apt install grpcurl
# or
sudo yum install grpcurl
# or
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest

Mac:

brew install grpcurl
# or
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest

Windows: Download the appropriate .exe from the grpcurl releases page and add it to your system’s PATH. Or using Go:

go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest

Core Concepts

  • Service: A collection of RPC methods.
  • Method: A single RPC operation defined by a request message and a response message.
  • Descriptor: Metadata describing the gRPC services, methods, and messages. grpcurl uses these descriptors to understand how to communicate with a server.
  • Reflection: A gRPC protocol that allows clients to discover the services and methods offered by a server at runtime. grpcurl relies heavily on reflection.

Commands / Usage

Exploring Services and Methods

List all services on a server:

grpcurl localhost:50051 list

Lists all services available at the given address.

List all methods of a specific service:

grpcurl localhost:50051 list grpc.reflection.v1alpha.ServerReflection

Lists all methods within the grpc.reflection.v1alpha.ServerReflection service.

Describe a specific service:

grpcurl localhost:50051 describe grpc.reflection.v1alpha.ServerReflection

Shows detailed information about the grpc.reflection.v1alpha.ServerReflection service, including its methods and message types.

Describe a specific method:

grpcurl localhost:50051 describe helloworld.Greeter.SayHello

Shows detailed information about the SayHello method of the Greeter service, including its request and response message structures.

Describe a message type:

grpcurl localhost:50051 describe helloworld.HelloRequest

Shows the fields and types within the helloworld.HelloRequest message.

Sending Requests

Send a unary RPC with JSON payload:

grpcurl -d '{"name": "World"}' localhost:50051 helloworld.Greeter/SayHello

Sends a request to the SayHello method of the Greeter service with a JSON payload.

Send a unary RPC with a proto file:

grpcurl -proto helloworld/helloworld.proto -d '{"name": "World"}' localhost:50051 helloworld.Greeter/SayHello

Uses a local proto file to parse the request message for the SayHello method. Useful when reflection is not enabled or you want to be explicit.

Send a unary RPC with multiple proto files:

grpcurl -proto helloworld/helloworld.proto -proto google/api/annotations.proto -d '{"name": "World"}' localhost:50051 helloworld.Greeter/SayHello

Specifies multiple proto files for parsing.

Send a client-streaming RPC:

grpcurl -d @ localhost:50051 helloworld.Greeter/LotsOfGreetings

The @ symbol indicates that the request body should be read from standard input, allowing you to pipe multiple messages for client-streaming.

Send a server-streaming RPC:

grpcurl -d '{"name": "World"}' localhost:50051 helloworld.Greeter/LotsOfReplies

For server-streaming, grpcurl will print each received message to standard output.

Send a bidirectional-streaming RPC:

grpcurl -d @ localhost:50051 helloworld.Greeter/BidiStream

Similar to client-streaming, @ reads from stdin for sending messages and prints received messages to stdout.

Send requests to a server using TLS:

grpcurl -insecure localhost:50051 greeter.Greeter/SayHello

The -insecure flag disables TLS verification. Use with caution.

grpcurl -cacert ca.crt -cert client.crt -key client.key localhost:50051 greeter.Greeter/SayHello

Provides client certificates and CA certificate for mutual TLS authentication.

Send requests with custom headers:

grpcurl -H "Authorization: Bearer YOUR_TOKEN" -d '{"name": "World"}' localhost:50051 helloworld.Greeter/SayHello

Adds custom HTTP/2 headers to the request.

Send requests with a specific content type:

grpcurl -plaintext -proto helloworld/helloworld.proto -d '{"name": "World"}' localhost:50051 helloworld.Greeter/SayHello

The -plaintext flag forces the use of plain HTTP/1.1 for the connection, useful for debugging or when gRPC is tunneled over HTTP/1.1.

List all available proto files from the server (if reflection supports it):

grpcurl -proto-discovery localhost:50051 list

Attempts to discover and list proto files served by the server.

Advanced Usage

Use a custom proto descriptor set:

grpcurl -import-path ./protos -proto my_service.proto -d '{"field": "value"}' localhost:50051 my_package.MyService/MyMethod

Specifies an import path for resolving proto dependencies and the main proto file.

Use reflection with a specific server name:

grpcurl -server-name my.grpc.server.com -d '{"name": "World"}' localhost:50051 helloworld.Greeter/SayHello

Useful when the server’s hostname in its certificate doesn’t match the address grpcurl is connecting to.

Format output as pretty JSON:

grpcurl -format json localhost:50051 helloworld.Greeter/SayHello

Ensures the JSON output is indented for readability.

Disable colorized output:

grpcurl -no-color localhost:50051 list

Turns off ANSI color codes in the output.

List all available proto files on the server:

grpcurl -proto-discovery localhost:50051 list

This command attempts to query the server for its available proto files.

Common Patterns

Introspecting a Kubernetes service:

kubectl get pods -l app=my-grpc-app -o jsonpath='{.items[0].metadata.name}' | xargs -I {} kubectl port-forward {} 50051:50051 & \
grpcurl localhost:50051 list

Forwards a pod’s gRPC port and then lists services.

Sending a request to a gRPC service behind Envoy:

grpcurl -H "x-envoy-external-address: 127.0.0.1" -d '{"name": "Envoy"}' localhost:8080 envoy.api.v2.RouteDiscoveryService/StreamRoutes

Includes a common Envoy header if the gRPC service is proxied by Envoy.

Streaming multiple requests to a client-streaming endpoint:

echo '{"name": "Alice"}' | grpcurl -d @ -assume-unary localhost:50051 mypackage.MyService/ClientStream
echo '{"name": "Bob"}' | grpcurl -d @ -assume-unary localhost:50051 mypackage.MyService/ClientStream

This example is slightly misleading as -assume-unary is incorrect for streaming. For actual client streaming, you’d typically pipe data that grpcurl interprets as a stream. A more accurate pattern for streaming multiple messages would involve a script or a more complex input.

A better pattern for client streaming with multiple messages:

(echo '{"name": "Alice"}'; echo '{"name": "Bob"}') | grpcurl -d @ localhost:50051 helloworld.Greeter/LotsOfGreetings

This pipes two JSON objects, each on a new line, to grpcurl for a client-streaming RPC.

Saving proto definitions from a server:

grpcurl -proto-discovery localhost:50051 list > services.txt

This command is not for saving proto definitions but for listing services. To save proto definitions, you’d typically need a tool that leverages reflection to dump the .proto files. grpcurl itself doesn’t have a direct command for this.

Gotchas

  • Reflection Not Enabled: If the gRPC server does not have reflection enabled, grpcurl will not be able to discover services and methods. You’ll need to provide .proto files using the -proto and -import-path flags.
  • TLS Issues: Using -insecure is convenient but bypasses security. For proper TLS, ensure you have the correct CA certificates and client certificates if required. Misconfigured TLS is a common stumbling block.
  • Message Parsing: grpcurl expects JSON by default for request payloads. If your message has complex nested structures or enums, you might need to consult the service descriptor (grpcurl ... describe) to format the JSON correctly.
  • Streaming Semantics: Understanding the difference between client-streaming, server-streaming, and bidirectional-streaming is crucial. The input (-d @) and output behavior differ significantly.
  • Default Port: If no port is specified in the address, grpcurl defaults to port 80 for HTTP and 443 for HTTPS.
  • Proto File Paths: When using -proto or -import-path, ensure the paths are relative to where you are running grpcurl or are absolute paths.
  • Service Name Formatting: gRPC service and method names are typically fully qualified (e.g., package.ServiceName/MethodName). grpcurl relies on this convention.