gRPC server exposing LinuxCNC machine control and HAL functionality
Project description
linuxcnc-grpc
gRPC interface for LinuxCNC machine control and HAL (Hardware Abstraction Layer).
Why gRPC?
LinuxCNC's native Python API only works locally. This project exposes it over gRPC, enabling:
- Remote monitoring - Build web dashboards, mobile apps, or desktop GUIs
- Multi-machine management - Monitor a fleet of CNC machines from one place
- Any-language integration - Use Go, Node.js, Rust, or any gRPC-supported language
- Real-time streaming - Subscribe to status updates instead of polling
Running the Server
The server runs on your LinuxCNC machine and exposes the gRPC interface.
Basic Usage
pip install linuxcnc-grpc
# or with uv
uv pip install linuxcnc-grpc
linuxcnc-grpc --host 0.0.0.0 --port 50051
LinuxCNC must already be running before starting the server.
Auto-start with LinuxCNC
To start the gRPC server automatically when LinuxCNC launches, add to your machine's HAL file:
# Start gRPC server (runs until LinuxCNC exits)
loadusr -W linuxcnc-grpc --host 0.0.0.0 --port 50051
Or use a dedicated HAL file via your INI:
[HAL]
POSTGUI_HALFILE = grpc-server.hal
The -W flag tells LinuxCNC to wait for the server to become ready before continuing.
Quick Start
Python
pip install linuxcnc-grpc
import grpc
from linuxcnc_pb import linuxcnc_pb2, linuxcnc_pb2_grpc
channel = grpc.insecure_channel("localhost:50051")
stub = linuxcnc_pb2_grpc.LinuxCNCServiceStub(channel)
status = stub.GetStatus(linuxcnc_pb2.GetStatusRequest())
print(f"Position: X={status.position.x:.3f} Y={status.position.y:.3f} Z={status.position.z:.3f}")
Go
go get github.com/dougcalobrisi/linuxcnc-grpc
import (
pb "github.com/dougcalobrisi/linuxcnc-grpc/packages/go"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
conn, _ := grpc.NewClient("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()))
client := pb.NewLinuxCNCServiceClient(conn)
status, _ := client.GetStatus(context.Background(), &pb.GetStatusRequest{})
fmt.Printf("Position: X=%.3f Y=%.3f Z=%.3f\n", status.Position.X, status.Position.Y, status.Position.Z)
Node.js / TypeScript
npm install linuxcnc-grpc
import * as grpc from "@grpc/grpc-js";
import { LinuxCNCServiceClient, GetStatusRequest } from "linuxcnc-grpc";
const client = new LinuxCNCServiceClient("localhost:50051", grpc.credentials.createInsecure());
client.getStatus(GetStatusRequest.create(), (err, status) => {
console.log(`Position: X=${status.position.x.toFixed(3)} Y=${status.position.y.toFixed(3)}`);
});
Rust
[dependencies]
linuxcnc-grpc = "0.5"
tokio = { version = "1", features = ["full"] }
tonic = "0.12"
use linuxcnc_grpc::linuxcnc::linux_cnc_service_client::LinuxCncServiceClient;
use linuxcnc_grpc::linuxcnc::GetStatusRequest;
let mut client = LinuxCncServiceClient::connect("http://localhost:50051").await?;
let status = client.get_status(GetStatusRequest {}).await?.into_inner();
println!("Position: X={:.3} Y={:.3}", status.position.unwrap().x, status.position.unwrap().y);
Examples
Complete examples for all supported languages:
| Example | Description | Python | Go | Node.js | Rust |
|---|---|---|---|---|---|
get_status |
Poll machine status | view | view | view | view |
stream_status |
Real-time status streaming | view | view | view | view |
jog_axis |
Jog axes with keyboard | view | view | view | view |
mdi_command |
Execute G-code via MDI | view | view | view | view |
hal_query |
Query HAL pins/signals | view | view | view | view |
upload_file |
Upload, list, delete G-code files | view | view | view | view |
See examples/README.md for setup instructions.
Services
- LinuxCNCService - Machine control: status, jogging, MDI, program execution, file management
- HalService - HAL introspection: query pins, signals, parameters (read-only)
File Management
The server provides UploadFile, ListFiles, and DeleteFile RPCs for remote G-code file management. Files are stored in the NC files directory (default: /home/linuxcnc/linuxcnc/nc_files).
Configure the directory with --nc-files or the LINUXCNC_NC_FILES environment variable:
linuxcnc-grpc --host 0.0.0.0 --nc-files /path/to/nc_files
Safety Warning
This server provides remote control of CNC machinery. Ensure proper safety measures:
- Use only on trusted networks
- Implement authentication in production (gRPC supports TLS/mTLS)
- Never leave machines unattended during remote operation
- Verify E-stop and safety systems are functional
Production Deployment
For production use, enable TLS authentication:
# Server with TLS
credentials = grpc.ssl_server_credentials([(private_key, certificate)])
server.add_secure_port('[::]:50051', credentials)
# Client with TLS
credentials = grpc.ssl_channel_credentials(root_certificates)
channel = grpc.secure_channel('your-machine:50051', credentials)
See Server Configuration for complete TLS setup instructions.
Development
Requires uv for Python dependency management:
# Install dev dependencies
make setup
# Run tests
make test # Python tests
make test-all # All languages
# Generate proto code
make proto-all # Regenerate for all languages
See CLAUDE.md for detailed development documentation.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file linuxcnc_grpc-0.6.0b5.tar.gz.
File metadata
- Download URL: linuxcnc_grpc-0.6.0b5.tar.gz
- Upload date:
- Size: 59.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cfc158bf7ee581cab377cdd3726b5645605420e228ef177d6d506aa4d47fdef7
|
|
| MD5 |
326dcf3867e5f28b581350d7a63514d5
|
|
| BLAKE2b-256 |
61855cc5eecbc0df0932603726559427b554de85b87557afcc62c59267f37c0d
|
Provenance
The following attestation bundles were made for linuxcnc_grpc-0.6.0b5.tar.gz:
Publisher:
release.yml on dougcalobrisi/linuxcnc-grpc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
linuxcnc_grpc-0.6.0b5.tar.gz -
Subject digest:
cfc158bf7ee581cab377cdd3726b5645605420e228ef177d6d506aa4d47fdef7 - Sigstore transparency entry: 1204387329
- Sigstore integration time:
-
Permalink:
dougcalobrisi/linuxcnc-grpc@0157979dba18e3aeaa07fef1f54ec00cafbf08dc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/dougcalobrisi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0157979dba18e3aeaa07fef1f54ec00cafbf08dc -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file linuxcnc_grpc-0.6.0b5-py3-none-any.whl.
File metadata
- Download URL: linuxcnc_grpc-0.6.0b5-py3-none-any.whl
- Upload date:
- Size: 39.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9358b0262f16ee0d54bc0618f353c3f618fb32b68964d8af41a3d2b2c91d313d
|
|
| MD5 |
92e2af935ebae63231305472a0a51b12
|
|
| BLAKE2b-256 |
326796512247fff69601adbccd72402a12da1c645cc7a785e699d733536249d1
|
Provenance
The following attestation bundles were made for linuxcnc_grpc-0.6.0b5-py3-none-any.whl:
Publisher:
release.yml on dougcalobrisi/linuxcnc-grpc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
linuxcnc_grpc-0.6.0b5-py3-none-any.whl -
Subject digest:
9358b0262f16ee0d54bc0618f353c3f618fb32b68964d8af41a3d2b2c91d313d - Sigstore transparency entry: 1204387330
- Sigstore integration time:
-
Permalink:
dougcalobrisi/linuxcnc-grpc@0157979dba18e3aeaa07fef1f54ec00cafbf08dc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/dougcalobrisi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0157979dba18e3aeaa07fef1f54ec00cafbf08dc -
Trigger Event:
workflow_dispatch
-
Statement type: