Labsco
bnomei logo

Raymon

17

from bnomei

Stateful HTTP ingest + MCP server + terminal UI for Ray-style logs.

🔥🔥🔥✓ VerifiedAccount requiredNeeds API keys

raymon

Crates.io Downloads

Raymon is a local-first Ray-style log receiver with an HTTP ingest endpoint, a Streamable HTTP MCP server, durable JSONL storage, and a Ratatui terminal UI.

Use Raymon when you want Ray-compatible dumps from your app to be visible in a terminal and searchable by AI agents through MCP.

Raymon terminal UI screenshot

What Raymon provides

SurfaceWhat it does
HTTP ingestAccepts Ray-style JSON envelopes on POST /.
MCP serverExposes raymon.search and raymon.get_entries on POST /mcp.
Terminal UIBrowses live logs, filters by screen/type/color, opens payloads, yanks details, and manages JSONL archives.
StoragePersists entries to data/entries.jsonl under the active storage root.
Rust crate APIExposes raymon::run() plus public raymon_core, raymon_ingest, raymon_storage, raymon_mcp, and raymon_tui modules for embedding and tests.

Raymon listens on the Ray default port, 23517, so many Ray client libraries can target it with little or no configuration.

Sending logs

Raymon stores Ray-style log entries. Generate them with a Ray-compatible library in your application, then point that library at Raymon's host and port.

Known Ray integrations include PHP, JavaScript, Bash, Ruby, Python, Go, Dart, and Rust. For Rust-native payloads, see ray-dbg.

The default local endpoint is:

http://127.0.0.1:23517/

If your sender uses the Ray desktop defaults, Raymon usually works by starting raymon before you emit logs.

Inbound envelopes must include a non-empty uuid, at least one payload, a non-empty payloads[*].type, and a non-empty payloads[*].origin.hostname. When the same UUID is ingested more than once, Raymon merges the payloads into one entry and stores the merged entry before it publishes live state or events.

Run modes

Local TUI

raymon

This starts the HTTP ingest endpoint, the MCP endpoint, and the TUI on 127.0.0.1:23517.

Headless local server

RAYMON_NO_TUI=1 raymon

Use this for background logging, MCP-only workflows, or tests.

Remote server with auth

export RAYMON_AUTH_TOKEN="change-me"
RAYMON_ALLOW_REMOTE=1 \
RAYMON_HOST=0.0.0.0 \
RAYMON_NO_TUI=1 \
raymon

Raymon refuses non-loopback binds unless RAYMON_ALLOW_REMOTE=1 is set. If the bind address is non-loopback, Raymon also requires RAYMON_AUTH_TOKEN unless you explicitly set RAYMON_ALLOW_INSECURE_REMOTE=1.

CLI reference

raymon [OPTIONS]
OptionMeaning
--host <HOST>Override the HTTP bind host.
--port <PORT>Override the HTTP bind port.
--config <PATH>Load a specific JSON config file instead of searching for ray.json.
--ide <COMMAND>Command used by the TUI to open origin files.
--editor <COMMAND>Command used by the TUI to open selected detail payloads in a temp file.
--jq <COMMAND>jq command used for detail-pane searches.
--tuiEnable the TUI.
--no-tuiDisable the TUI.
--demoGenerate local demo events.
-v, --verboseEnable info logging. Use -vv for debug logging.
-h, --helpPrint CLI help.
-V, --versionPrint the Raymon version.

Configuration precedence is:

  1. Defaults.
  2. ray.json.
  3. Environment variables.
  4. CLI flags.

Storage

Raymon stores entries as newline-delimited JSON in:

data/entries.jsonl

The data/ directory is created under the active storage root. The TUI also writes session archives under:

data/archives/

On startup, Raymon restores stored entries into the core state so MCP search can see persisted logs. The TUI starts with a fresh live view and lets you browse archive files from the archives pane.

Retention keeps the newest distinct UUIDs. During restore, Raymon skips corrupt JSONL lines and legacy blob entries instead of aborting startup.

HTTP API

Method and pathPurpose
POST /Ray ingest endpoint for Ray payload envelopes.
POST /mcpMCP Streamable HTTP endpoint. Prefer this path for MCP clients.

POST / also accepts MCP JSON-RPC requests as a compatibility fallback when ingest parsing rejects the body and the JSON looks like MCP JSON-RPC. Prefer /mcp for new MCP clients.

When RAYMON_AUTH_TOKEN is set, every request must include one of these headers:

Authorization: Bearer <token>
x-raymon-token: <token>

Ingest responses use HTTP status codes:

StatusMeaning
200The envelope was stored and published.
400The request body was invalid JSON.
413The merged entry exceeded RAYMON_MAX_BODY_BYTES.
422The envelope was missing required fields or had invalid data.
500Storage, state, or event-bus handling failed.

MCP tools

Raymon exposes two read-only tools.

raymon.search

Search stored entries and return compact summaries.

Input:

{
  "query": "string (optional; plain text or /regex/)",
  "types": ["string"],
  "colors": ["string"],
  "screen": "string (optional)",
  "project": "string (optional)",
  "host": "string (optional)",
  "limit": "number (optional)",
  "offset": "number (optional)"
}

types and colors also accept comma-separated strings:

{ "types": "error,exception", "colors": "red" }

Result:

