Skip to content

How to use the grpcurl command-line tool to test your gRPC service ​

Schematic diagram of how to use the grpcurl command-line tool to test your gRPC service

Test gRPC services just like testing HTTP APIs with curl — A complete tutorial on the grpcurl tool

1. What is grpcurl? ​

grpcurl is a command-line tool for interacting with gRPC servers. Its design is inspired by curl, but specifically optimized for the gRPC protocol.

Core Features ​

FunctionDescription
Call gRPC methodCall gRPC services just like calling REST APIs with curl.
Service DiscoveryAutomatically retrieve service definitions via gRPC reflection
Multi-protocol supportSupports HTTP/2, TLS, Unix Socket
Multiple data formatsSupports JSON and Protobuf Text formats
Streaming callSupports server streaming, client streaming, and bidirectional streaming.

Applicable scenarios ​

  • Debugging gRPC services during development

  • Verify whether the service interface is working properly.

  • Quickly test API return results

  • API testing in CI/CD

2. Install grpcurl ​

bash
# Install the latest version
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest

# Verify installation
~/go/bin/grpcurl --version

Option 2: Using Homebrew (macOS) ​

bash
brew update
brew install grpcurl
grpcurl --version

Method 3: Download the precompiled binary ​

Access GitHub Releases Download the binary file for the corresponding platform.

bash
# Example: Download the Linux amd64 version
curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.9.3/grpcurl_1.9.3_linux_x86_64.tar.gz -o grpcurl.tar.gz
tar -xzf grpcurl.tar.gz
sudo mv grpcurl /usr/local/bin/

Verify the installation ​

bash
grpcurl --version
# grpcurl 1.9.3

3. Basic Usage ​

3.1 View service list ​

bash
# List all services through reflection
grpcurl -plaintext localhost:50051 list

# Output example
# grpc.health.v1.Health
# grpc.reflection.v1alpha.ServerReflection
# discovery.v1.DiscoveryAgent

3.2 View service methods ​

bash
# List all methods of a specific service
grpcurl -plaintext localhost:50051 list discovery.v1.DiscoveryAgent

# Output example
# discovery.v1.DiscoveryAgent.Status
# discovery.v1.DiscoveryAgent.Heartbeat
# discovery.v1.DiscoveryAgent.Reload
# discovery.v1.DiscoveryAgent.Verify
# discovery.v1.DiscoveryAgent.StreamHeartbeat

3.3 View Method Details ​

bash
# View the request/response structure of the method
grpcurl -plaintext localhost:50051 describe discovery.v1.DiscoveryAgent.Status

# Output example
# discovery.v1.DiscoveryAgent.Status is a method:
# rpc Status ( .discovery.v1.StatusRequest ) returns ( .discovery.v1.StatusResponse );

3.4 Calling gRPC Methods ​

bash
# Call with no arguments
grpcurl -plaintext localhost:50051 discovery.v1.DiscoveryAgent/Status

# Call with parameters
grpcurl -plaintext -d '{"timestamp": 1723456789}' localhost:50051 discovery.v1.DiscoveryAgent/Heartbeat

4. Unix Socket Debugging (Key!) ​

4.1 Version Differences ​

Different versions of grpcurl The support for Unix Socket differs:

VersionCorrect formatDescription
v1.8.7 and below-unix /path/to/socketUse -unix Logo
v1.9.0 and aboveunix:///path/to/socketUse URL format (Recommend)

4.2 Invocation method for v1.9.0+ ​

bash
# Basic format: grpcurl [flags] [address] [service/method]
# address format: unix:///path/to/socket (three slashes)

# Basic call
grpcurl -plaintext unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Status

# Call with parameters
grpcurl -plaintext -d '{"timestamp": 1723456789}' unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Heartbeat

# Parameterless call
grpcurl -plaintext -d '{}' unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Reload

4.3 Points to Note ​

Key pointsExplanation
Must add -plaintextUnix Socket has no TLS; omitting it will cause a TLS error.
Address formatMust use unix:///path/to/socket(three slashes)
-d parameter positionPlace it before the service name.
Service name formatpackage.Service/Method

4.4 Common Errors and Solutions ​

ErrorReasonSolution
missing port in addressUnused unix:// formatUse unix:///path/to/socket
first record does not look like a TLS handshakeNot added -plaintextAdd -plaintext Logo
Too many argumentsParameter order or format errorCheck -d Parameter format

5. Advanced Usage ​

5.1 Usage -d @ Read from standard input ​

When the JSON data is large or contains special characters, you can use -d @ Read from standard input:

bash
# Use echo
echo '{"timestamp": 1723456789}' | grpcurl -plaintext -d @ unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Heartbeat

