Skip to content

ability-tunnel

Network tunnel ability

ability-tunnel is a unified tunnel ability for AGENTS that exposes local services through multiple tunneling backends (kadi-tunnel, SSH, frpc, ngrok, serveo, localtunnel, pinggy, or localhost.run). It centralizes configuration, connection limits, timeouts, and reconnection policies so other agents can request public endpoints for local services without caring about the specific transport.

  • Broker connectivity: The ability connects to the Kadi broker specified in config.toml under [broker.local] (URL, NETWORKS, MODE). The ability registers itself with the broker (entrypoint: dist/index.js) and listens for tunnel requests from other agents on the network “infra”.
  • Backends: The ability implements multiple backend adapters (kadi, ssh, frpc, ngrok, serveo, localtunnel, pinggy, localhost.run). Each adapter handles:
    • opening a tunnel for a given local port
    • returning a public address (host, port, path)
    • monitoring the tunnel health and performing reconnection according to AUTO_RECONNECT / MAX_RECONNECT_ATTEMPTS / RECONNECT_DELAY_MS
  • Coordinator: A concurrency limiter uses tunnel.MAX_CONCURRENT to limit concurrent tunnel setups. TIMEOUT_MS is used for backend operations that must complete within a deadline.
  • Control plane (kadi backend): When using tunnel.kadi the ability may call CONTROL_API_URL and use AGENT_ID and TRANSPORT/WSS_HOST to manage tunnels via kadi’s control API and SSH port (SSH_PORT) settings.
  • Fit in AGENTS ecosystem: This ability is consumed by agents that need transient or permanent public endpoints for local services (webhooks, dev servers, demos). Agents request a tunnel; the ability performs provisioning and returns the connection details.

The package exposes tunneling backends as tools (the runtime ability will present a “tunnel” tool with backend options). The following table documents the backends and the key configuration fields they use.

Tool / BackendDescriptionKey config fields / parameters
kadi (kadi-tunnel)Primary integrated backend; uses kadi control API and WebSocket/WSS transport[tunnel.kadi].SERVER, SSH_PORT, DOMAIN, TRANSPORT, WSS_HOST, AGENT_ID, CONTROL_API_URL
sshEstablish an SSH reverse tunnel to a remote host[tunnel.ssh].HOST, PORT, USER, KEY_PATH
frpcUse frpc client to register to frp server[tunnel.frpc].SERVER_ADDR, SERVER_PORT
ngrokPublic tunneling via ngrok (token must be provided via secrets)tunnel.DEFAULT_PORT, backend-specific secrets (ngrok auth)
serveo / localhost.run / localtunnel / pinggyLightweight public tunnels over respective servicestunnel.DEFAULT_PORT, per-backend secrets or credentials as required

Developer scripts (from agent.json) useful during development:

  • preflight — node —version
  • setup — npm install && npm run build
  • build — npx tsc
  • start — node dist/index.js
  • dev — npx tsx index.ts
  • serve — npx tsx index.ts stdio
  • serve:broker — npx tsx index.ts broker
  • clean — rm -rf node_modules abilities agent-lock.json package-lock.json dist

Note: The actual runtime tool names presented to agents depend on the ability’s exported tool registration logic (entrypoint: dist/index.js). The above table reflects backends present in the source configuration.

Configuration is provided by config.toml. Secrets should be placed in a separate secrets.toml (encrypted vault) as noted in the file header.

Relevant config.toml fields:

  • [broker.local]

    • URL: websocket URL to the kadi broker, e.g. “ws://localhost:8080/kadi”
    • NETWORKS: list of networks to join (e.g. [“infra”])
    • MODE: “native” or other supported broker connectivity mode
  • [tunnel]

    • DEFAULT_PORT: default local port to expose (3000)
    • DEFAULT_MODE: default backend (“kadi”)
    • TIMEOUT_MS: default operation timeout in milliseconds (30000)
    • MAX_CONCURRENT: maximum concurrent tunnel operations (5)
    • AUTO_RECONNECT: boolean to auto-reconnect tunnels (true)
    • MAX_RECONNECT_ATTEMPTS: max attempts to reconnect (3)
    • RECONNECT_DELAY_MS: delay between reconnect attempts (5000)
  • [tunnel.kadi]

    • SERVER: host for the kadi tunnel server (e.g. “tunnel.kadi.build”)
    • SSH_PORT: remote SSH port used by kadi backend (2222)
    • DOMAIN: optional domain to request
    • TRANSPORT: “wss” or “ws”
    • WSS_HOST: optional wss host override
    • AGENT_ID: optional agent identifier for control-plane operations
    • CONTROL_API_URL: optional HTTP API endpoint for control operations
  • [tunnel.ssh]

    • HOST: remote SSH host for reverse tunnels
    • PORT: SSH port (22)
    • USER: username to use
    • KEY_PATH: path to private key on disk
  • [tunnel.frpc]

    • SERVER_ADDR: frp server address
    • SERVER_PORT: frp server port (7000)