{
  "entries": [
    {
      "uuid": "string",
      "received_at": 0,
      "project": "string",
      "host": "string",
      "screen": "string",
      "payload_count": 1,
      "payload_types": ["log"]
    }
  ],
  "count": 1,
  "limit": 100,
  "offset": 0,
  "scan_limit": 5000
}

Defaults and limits:

FieldDefaultLimit
limit100500
offset05000
scan_limit5000Fixed newest-entry scan window
queryunsetRAYMON_MAX_QUERY_LEN bytes

raymon.get_entries

Fetch full entries by UUID.

Input:

{
  "uuids": ["<uuid>"],
  "redact": false
}

Supported input aliases:

{ "uuid": "<uuid>" }
{ "uuids": "<uuid-1>,<uuid-2>" }

redacted and redact_payloads are aliases for redact. When redaction is enabled, Raymon replaces sensitive-looking payload fields such as passwords, tokens, API keys, cookies, and secrets.

Result:

{
  "entries": [
    {
      "uuid": "string",
      "received_at": 0,
      "project": "string",
      "host": "string",
      "screen": "string",
      "session_id": null,
      "payloads": [
        {
          "type": "log",
          "content": {},
          "origin": {
            "project": "string",
            "host": "string",
            "screen": "string",
            "session_id": null,
            "function_name": null,
            "file": null,
            "line_number": null
          }
        }
      ]
    }
  ]
}

Limits:

LimitValue
UUIDs per request100
Bytes per UUID265
Serialized tool result1048576 bytes

Connected MCP peers receive ray/event notifications for inserted, updated, cleared, and lagged events. If a client receives a lag notification, it should refresh with raymon.search.

TUI

The TUI is keyboard-first and has built-in help. Press ? for the full keymap.

KeyAction
?Open keybindings.
qQuit Raymon and stop the HTTP/MCP server.
SpaceOpen the picker menu.
/ or fSearch messages and file paths with fuzzy search.
rStart a regex search.
:Search inside the selected detail payload. Uses jq for JSON queries when available.
j/k, arrowsMove in the focused pane.
h/l, left/right arrowsMove focus left or right.
J/K, PageUp/PageDownScroll the detail pane.
Tab, Shift+TabMove focus between logs, detail, and archives.
gGo to a log position.
GJump to the last log.
sSnap color and type filters to the selected log entry.
uReset search and filters.
pPause or resume live updates.
aToggle the archives pane.
xArchive the current view to a JSONL file.
EnterLoad the selected archive when the archives pane has focus.
nRename the selected archive. Live archives cannot be renamed.
dDelete the selected archive after confirmation. Live archives cannot be deleted.
yYank the selected list entry.
YYank the selected detail payload.
zToggle expanded JSON rendering.
ZToggle raw JSON rendering.
mToggle style and metadata payloads in the detail pane.
1 through 6Toggle list columns: color dot, timestamp, type label, file, message, UUID.
oOpen the origin file in the configured IDE.
eOpen the selected detail payload in the configured editor.
Ctrl+lClear the live log list without deleting stored entries.
Ctrl+cQuit from anywhere.

Mouse support is enabled: click to focus or select, and use the wheel to move through the pane under the pointer.

Raymon uses the terminal ANSI palette by default, so it inherits light, dark, and base16-style terminal themes. Use RAYMON_TUI_PALETTE when you need a fixed palette.

Agent skill

This repository includes an AI-facing runbook at skills/raymon/SKILL.md. It teaches agents how to:

  • Generate Ray-style events with common Ray integrations.
  • Add Raymon as a local or remote MCP server.
  • Use raymon.search before raymon.get_entries to inspect logs efficiently.

The skill is documentation for agents. It is not runtime code.

Source layout

PathPurpose
src/cli.rsRuntime lifecycle, configuration, storage restore, demo mode, and TUI/server orchestration.
src/cli/http.rsAxum router, auth, body limits, concurrency limits, ingest, and MCP mounting.
src/raymon_core.rsIO-free domain types, filters, events, and Ray envelope normalization.
src/raymon_ingest.rsHTTP ingest parsing, validation, duplicate-UUID merging, storage, and event emission.
src/raymon_mcp.rsMCP tools, notifications, query limits, result limits, and shutdown hooks.
src/raymon_mcp/schema.rsMCP request and response schemas.
src/raymon_storage/JSONL persistence, indexing, listing, and retention.
src/raymon_tui.rsTUI state, rendering, search, filtering, key handling, editor integration, and archive workflows.
tests/ray_php_local.rsIgnored local PHP/Ray integration test.

Development

Run the Rust test suite:

cargo test --all-targets

Run formatting and clippy checks:

cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings

Run pre-commit hooks when prek is installed:

prek validate-config prek.toml
prek run --all-files
prek install

Run the local-only PHP Ray integration test after installing the global PHP ray() helper:

cargo test --test ray_php_local -- --ignored ray_php_local_integration

Build and package release artifacts:

TARGET=x86_64-apple-darwin scripts/build-release.sh
VERSION=0.7.0 TARGET=x86_64-apple-darwin scripts/package-release.sh

The release workflow builds Linux musl (x86_64, aarch64), macOS (x86_64, aarch64), and Windows MSVC (x86_64) targets. Unix artifacts are .tar.gz archives, Windows artifacts are .zip archives, and each package gets a .sha256 file.