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.
grpcurluses 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.
grpcurlrelies 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,
grpcurlwill not be able to discover services and methods. You’ll need to provide.protofiles using the-protoand-import-pathflags. - TLS Issues: Using
-insecureis 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:
grpcurlexpects 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,
grpcurldefaults to port 80 for HTTP and 443 for HTTPS. - Proto File Paths: When using
-protoor-import-path, ensure the paths are relative to where you are runninggrpcurlor are absolute paths. - Service Name Formatting: gRPC service and method names are typically fully qualified (e.g.,
package.ServiceName/MethodName).grpcurlrelies on this convention.