CLI tool
fullstorydev/grpcurl avatar
fullstorydev/grpcurl

grpcurl: a command-line client for gRPC servers that speak protobuf, not JSON

Like cURL, but for gRPC: Command-line tool for interacting with gRPC servers

12,832 stars581 forksGoMIT

At a glance

What is it?
grpcurl sends JSON requests to gRPC endpoints, reads service schemas from server reflection or protoset files, and works with streaming methods. It is a debugging and scripting tool for engineers who already have a gRPC service running and no browser to poke at it with.
Who is it for?
Adopt grpcurl if you need to invoke or inspect a gRPC service from a shell, a CI job, or a debugging session, and you can get either server reflection or the matching .proto or protoset files. Do not adopt it as a general HTTP client, and do not expect it to work against a server whose schema you cannot obtain.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 29 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 26, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What grpcurl solves that curl cannot

A gRPC server does not speak text over the wire. The README states that gRPC servers use a binary encoding, protocol buffers, and that this makes them "basically impossible to interact with using regular curl". Older curl builds without HTTP/2 support are described as non-starters. grpcurl exists to close that gap: it accepts a JSON request body, parses it against the service schema, and transmits a binary-encoded protobuf message to the server.

The target user is an engineer who has a running gRPC service and needs to call one method without writing a client. Typical situations are checking whether a deployment responds at all, reproducing a failing call with a specific payload, or wiring a smoke test into a shell script. The README also notes that the repository ships a library package, github.com/fullstorydev/grpcurl, with functions for building other command-line tools that invoke gRPC endpoints dynamically. That library is a second audience: people writing their own tooling rather than using the binary.

How the schema lookup and JSON-to-protobuf conversion work

The mechanism rests on a schema. grpcurl needs to know the shape of the request and response messages before it can translate JSON into protobuf bytes. The README lists three ways to supply that schema: querying a server that supports server reflection, reading .proto source files, or loading compiled protoset files, which are files containing encoded file descriptor protos produced by protoc.

Reflection is the path of least resistance. If the server implements the reflection service, grpcurl can ask it for the schema at call time, and no local files are needed. If reflection is unavailable, the user must supply either the proto sources or a protoset. This is the central constraint of the tool: without one of those three schema sources, no call can be constructed. The README states this plainly, saying that if the server does not support reflection, you will need the proto source files or protoset files that grpcurl can use.

Streaming is handled too. The README says grpcurl supports all kinds of RPC methods, including streaming methods, and that bi-directional streaming can be operated interactively by running the tool from an interactive terminal and using stdin as the request body. That is a narrower claim than it sounds: interactive bidirectional streaming assumes a terminal, so it is not a scripting path.

Installing grpcurl on macOS, Linux, Windows, and Docker

The README lists several installation routes. On macOS, Homebrew is the documented option. The command installs the binary and puts it on the path.

bash
brew install grpcurl

On Linux, the README points to a snap package, and also to repology.org for a full list of third-party packages covering Windows and many Linux distributions. The snap route is a single command.

bash
snap install grpcurl

If you have the Go SDK, the go tool installs the command into the bin sub-folder of $GOPATH, which defaults to $HOME/go/bin when GOPATH is unset.

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

Docker is the fourth route. The README gives a pull command and a run example that lists the services on a server. Note the two pitfalls it documents: from inside the container, a server on the host loopback must be addressed as host.docker.internal on Mac or Windows, or the container must use the host network on Linux. Proto files must be mounted as a volume, and reading the request body from stdin with -d @ requires the -i flag on the docker command.

bash
docker pull ghcr.io/fullstorydev/grpcurl:latest
docker run ghcr.io/fullstorydev/grpcurl api.grpc.me:443 list

For a first real call, the README's minimal example sends an empty request body to a TLS server that supports reflection. The second line drops TLS for a plaintext server. All flags must come before the server address and method name.

bash
grpcurl grpc.server.com:443 my.custom.server.Service/Method

grpcurl -plaintext grpc.server.com:80 my.custom.server.Service/Method

To send a payload, use -d with a JSON object. The README's example passes an id and a tags array. The body is parsed and then transmitted in protobuf binary format.

bash
grpcurl -d '{"id": 1234, "tags": ["foo","bar"]}' \
    grpc.server.com:443 my.custom.server.Service/Method

For pipelines, -d @ tells grpcurl to read the request body from stdin, which the README illustrates with a heredoc feeding a JSON object into the call. That is the form to use when another command, such as jq, generates the payload.

Where grpcurl stops being the right tool

The schema requirement is the hard boundary. A server without reflection, and without proto sources or a protoset that matches the deployed build, cannot be called. A stale protoset is worse than none: the tool will parse your JSON against the schema you gave it, and the failure will surface as a server-side error rather than a clear local complaint about a mismatched field.

The Docker path carries its own friction. Loopback addressing changes, proto imports have to be rewritten to container paths, and stdin input needs the -i flag. None of that is a defect, but it means a copy-pasted command from a colleague's laptop often fails inside a container.

Interactive bidirectional streaming is a terminal feature. If you need to drive a bidirectional stream from a script, the README does not describe a non-interactive mode for that case, so plan on a generated client instead. And as with any client that can reach a production endpoint, the tool itself is only as safe as the target you point it at: the README documents no confirmation prompt or dry-run mode, so a -d payload against a live service is a real call.

grpcurl versus curl and versus generated clients

The comparison with curl is the one the README invites. curl speaks HTTP and can send arbitrary bytes, but it has no concept of a protobuf message, no schema lookup, and no JSON-to-binary conversion. You can hand-encode a protobuf body and post it with curl, and people do, but you lose the schema check and you lose readable output. grpcurl trades curl's universality for gRPC awareness.

The other alternative is a generated client, produced from the same .proto files with protoc. A generated client gives you typed method signatures, compile-time checking of field names, and a natural home for retry and auth logic. What it does not give you is a one-line invocation from a shell. grpcurl's advantage is that the schema can come from the server at runtime, so the tool works against a service whose proto files you do not have checked out. That is the whole trade: less type safety, no build step, immediate use against a live endpoint. Teams that already maintain a Go or Java client for a service will often find that client easier to extend for a new test than a growing pile of grpcurl flags.

Maintenance, licence, and what an upgrade costs

The repository is not archived, and the last push was on 2026-09-02. The most recent release listed is v1.9.4 on 2026-08-31, following v1.9.3 on 2025-03-11 and v1.9.2 on 2024-11-28. The cadence is irregular: a nine-month gap sits between v1.9.2 and v1.9.3, then roughly five months to v1.9.4. Anyone pinning a version should read the release notes rather than assume a schedule.

The licence is MIT, which permits use, modification, and redistribution with the licence and copyright notice retained. That is a permissive arrangement, but it is not legal advice, and a team redistributing the binary inside a product should have its own counsel review the notice requirements.

Upgrade cost is dominated by the dependency graph, not by grpcurl's own code. The go.mod requires google.golang.org/grpc v1.83.2 and google.golang.org/protobuf v1.36.12, with a long list of indirect dependencies including OpenTelemetry, xDS, and cloud auth libraries. Building from source with an older Go SDK is called out in the README as a source of compile errors caused by outdated dependencies, with make updatedeps as the remedy. The Makefile pins PROTOC_VERSION to 22.0 for code generation and sets CGO_ENABLED=0 for cross-distribution compatibility. The Dockerfile builds a static binary and ships two final stages, one on alpine:3 and one on scratch.

Verifying a server before you trust the output

Start with the list subcommand against the endpoint. If reflection is enabled, the server returns its service names and you know the schema path is open. If it errors, stop and locate the proto sources or a protoset before trying a method call, because no amount of flag tuning will substitute for a missing schema.

Next, confirm the transport. The default invocation assumes TLS, and -plaintext is the documented switch for a server without it. The README also states support for mutual TLS, where the client presents a certificate, and describes numerous options for TLS configuration, so an internal service behind a custom CA will need those settings rather than the bare command. Finally, check the method signature against the schema you loaded, since a JSON field that does not exist in the message will not be caught by curl-style intuition. The tool parses against the schema it has, and that schema is the thing worth verifying first.

Editorial conclusion

Adopt grpcurl if you need to invoke or inspect a gRPC service from a shell, a CI job, or a debugging session, and you can get either server reflection or the matching .proto or protoset files. Do not adopt it as a general HTTP client, and do not expect it to work against a server whose schema you cannot obtain. Before relying on it, verify that the target server exposes reflection or that you have the proto sources, and check whether the endpoint needs TLS, mutual TLS, or plaintext, because the default invocation assumes TLS on port 443.

Frequently asked questions

How do I install grpcurl on Windows?

The README does not give a Windows-specific command. It points to repology.org for the full list of third-party packages covering Windows, and lists downloading a binary from the releases page as a general option.

How do I install grpcurl on a Mac?

On macOS, the README documents Homebrew: run brew install grpcurl. The README also lists a snap package and go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest as alternatives.

How do I install grpcurl on Linux?

The README gives snap install grpcurl for Linux, and points to repology.org for packages covering many Linux distributions. With the Go SDK installed, go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest also works.

What is grpcurl and what does it do?

grpcurl is a command-line tool that lets you interact with gRPC servers, described in the README as basically curl for gRPC servers. It accepts JSON request bodies, converts them to binary protobuf using a schema, and can browse the schema for gRPC services.

Can I use curl with gRPC instead of grpcurl?

The README states that gRPC servers use a binary encoding on the wire, so they are basically impossible to interact with using regular curl, and that older curl versions without HTTP/2 support are non-starters. grpcurl exists to accept JSON instead and convert it to protobuf.

How do I use grpcurl to invoke a method?

Pass the server address and the fully qualified method name, with any flags before them. To send a body, use -d with a JSON object, or -d @ to read the body from stdin. The README's minimal example is grpcurl grpc.server.com:443 my.custom.server.Service/Method.

Official sources

  1. fullstorydev/grpcurl on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/fullstorydev-grpcurl.svg)](https://hysenlabs.com/projects/fullstorydev-grpcurl)