Back to Serial Studio

gRPC server

doc/help/gRPC-Server.md

4.0.18.0 KB
Original Source

gRPC server

Table of contents

Overview

Serial Studio exposes its entire API over gRPC on port 8888. The gRPC server starts automatically when the API server is enabled. It provides:

  • High-performance frame streaming. Binary protobuf encoding is roughly 5 to 10 times smaller and faster than JSON.
  • Typed service definition. A full .proto file for code generation in any language.
  • Server-streaming RPCs. Real-time frame and raw data push, no polling.
  • Cross-language support. Python, C++, Go, Java, Rust, Node.js, C#, and more.

The gRPC server shares the same command set as the TCP/JSON API. Any command available on port 7777 can run over gRPC on port 8888.

Turning gRPC on

The gRPC server starts automatically whenever the API server is enabled:

  1. Open Preferences (wrench icon or Ctrl/Cmd+,).
  2. On the General tab, scroll to the Advanced section.
  3. Turn on "Enable API Server (Port 7777)".
  4. Click OK.

Both the TCP/JSON server (port 7777) and the gRPC server (port 8888) start together.

Service definition

The gRPC API is defined in doc/grpc/serialstudio.proto in the Serial Studio repository (package serialstudio). Generate client stubs from that file:

protobuf
service SerialStudioAPI {
  rpc ExecuteCommand(CommandRequest) returns (CommandResponse);
  rpc ExecuteBatch(BatchRequest) returns (BatchResponse);
  rpc StreamFrames(StreamRequest) returns (stream FrameBatch);
  rpc StreamRawData(StreamRequest) returns (stream RawBatch);
  rpc WriteRawData(RawDataRequest) returns (CommandResponse);
  rpc ListCommands(google.protobuf.Empty) returns (CommandList);
}
RPCDescription
ExecuteCommandExecute a single API command and get the result.
ExecuteBatchExecute multiple commands in one request.
StreamFramesServer-streaming RPC that pushes parsed frames in real time.
StreamRawDataServer-streaming RPC that pushes raw bytes from the device.
WriteRawDataSend raw bytes to the connected device.
ListCommandsList all available API commands.

Quick start (Python)

Install the gRPC Python packages:

bash
pip install grpcio grpcio-tools

Connect and execute commands:

python
import grpc
import serialstudio_pb2 as pb
import serialstudio_pb2_grpc as rpc

channel = grpc.insecure_channel('localhost:8888')
stub = rpc.SerialStudioAPIStub(channel)

# Execute a command
resp = stub.ExecuteCommand(pb.CommandRequest(
    id="1", command="io.getStatus"))
print(resp.result)

# Stream frames in real-time (each message is a FrameBatch)
for batch in stub.StreamFrames(pb.StreamRequest()):
    for frame in batch.frames:
        print(frame.frame)  # protobuf Struct, convertible to dict

Quick start (grpcurl)

grpcurl is a command-line tool for interacting with gRPC servers:

bash
# List available commands
grpcurl -plaintext localhost:8888 serialstudio.SerialStudioAPI/ListCommands

# Execute a command
grpcurl -plaintext -d '{"command":"io.getStatus","id":"1"}' \
  localhost:8888 serialstudio.SerialStudioAPI/ExecuteCommand

# Stream frames (Ctrl+C to stop)
grpcurl -plaintext localhost:8888 serialstudio.SerialStudioAPI/StreamFrames

About the "Export Protobuf File" button. The Export… button under Preferences → General → Advanced → Export Protobuf File writes an auto-generated typed schema (package serialstudio.typed, service SerialStudioTypedAPI) with one request message and one RPC per registered command. Use it as machine-readable documentation of every command's parameters. The running server implements only the dynamic SerialStudioAPI service shown above, so generate client stubs from the repo's doc/grpc/serialstudio.proto, not from the exported typed file.

Generating client stubs

Download doc/grpc/serialstudio.proto from the Serial Studio repository, then generate stubs for your language:

bash
# Python
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. serialstudio.proto

# C++
protoc -I. --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin serialstudio.proto

# Go
protoc -I. --go_out=. --go-grpc_out=. serialstudio.proto

# Java
protoc -I. --java_out=. --grpc-java_out=. serialstudio.proto

# C# / .NET
protoc -I. --csharp_out=. --grpc_out=. --plugin=protoc-gen-grpc=grpc_csharp_plugin serialstudio.proto

Frame streaming

The StreamFrames RPC is the primary way plugins and external tools receive real-time data. The TCP/JSON server also pushes frames (as JSON lines broadcast to every connected client), but gRPC delivers them as compact binary messages on an explicit per-client stream, which holds up better at high frame rates.

python
# Stream frames with automatic reconnection
import time

def stream_with_retry(stub):
    while True:
        try:
            for batch in stub.StreamFrames(pb.StreamRequest()):
                for frame in batch.frames:
                    process_frame(frame)
        except grpc.RpcError as e:
            if e.code() == grpc.StatusCode.UNAVAILABLE:
                time.sleep(1)
                continue
            raise

Each stream message is a FrameBatch whose frames field holds one or more FrameData entries. Each FrameData contains:

  • frame. The parsed frame as a protobuf Struct (equivalent to a JSON object).
  • timestamp_ms. The frame's timestamp in milliseconds.

External connections

The gRPC server follows the same Allow External API Connections setting as the TCP server:

SettingTCP/JSON (7777)gRPC (8888)
Disabled (default)127.0.0.1:7777127.0.0.1:8888
Enabled0.0.0.0:77770.0.0.0:8888

Enable external connections under Preferences → General → Advanced → Allow External API Connections.

Security note. Enabling external connections exposes the API to your network. Non-loopback clients must then authenticate: send the access token (shown in the API Access Token field next to the external-connections switch) in the x-serial-studio-token request metadata. Loopback clients (127.0.0.1 / ::1) are exempt. The token is the only barrier, so keep it secret and disable external access when it is not needed.

Comparison with the TCP/JSON API

FeatureTCP/JSON (port 7777)gRPC (port 8888)
EncodingJSON textProtobuf binary
Frame streamingJSON lines pushed to all clientsServer-push (StreamFrames)
Message sizeLarger (JSON overhead)About 5 to 10 times smaller
Code generationManual parsingAuto-generated stubs
Browser supportWebSocket/TCP clientsgrpc-web (needs a proxy)
Ease of usenc, curl, any TCP clientNeeds gRPC tooling

When to use gRPC:

  • Plugins that process real-time frame data at high rates.
  • Applications where serialization overhead matters.
  • Projects that benefit from strongly typed generated clients.

When to use TCP/JSON:

  • Quick scripting and debugging (nc, curl).
  • Environments without gRPC tooling.
  • MCP (Model Context Protocol) integration with AI assistants.

See the API Reference for the full command list. It's shared by both protocols.