No description
  • Rust 64.8%
  • HTML 16.4%
  • Shell 11.2%
  • JavaScript 4.6%
  • CSS 2.2%
  • Other 0.8%
Find a file
Timur Gordon 77a9066896
Some checks failed
Build & Test / check (pull_request) Failing after 1m51s
Build & Test / check (push) Failing after 2m21s
fix(mcp): pass named args through instead of named->positional conversion
Hero services codegen'd from OSchema only accept named (object) JSON-RPC
params, not positional (array). The MCP gateway's named_to_positional
conversion was breaking every tool call — e.g. page_create with
{browser_id, url} got converted to ["abc", "https://..."] which
hero_browser rejected with "missing browser_id".

Switch to passing `arguments` straight through as the backend's params.
If arguments is null (tool with no args), send {} so the downstream
deserializer sees a valid empty object.

`named_to_positional` and `coerce_value` helpers remain in the file
but are now dead code; leaving them in place in case a future backend
actually needs positional — can be removed in a follow-up cleanup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 12:38:05 +02:00
.forgejo/workflows ci: reorder and rename CI steps 2026-04-12 18:35:55 +02:00
crates fix(mcp): pass named args through instead of named->positional conversion 2026-04-20 12:38:05 +02:00
docs fix: change port 2026-04-08 13:29:56 +02:00
scripts cleanup scripts and migrate to CLI-managed service registration 2026-04-05 05:25:59 +02:00
.gitignore Add *.db to .gitignore to exclude database files from version control 2026-03-22 10:15:32 +01:00
buildenv.sh chore: bump version to 0.2.2 2026-04-10 16:29:06 +02:00
Cargo.lock Merge branch 'development' of forge.ourworld.tf:lhumina_code/hero_router into development 2026-04-19 15:46:33 +02:00
Cargo.toml feat: sessions 17-18 — native dioxus islands, new URL routing, OSIS auth fix, build safety 2026-04-12 09:59:08 -04:00
CLAUDE.md feat: split hero_router into separate RPC and UI routers with dedicated sockets 2026-04-15 11:08:44 +02:00
Makefile feat: split hero_router into separate RPC and UI routers with dedicated sockets 2026-04-15 11:08:44 +02:00
README.md feat: add IP whitelist access control for admin UI backed by hero_proc secrets 2026-04-19 13:42:07 +02:00

Hero Router

The single TCP entry point for all Hero services. Scans Unix sockets, routes HTTP traffic by URL prefix, provides service discovery, documentation, and an MCP gateway.

Quick Start

# Build and start
make run

# Stop
make stop

# CLI: list discovered services
hero_router list

Open the admin dashboard at http://localhost:9997.

Architecture

Internet / Browser / hero_proxy
       │
  :9988 (TCP, localhost only)
       │
  hero_router
    ├── /{service}/rpc/*    → {service}/rpc.sock
    ├── /{service}/admin/*  → {service}/ui.sock
    ├── /{service}/{web}/*  → {service}/web_{name}.sock
    ├── /rpc                → management API
    ├── /mcp                → MCP gateway
    └── :9997               → admin dashboard
       │
  Unix sockets (auto-discovered)
    ~/hero/var/sockets/
      hero_compute/rpc.sock
      hero_compute/ui.sock
      hero_proxy/rpc.sock
      hero_proc/rpc.sock
      ...

Features

  • Auto-discovery — scans $HERO_SOCKET_DIR/ for service sockets
  • URL prefix routing/{service}/{socket_type}/* stripped and forwarded
  • Header injectionX-Hero-Context, X-Hero-Claims, X-Forwarded-Prefix
  • MCP gateway — exposes services as MCP-compatible tools for AI agents
  • Admin dashboard — interactive web UI with service status
  • CLIlist, scan, spec, markdown, html subcommands
  • Documentation generation — Markdown and HTML from OpenRPC specs

Crate

Crate Type Description
hero_router binary + library Single binary with CLI, server, admin UI, and core library (herolib_router)

All crates were consolidated into a single binary in v0.2.0.

Sockets

All sockets under $HERO_SOCKET_DIR/hero_router/ (default: ~/hero/var/sockets/hero_router/).

Socket Protocol Description
rpc.sock JSON-RPC 2.0 Management API
ui.sock HTTP Admin dashboard

Ports (TCP, localhost only)

Port Description
9988 Routing entry point — proxies /{service}/* to Unix sockets
9997 Admin dashboard

Documentation

Development

make check          # cargo check
make test           # cargo test
make lint           # clippy
make fmt            # rustfmt
make rundev         # debug build
make test-all       # full CI suite

Installation

make install        # build release + install to ~/hero/bin/

Security

  • TCP listeners bind to 127.0.0.1 only by default (or an explicit --address)
  • Use hero_proxy for external/TLS access

Admin UI whitelist (optional)

When hero_router is exposed on a non-loopback address (e.g. the mycelium IPv6 of the host), the admin UI can be locked to specific source IPs. The whitelist is stored as a hero_proc secret — no config files.

  • Storage: hero_proc secret core/ADMIN_SECRETS, value is a comma-separated list of IP addresses (IPv4 or IPv6).
  • UDS (ui.sock) always bypasses — local tooling over the Unix socket is trusted.
  • Fail-open: if hero_proc is unreachable, or the secret is missing/empty, the feature is disabled and all TCP connections are allowed. This keeps hero_router usable when the supervisor is down.
  • Fail-closed only when configured: once ADMIN_SECRETS contains at least one valid IP, every non-matching TCP connection is silently dropped at accept time — no HTTP response, just a closed socket.
  • Refresh: the running process re-reads the secret every 60 seconds, so CLI edits propagate without a restart.
  • Same pattern applies to any Hero admin interface that wants whitelisting — read/write this one secret.

Manage from the CLI:

# Set the whitelist (comma-separated)
hero_proc secret set --context core --key ADMIN_SECRETS \
  --value "4f8:306f:d514:7bd::1,192.168.1.5"

# Read current value
hero_proc secret get --context core --key ADMIN_SECRETS

# Clear (disable enforcement — open access)
hero_proc secret delete --context core --key ADMIN_SECRETS

Or manage from the dashboard: open Admin in the top navbar (or go to /admin). The page shows your current source IP, the active whitelist, and buttons to add/remove/clear entries. All edits go to the hero_proc secret above via the ui.addAccess / ui.removeAccess / ui.clearAccess JSON-RPC methods on the UI router's /rpc endpoint.