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.
Architecture
Section titled “Architecture”- 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.
Tools / API
Section titled “Tools / API”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 / Backend | Description | Key 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 |
| ssh | Establish an SSH reverse tunnel to a remote host | [tunnel.ssh].HOST, PORT, USER, KEY_PATH |
| frpc | Use frpc client to register to frp server | [tunnel.frpc].SERVER_ADDR, SERVER_PORT |
| ngrok | Public tunneling via ngrok (token must be provided via secrets) | tunnel.DEFAULT_PORT, backend-specific secrets (ngrok auth) |
| serveo / localhost.run / localtunnel / pinggy | Lightweight public tunnels over respective services | tunnel.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
Section titled “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.
Code Examples
Section titled “Code Examples”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.
- 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";- 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";- 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.
Dependencies
Section titled “Dependencies”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.
Notes for developers
Section titled “Notes for developers”- 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.