Environment variables and secrets

  • The repo expects secrets (SSH private keys, frp credentials, ngrok tokens, etc.) to be stored in secrets.toml or a vault that your deployment system injects. The config.toml header explicitly notes: “Secrets go in secrets.toml (encrypted vault)”.
  • Standard practice: export runtime overrides via environment variables in your orchestration environment (e.g., TUNNEL_DEFAULT_PORT, BROKER_URL), but this ability does not define mandatory env var names in the provided source. The ability will normally prefer values in config.toml and secrets.toml.

Below are minimal, directly-derived patterns you can use when developing or extending ability-tunnel. These snippets reflect the package entrypoint and config usage patterns from the source layout.

  1. Starting the built ability (entrypoint referenced in agent.json)
// Start the built ability (uses package scripts)
// This is the standard production entrypoint from agent.json:
const startCmd = "node dist/index.js";
// Run locally during development:
const devCmd = "npx tsx index.ts";
  1. Reading config values with fallback to the defaults declared in config.toml
// Example: derive runtime values from process.env or config defaults.
// This mirrors the fields declared in config.toml (names used here match the file).
const DEFAULT_PORT = Number(process.env.TUNNEL_DEFAULT_PORT ?? 3000);
const DEFAULT_MODE = process.env.TUNNEL_DEFAULT_MODE ?? "kadi";
const TIMEOUT_MS = Number(process.env.TUNNEL_TIMEOUT_MS ?? 30000);
const MAX_CONCURRENT = Number(process.env.TUNNEL_MAX_CONCURRENT ?? 5);
const AUTO_RECONNECT = (process.env.TUNNEL_AUTO_RECONNECT ?? "true") === "true";
  1. Developer helper: serve/stdio and broker modes (scripts)
// The project exposes convenient npm scripts that are used during development.
// - `npm run serve` => runs: npx tsx index.ts stdio
// - `npm run serve:broker` => runs: npx tsx index.ts broker
// Use these to run the ability in different frontend modes while developing.

Note: The repository’s Typescript sources for actual tunnel adapters and tool registration are located under source files referenced by entrypoint (dist/index.js after build). Inspect the built/artifact files generated by the build step (npx tsc) to see exported tool names and the exact runtime API surface.

Packages required by ability-tunnel (from package metadata):

  • runtime
    • @kadi.build/core ^0.9.0 — integration with the Kadi framework / broker (used to register ability and communicate with agents)
    • tsx ^4.21.0 — used for dev/run-time TypeScript execution in scripts
  • dev
    • typescript ^5.9.3
    • @types/node ^25.3.1

What ability-tunnel depends on conceptually:

  • kadi control infrastructure (broker at broker.local.URL)
  • backend services and credentials for chosen tunnel backends (SSH server, frp server, ngrok account, etc.)

What may depend on ability-tunnel:

  • Any agent that needs a public endpoint for a local service in the “infra” network or other networks the ability joins. Those agents request tunnels via the ability’s tool API exposed through the broker.
  • Entrypoint: the built runtime is dist/index.js (see agent.json). Use npm run build to regenerate the dist folder.
  • Keep secrets out of config.toml — use secrets.toml (encrypted vault) as documented in config.toml.
  • To add a new backend adapter, implement the open/close/probe lifecycle, honor TIMEOUT_MS and MAX_CONCURRENT, and register the adapter with the ability’s tool registry (examined in the entrypoint build).
  • Use the existing tunnel.kadi control fields (AGENT_ID, CONTROL_API_URL, TRANSPORT) when adding control-plane integrations so operators can manage tunnels centrally.