# Use here-document
grpcurl -plaintext -d @ unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Heartbeat <<EOF
{"timestamp": 1723456789}
EOF

# Read from file
grpcurl -plaintext -d @ unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Heartbeat < request.json

5.2 Using reflection vs using proto files ​

bash
grpcurl -plaintext localhost:50051 list
grpcurl -plaintext localhost:50051 describe discovery.v1.DiscoveryAgent

Method 2: Use a proto file (when reflection is unavailable) ​

bash
grpcurl -plaintext -proto api/v1/discovery.proto \
    -import-path ./api/v1 \
    localhost:50051 discovery.v1.DiscoveryAgent/Status

5.3 Add Custom Header ​

bash
# Add custom Header
grpcurl -plaintext -H "X-API-Key: abc123" \
    localhost:50051 discovery.v1.DiscoveryAgent/Status

# Add multiple Header
grpcurl -plaintext -H "Authorization: Bearer token123" \
    -H "X-Request-ID: 12345" \
    localhost:50051 discovery.v1.DiscoveryAgent/Status

5.4 Streaming Invocation ​

bash
# Server-side streaming (Server Streaming)
grpcurl -plaintext -d '{}' localhost:50051 package.Service/ServerStream

# Client Streaming (Client Streaming)
grpcurl -plaintext -d @ localhost:50051 package.Service/ClientStream <<EOF
{"msg": "hello"}
{"msg": "world"}
EOF

6. Practical Tips ​

6.1 Formatted Output ​

bash
# Pretty-print the output with jq
grpcurl -plaintext unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Status | jq .

# Extract only specific fields
grpcurl -plaintext unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Status | jq '.modules'

6.2 Output as Protobuf Text format ​

bash
grpcurl -format text -plaintext localhost:50051 discovery.v1.DiscoveryAgent/Status

6.3 Debugging Request/Response ​

bash
# Enable verbose output
grpcurl -v -plaintext localhost:50051 discovery.v1.DiscoveryAgent/Status

# View request/response headers
grpcurl -vv -plaintext localhost:50051 discovery.v1.DiscoveryAgent/Status

6.4 Set Timeout ​

bash
# Connection timeout 10 seconds, total timeout 30 seconds
grpcurl -connect-timeout 10 -max-time 30 \
    -plaintext localhost:50051 discovery.v1.DiscoveryAgent/Status

7. Using in a Makefile ​

Complete example ​

makefile
# grpcurl test command
grpcurl-status:
	grpcurl -plaintext unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Status

grpcurl-heartbeat:
	grpcurl -plaintext -d '{"timestamp": 1723456789}' unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Heartbeat

grpcurl-reload:
	grpcurl -plaintext -d '{}' unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Reload

grpcurl-verify:
	grpcurl -plaintext -d '{"discovery_data": ""}' unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Verify

# Version that reads data from a file
grpcurl-heartbeat-file:
	grpcurl -plaintext -d @ unix:///tmp/discovery-agent.sock discovery.v1.DiscoveryAgent/Heartbeat < request.json

Usage example ​

bash
make grpcurl-status
make grpcurl-heartbeat
make grpcurl-reload

8. Comparison with curl ​

Functioncurlgrpcurl
ProtocolHTTP/1.1, HTTP/2HTTP/2 (gRPC)
Data formatJSON, XML, FormJSON, Protobuf
Service DiscoveryOpenAPI/SwaggergRPC reflection
Unix Socket--unix-socketunix:///path
Streaming❌✅ (bidirectional stream)
TLS✅✅

9. Frequently Asked Questions FAQ ​

Q1:grpcurl report Too many arguments ​

Reason: The parameter format is incorrect.

Solution:

  • Check -d Whether the parameters are correctly parsed

  • Use -d @ Read data from standard input

Q2: Unix Socket error missing port in address ​

Reason: The correct Unix Socket address format was not used.

Solution:

bash
# Correct format (v1.9.0+)
grpcurl -plaintext unix:///tmp/socket.sock service/method

Q3: Report first record does not look like a TLS handshake ​

Reason: Not added -plaintext Sign.

Solution:

bash
grpcurl -plaintext localhost:50051 service/method

Q4: How to check the grpcurl version? ​

bash
grpcurl --version

Q5: What should I do if reflection is not enabled on the server? ​

Use -proto Specify the proto file:

bash
grpcurl -plaintext -proto api/v1/service.proto -import-path ./api/v1 localhost:50051 package.Service/Method

10. Reference Resources ​

Last updated on11/07/2026, 02:16 PM
@fishfinal | @fishfinals | [email protected]