HARDWARIO Real Time Transfer Terminal Console
Overview
HARDWARIO Real Time Transfer Terminal Console (rttt) is a Python package that provides an interface for real-time data transfer using SEGGER J-Link RTT (Real-Time Transfer) technology. It enables efficient data communication between an embedded system and a host computer via RTT channels.
This package is particularly useful for debugging, logging, and real-time data visualization in embedded applications.
Features
- Real-time communication with embedded devices via RTT.
- Support for multiple RTT buffers (console and logger).
- Adjustable latency for optimized readout.
- J-Link support with configurable serial numbers, device types, and speeds.
- Command-line interface (CLI) for quick and easy access.
- Easy installation via PyPI.
Installation
To install the package, use:
pip install rttt
To verify the installation, run:
rttt --help
Usage
Basic Command
To start the RTT console:
rttt --device <DEVICE_NAME>
Available Options
Usage: rttt [OPTIONS]
HARDWARIO Real Time Transfer Terminal Console.
Options:
--version Show the version and exit.
--serial SERIAL_NUMBER J-Link serial number.
--device DEVICE J-Link Device name.
--speed SPEED J-Link clock speed in kHz. [default: 2000]
--reset Reset application firmware.
--flash-cmd COMMAND External command used by the flash operation
instead of the built-in J-Link programming.
Must contain the {file} placeholder.
--address ADDRESS RTT block address.
--terminal-buffer INTEGER RTT Terminal buffer index. [default: 0]
--logger-buffer INTEGER RTT Logger buffer index. [default: 1]
--latency INTEGER Latency for RTT readout in ms. [default: 50]
--history-file PATH Path to history file. [default: ~/.rttt_history]
--console-file PATH Path to console file. [default: ~/.rttt_console]
--mcp / --no-mcp Enable MCP server. [default: no-mcp]
--mcp-listen TEXT MCP server listen address [host:]port. [default: 127.0.0.1:8090]
--mcp-token TOKEN Require "Authorization: Bearer TOKEN" on the MCP
server and upload endpoint.
--substitutions / --no-substitutions
Enable template substitutions in terminal input.
[default: substitutions]
--trust-shells Trust shell substitutions in config without
interactive prompt (for CI/scripts).
--headless Run without the interactive console, MCP server
only (requires --mcp).
--help Show this message and exit.
Examples
Connect to a device (replace NRF52840_xxAA with your actual device name):
rttt --device NRF52840_xxAA
Use a specific J-Link serial number:
rttt --device NRF52840_xxAA --serial 123456789
Configuration File
RTTT supports configuration via .rttt.yaml files. All existing files are loaded and deep-merged, so you can keep user-wide defaults in your home directory and override specific keys per project. The load order, from lowest to highest priority, is:
~/.config/rttt.yaml— user defaults~/.rttt.yaml— user defaults (alternative location)./.rttt.yaml— project-specific overridesRTTT_*environment variables- Command-line flags
Nested mappings (like substitutions:) merge per-key — a project config can add new substitutions without losing the ones defined in your home config, or override specific ones by name.
Example Configuration:
device: NRF9151_XXCA
console_file: "test.log"
substitutions:
RTC_SET: "rtc set {{UTC_NOW}}"
With this configuration, simply running:
rttt
Input Substitutions
RTTT can expand {{NAME}} placeholders in commands you type in the terminal before they are sent to the device. This is handy for things like setting the current time on the device without typing it manually:
rtc set {{UTC_NOW}}
gets expanded to (example):
rtc set 2026/04/20 10:08:00
Built-in Substitutions
| Placeholder | Output | Notes |
|---|---|---|
{{UTC_NOW}} |
2026/04/20 10:08:00 |
UTC, default format %Y/%m/%d %H:%M:%S |
{{UTC_NOW:<fmt>}} |
e.g. 2026-04-20 |
Any strftime format, e.g. {{UTC_NOW:%Y-%m-%d}} |
{{LOCAL_NOW}} |
2026/04/20 12:08:00 |
Local time, same default format |
{{LOCAL_NOW:<fmt>}} |
e.g. 12:08:00 |
Any strftime format |
{{UNIX_NOW}} |
1776636480 |
Unix timestamp (seconds), format is ignored |
Placeholder names must be upper-case letters, digits, and underscores, and start with a letter or underscore.
Custom Substitutions
Define your own values in .rttt.yaml under the substitutions key. Values are strings and may reference other substitutions (built-in or custom):
substitutions:
RTC_SET: "rtc set {{UTC_NOW}}"
PROJECT: "nrf9151-demo"
HEADER: "DEV={{PROJECT}} T={{UTC_NOW}}"
Then typing {{RTC_SET}} in the terminal sends e.g. rtc set 2026/04/20 10:08:00 to the device.
Custom names take precedence over built-ins, so you can override UTC_NOW with a fixed value if needed.
Multi-Line Substitutions
A substitution value may contain newlines. When the expanded text spans multiple lines, each line is sent as a separate input event to the device. This is useful for grouping a batch of commands under a single placeholder:
substitutions:
CONFIG: |
app config interval-sample 60
app config interval-aggreg 300
app config interval-report 1800
{{RTC_SET}}
Typing {{CONFIG}} sends all five commands in order. Nested placeholders (like {{RTC_SET}} above) are expanded recursively before the fan-out.
Shell Substitutions
A substitution value can also be a shell command, evaluated lazily each time the placeholder is expanded:
substitutions:
GIT_SHA:
shell: "git rev-parse --short HEAD"
BUILD_HEADER: "build={{GIT_SHA}} at {{UTC_NOW}}"
Options for a shell: entry:
| Key | Default | Description |
|---|---|---|
shell |
(required) | Command passed to /bin/sh -c. |
cwd |
current working directory | Directory to run the command in. ~ is expanded. |
multiline |
false |
If true, the full output is used (newlines in it cause the command to be split and sent as multiple lines to the device). If false, only the first line is used. |
Commands have a 5 second timeout. On failure (non-zero exit, timeout, or missing binary), the placeholder is left in the text and a warning is logged.
Trust prompt. Because a .rttt.yaml in a project you didn't write could run commands on your machine, rttt asks for confirmation the first time it sees a new set of shell substitutions. The approval is cached in ~/.hardwario/rttt_allowed_shells as a hash of the command list plus the absolute config path — you only get asked again if the commands actually change. For non-interactive use (CI, scripts), pass --trust-shells to skip the prompt.
Enabling / Disabling
Substitutions are enabled by default, so built-ins like {{UTC_NOW}} work out of the box. Use --no-substitutions on the command line to disable them for a single session (for example if you actually need to send the literal text {{UTC_NOW}} to the device).
Errors
If a placeholder name is unknown, references itself (cycle), or the format string fails, the placeholder is left in the text as-is and a warning is written to ~/.hardwario/rttt.log. The command is still sent to the device so you don't lose keystrokes.
MCP Server (AI Integration)
RTTT includes a built-in Model Context Protocol (MCP) server that allows AI tools (Claude, Cursor, etc.) to interact with your embedded device via RTT.
MCP server is enabled by default. Start RTTT as usual:
rttt --device NRF52840_xxAA --mcp
Claude Code Configuration
Add to your .mcp.json:
{
"mcpServers": {
"rttt": {
"type": "http",
"url": "http://127.0.0.1:8090/mcp"
}
}
}
When the server runs with --mcp-token, add the matching header:
{
"mcpServers": {
"rttt": {
"type": "http",
"url": "http://127.0.0.1:8090/mcp",
"headers": {
"Authorization": "Bearer <TOKEN>"
}
}
}
}
Authentication
By default the MCP server has no authentication and binds to 127.0.0.1,
which is fine for local use. When exposing it to a network (e.g.
--mcp-listen 0.0.0.0:8090 on a shared debug box), set a token:
rttt --device NRF9151_XXCA --mcp --mcp-token "$(openssl rand -hex 16)"
Every HTTP request — both the /mcp endpoint and /upload — must then carry
Authorization: Bearer <TOKEN>; anything else gets 401 Unauthorized. The
token can also come from the RTTT_MCP_TOKEN environment variable or the
mcp_token key in .rttt.yaml. Note the transport is plain HTTP, so on an
untrusted network the token (and everything else) is visible on the wire —
use an SSH tunnel or a TLS reverse proxy for anything beyond a lab LAN.
Available MCP Tools
| Tool | Description |
|---|---|
send_command(command, timeout) |
Send a shell command to the device and wait for response |
read_terminal(lines) |
Read recent terminal output (device responses and sent commands) |
read_log(lines, after_cursor, pattern) |
Read log output from the device ring buffer, with optional regex filter |
status() |
Get session statistics (line counts, buffer usage, cursors) |
flash(file_path, addr) |
Flash a firmware file (.hex, .bin, .elf, .srec) to the target device |
reconnect() |
Re-attach a stuck RTT session without resetting the device |
reset(halt) |
Reset the target; RTT re-attaches automatically (unless halting) |
halt() / go() |
Stop / resume the target CPU |
target_status() |
CPU halted flag and core identification |
read_memory(address, length, width) |
Hexdump of RAM, peripherals or memory-mapped flash |
write_memory(address, data, width) |
Write RAM or peripheral registers |
write_flash(address, data) |
Program internal flash bytes (reset+halt, program, reboot) |
read_registers() |
Core CPU registers (requires a halted target) |
memory_zones() |
Memory zones supported by the J-Link for the target |
The server also exposes a debug_device MCP prompt describing typical
debugging workflows and RTT troubleshooting for agent clients.
External Flash Command
By default the flash operation programs the device through the J-Link DLL.
When a different tool works better for your target (e.g. nrfjprog for nRF91,
hardwario CLI, west flash), override it with --flash-cmd or the
flash_cmd key in .rttt.yaml:
rttt --device NRF9151_XXCA --mcp \
--flash-cmd 'nrfjprog --family NRF91 --program {file} --sectorerase --verify --reset'
flash_cmd: "nrfjprog --family NRF91 --program {file} --sectorerase --verify --reset"
The command runs through the shell with these placeholders (values are shell-quoted automatically):
| Placeholder | Value |
|---|---|
{file} |
Absolute path of the firmware file (required in the template) |
{addr} |
Start address as hex, e.g. 0x0 |
{device} |
J-Link device name |
{serial} |
J-Link serial number (empty if not set) |
The J-Link connection is released for the duration of the command so the
external tool can claim the debug probe, and RTT re-attaches afterwards. The
tool's output is streamed to the console and log. With an external command
the .zip extension is also accepted (nrfjprog modem firmware packages).
Because flash_cmd from a config file is an arbitrary shell command, it goes
through the same trust prompt as shell substitutions
— you approve it once per config file (or pass --trust-shells in CI).
Headless Mode
For CI boxes, remote debug servers or fully agent-driven sessions, run the MCP server without the interactive console:
rttt --device NRF9151_XXCA --mcp --headless
Uploading Firmware from a Remote Client
The flash tool resolves paths on the machine rttt runs on. When the MCP
client runs elsewhere, upload the firmware first via the HTTP endpoint served
on the same port:
curl --data-binary @fw.hex 'http://<host>:8090/upload?filename=fw.hex'
# → {"status": "ok", "path": "/tmp/rttt-uploads-8090/fw.hex", "size": 123456}
Then pass the returned path to the flash tool. Allowed extensions are
.hex, .bin, .elf and .srec; the body is limited to 64 MiB.
With --mcp-token set, include the header:
curl -H 'Authorization: Bearer <TOKEN>' \
--data-binary @fw.hex 'http://<host>:8090/upload?filename=fw.hex'
Note: without
--mcp-tokenthe MCP server and the upload endpoint have no authentication. The default bind is127.0.0.1; set a token before exposing them with--mcp-listen 0.0.0.0:8090outside a trusted network (see Authentication).
License
This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤ by HARDWARIO a.s. in the heart of Europe.
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 rttt-1.6.0.tar.gz.
File metadata
- Download URL: rttt-1.6.0.tar.gz
- Upload date:
- Size: 36.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d862359d467df6940f21fffee7ad5c924d26e0d663afbfffed79e7fa9e9a127
|
|
| MD5 |
0d9ede4cbb1633a1b9fa6ff3a64ccf9d
|
|
| BLAKE2b-256 |
74525ce2577610057319f6ff2f0fb12ba181e870191ed223ba0a7463d01233a6
|
Provenance
The following attestation bundles were made for rttt-1.6.0.tar.gz:
Publisher:
publish.yaml on hardwario/py-rttt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rttt-1.6.0.tar.gz -
Subject digest:
1d862359d467df6940f21fffee7ad5c924d26e0d663afbfffed79e7fa9e9a127 - Sigstore transparency entry: 2161338277
- Sigstore integration time:
-
Permalink:
hardwario/py-rttt@0ba09fde31731f542fe1dd8d093767bf1e97d925 -
Branch / Tag:
refs/tags/v1.6.0 - Owner: https://github.com/hardwario
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@0ba09fde31731f542fe1dd8d093767bf1e97d925 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rttt-1.6.0-py3-none-any.whl.
File metadata
- Download URL: rttt-1.6.0-py3-none-any.whl
- Upload date:
- Size: 37.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c98ee55e200e3df4817378e018b0f6c8d9b7f1d34e2c648113ab6dfb63c2b808
|
|
| MD5 |
3173663e3e551e6380e84a57afc49190
|
|
| BLAKE2b-256 |
294597cec08949c0fdc80c3cfa66fcdbcd7b4bd10d09d4ed4774ced92c8f689e
|
Provenance
The following attestation bundles were made for rttt-1.6.0-py3-none-any.whl:
Publisher:
publish.yaml on hardwario/py-rttt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rttt-1.6.0-py3-none-any.whl -
Subject digest:
c98ee55e200e3df4817378e018b0f6c8d9b7f1d34e2c648113ab6dfb63c2b808 - Sigstore transparency entry: 2161338452
- Sigstore integration time:
-
Permalink:
hardwario/py-rttt@0ba09fde31731f542fe1dd8d093767bf1e97d925 -
Branch / Tag:
refs/tags/v1.6.0 - Owner: https://github.com/hardwario
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@0ba09fde31731f542fe1dd8d093767bf1e97d925 -
Trigger Event:
push
-
Statement type: