Evans
Evans: more expressive universal gRPC client
Install / Use
/learn @ktr0731/EvansREADME

Motivation
Evans has been created to use easier than other existing gRPC clients.
If you want to keep your product quality, you must use CI with gRPC testing, should not do use manual testing.
Evans will complete your other use cases just like:
- Manually gRPC API inspection
- To automate some tasks by scripting
The above use cases are corresponding to Evans's two modes, REPL mode, and CLI mode.
REPL mode

REPL mode is the solution for first use case.
You can use it without thinking like the package name, service name, RPC name, command usage, and so on because REPL mode has powerful completion!
CLI mode

CLI mode is a stateless mode just like grpc-ecosystem/polyglot.
It sends one request per one command as its name suggests.
So it is based on UNIX philosophy.
For example, read inputs from stdin, the command will be a filter command.
On the other hand, the command result will be outputted to stdout by JSON formatted.
So, you can format it by any commands like jq. Also, if you want to use the same command (e.g. use same JSON inputs), you can use --file (-f) option.
Table of Contents
- Installation
- Usage (REPL)
- Usage (CLI)
- Other features
- Supported IDL (interface definition language)
- Supported Codec
- Supported Compressor
- See Also
Installation
Highly recommended methods are GitHub Releases or Homebrew because these can be updated automatically by the built-in feature in Evans.
From GitHub Releases
Please see GitHub Releases.
Available binaries are:
- macOS
- Linux
- Windows
macOS
brew tap ktr0731/evans
brew install evans
Docker image
You can use our docker image to run Evans - please see container registry.
For example, if you want to connect to the server on host example.com on port 50051 using proto file in ./proto/files/file-name.proto (default working directory is /mount):
$ docker run --rm -v "$(pwd):/mount:ro" \
ghcr.io/ktr0731/evans:latest \
--path ./proto/files \
--proto file-name.proto \
--host example.com \
--port 50051 \
repl
[Not-recommended] go install
Go v1.20 or later is required.
go install github.com/ktr0731/evans@latest
Usage (REPL)
Basic usage
Evans consists of some commands in REPL mode.
The proto file which read in the demonstration and its implementation are available at ktr0731/grpc-test.
grpc-test's details can see grpc-test --help.
Enter to REPL.
cd grpc-test
evans --proto api/api.proto repl
If your server is enabling gRPC reflection, you can launch Evans with only -r (--reflection) option.
evans -r repl
Also if the server requires secure TLS connections, you can launch Evans with the -t (--tls) option.
evans --tls --host example.com -r repl
To show package names of proto files REPL read:
> show package
+---------+
| PACKAGE |
+---------+
| api |
+---------+
To show the summary of services or messages:
> package api
> show service
+---------+----------------------+-----------------------------+----------------+
| SERVICE | RPC | REQUESTTYPE | RESPONSETYPE |
+---------+----------------------+-----------------------------+----------------+
| Example | Unary | SimpleRequest | SimpleResponse |
| | UnaryMessage | UnaryMessageRequest | SimpleResponse |
| | UnaryRepeated | UnaryRepeatedRequest | SimpleResponse |
| | UnaryRepeatedMessage | UnaryRepeatedMessageRequest | SimpleResponse |
| | UnaryRepeatedEnum | UnaryRepeatedEnumRequest | SimpleResponse |
| | UnarySelf | UnarySelfRequest | SimpleResponse |
| | UnaryMap | UnaryMapRequest | SimpleResponse |
| | UnaryMapMessage | UnaryMapMessageRequest | SimpleResponse |
| | UnaryOneof | UnaryOneofRequest | SimpleResponse |
| | UnaryEnum | UnaryEnumRequest | SimpleResponse |
| | UnaryBytes | UnaryBytesRequest | SimpleResponse |
| | ClientStreaming | SimpleRequest | SimpleResponse |
| | ServerStreaming | SimpleRequest | SimpleResponse |
| | BidiStreaming | SimpleRequest | SimpleResponse |
+---------+----------------------+-----------------------------+----------------+
> show message
+-----------------------------+
| MESSAGE |
+-----------------------------+
| SimpleRequest |
| SimpleResponse |
| Name |
| UnaryMessageRequest |
| UnaryRepeatedRequest |
| UnaryRepeatedMessageRequest |
| UnaryRepeatedEnumRequest |
| UnarySelfRequest |
| Person |
| UnaryMapRequest |
| UnaryMapMessageRequest |
| UnaryOneofRequest |
| UnaryEnumRequest |
| UnaryBytesRequest |
+-----------------------------+
To show more description of a message:
> desc SimpleRequest
+-------+-------------+
| FIELD | TYPE |
+-------+-------------+
| name | TYPE_STRING |
+-------+-------------+
Set headers for each request:
> header foo=bar
To show headers:
> show header
+-------------+-------+
| KEY | VAL |
+-------------+-------+
| foo | bar |
| grpc-client | evans |
+-------------+-------+
Note that if you want to set comma-included string to a header value, it is required to specify --raw option.
To remove the added header:
> header foo
> show header
+-------------+-------+
| KEY | VAL |
+-------------+-------+
| grpc-client | evans |
+-------------+-------+
Call a RPC:
> service Example
> call Unary
name (TYPE_STRING) => ktr
{
"message": "hello, ktr"
}
Evans constructs a gRPC request interactively and sends the request to a gRPC server.
Finally, Evans prints the JSON formatted result.
Repeated fields
repeated is an array-like data structure.
You can input some values and finish with <kbd>CTRL-D</kbd>
> call UnaryRepeated
<repeated> name (TYPE_STRING) => foo
<repeated> name (TYPE_STRING) => bar
<repeated> name (TYPE_STRING) => baz
<repeated> name (TYPE_STRING) =>
{
"message": "hello, foo, bar, baz"
}
Enum fields
You can select one from the proposed selections.
When <kbd>CTRL-C</kbd> is entered, default value 0 will be used.
When <kbd>CTRL-D</kbd> is entered, inputting will be aborted.
> call UnaryEnum
? UnaryEnumRequest [Use arrows to move, type to filter]
> Male
Female
{
"message": "M"
}
Bytes type fields
You can pass bytes as a base64-encoded string.
> call UnaryBytes
data (TYPE_BYTES) => SGVsbG8gV29ybGQh
{
"message": "received: (bytes) 48 65 6c 6c 6f 20 57 6f 72 6c 64 21, (string) Hello World!"
}
⚠️ Warning: Previously, bytes were passed as a (quoted) byte literal or Unicode literal string.
While evans currenty still attempts to fall back to that encoding if decoding as base64 fails, it's discouraged, and might be dropped.
Please either encode bytes as base64, or pass --bytes-as-quoted-literals
explicitly:
> call UnaryBytes --bytes-as-quoted-literals
data (TYPE_BYTES) => \x46\x6f\x6f
{
"message": "received: (bytes) 46 6f 6f, (string) Foo"
}
> call UnaryBytes --bytes-as-quoted-literals
data (TYPE_BYTES) => \u65e5\u672c\u8a9e
{
"message": "received: (bytes) e6 97 a5 e6 9c ac e8 aa 9e, (string) 日本語"
}
You can also add the flag --bytes-as-base64 to explicitly disable the
fallback behaviour.
Or add the flag --bytes-from-file to read bytes from the provided relative path
> call UnaryBytes --bytes-from-file
data (TYPE_BYTES) => ../relative/path/to/file
Client streaming RPC
Client streaming RPC accepts some requests and then returns on
Related Skills
node-connect
334.9kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
xurl
334.9kA CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.
frontend-design
82.3kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
334.9kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
